Frens System — Implementation Summary
Date: January 9, 2026
Status: ✅ Design Phase Complete (Frontend Scaffold)
What Was Built
A complete privacy-first reconnection system that allows users to save connections from in-person meetings while maintaining Lantern's core anonymity and privacy principles.
Core Innovation
Venue-Bound Broadcasting Model
Unlike traditional social apps where you track other people, Lantern inverts the model:
Traditional: "Let me see where my friends are"
Lantern: "Let my friends see where I am (at specific venues I choose)"Key Difference: You broadcast TO people, not track them. Each venue is a separate, intentional choice.
Files Created
Documentation
- docs/features/frens/FRENS_SYSTEM.md - Complete system documentation (400+ lines)
- docs/features/frens/FRENS_QUICK_REF.md - Quick reference guide
Components
- src/components/SaveConnectionPrompt.jsx - Modal to save connections after chatting
- src/components/ManageVenuesModal.jsx - Manage broadcast venues
Screens
- src/screens/frens/FrensList.jsx - Main frens list with filters and search
- src/screens/frens/FrenProfile.jsx - Individual fren detailed view
Storybook Stories
- src/components/SaveConnectionPrompt.stories.jsx
- src/components/ManageVenuesModal.stories.jsx
- src/screens/frens/FrensList.stories.jsx
- src/screens/frens/FrenProfile.stories.jsx
Routes
- Updated src/App.jsx to include:
#/frens- Frens list#/frens/:id- Individual fren profile
How It Works
The User Flow
1. You meet someone at Coffee House
↓
2. Accept their wave → Chat
↓
3. Tap "Save Connection"
↓
4. You're now broadcasting to them at Coffee House
→ They can see YOUR lantern when you're at Coffee House
→ You can't see theirs (unless they save you back)
↓
5. If they save you back:
→ 🎉 Mutual connection notification
→ Both see each other at shared venues
↓
6. Later, you both show up at The Speakeasy
→ Option to add as broadcast venue
→ Each venue is a separate choicePrivacy Model
| State | You See Them | They See You |
|---|---|---|
| Neither saved | ❌ | ❌ |
| You saved them | ❌ | ✅ (at broadcast venues) |
| They saved you | ✅ (at broadcast venues) | ❌ |
| Mutual save | ✅ (at shared venues) | ✅ (at shared venues) |
Key Features Implemented
1. SaveConnectionPrompt
- Clear explanation of venue-bound broadcasting
- Visual confirmation of what they're agreeing to
- Success state with celebration
- Privacy-first messaging
2. FrensList
- Filters: All, Lit (active), Mutual
- Search: Filter by lantern name
- Real-time status: Lit indicator with pulse animation
- Lit banner: "X frens have lit lanterns" priority section
- Empty state: Educational onboarding
3. FrenProfile
- Current status: Lit/not lit with venue
- Interests: Visual tags
- Connection info: Where/when you met
- Venue broadcasting:
- Who you broadcast to (📡)
- Who broadcasts to you (👀)
- Shared venues highlight (✨)
- Actions: Wave, manage venues, remove connection
- Privacy notice: Explanation of how it works
4. ManageVenuesModal
- Checkbox list: Toggle venues on/off
- Mutual indicators: Show which venues are mutually broadcast
- Explanatory text: How broadcasting works
- Save state: Only enable save if changes made
- Privacy reminder: Can change anytime
Design Decisions
Why Venue-Bound Broadcasting?
Problem with traditional location tracking:
- Reveals patterns (every Tuesday at gym)
- Enables stalking
- Creepy factor
Solution:
- Only see someone at venues you BOTH chose
- Each venue is intentional
- Can't build routines or patterns
- Natural privacy boundaries
Why Asymmetric Visibility?
You save someone = You broadcast to them
- Like leaving a standing invitation
- "If you want to find me again, here's my signal"
- NOT "Let me track where you are"
- Consent flows with the action
Why No Persistent Chat?
Forces real-world connection:
- Chat only when both at venues
- 2-hour post-meetup window for logistics
- Prevents "pen-pal" syndrome
- Beacon Invites for coordination
What's Next
Phase 2: Firebase Integration
- [ ] Firestore
connectionscollection schema - [ ] Real-time listeners for lit lanterns
- [ ] Cloud Functions for mutual detection
- [ ] Notification system (mutual save, fren lit)
- [ ] Connection CRUD operations
Phase 3: Real-Time Features
- [ ] Live updates when frens light lanterns
- [ ] Priority wave queue for frens
- [ ] Venue expansion prompts
- [ ] Connection removal handling
Phase 4: Beacon Invites
- [ ] "I'll be at X venue on Y date" invites
- [ ] One-way coordination (no chat)
- [ ] Calendar integration
- [ ] Reminder system
Phase 5: Polish & Analytics
- [ ] Track save rates
- [ ] Monitor venue expansion patterns
- [ ] A/B test messaging
- [ ] User feedback integration
- [ ] Performance optimization
Testing in Storybook
bash
npm run storybookNavigate to:
Frens/SaveConnectionPrompt- Save modal variationsFrens/FrensList- List views and filtersFrens/FrenProfile- Profile states (mutual, one-way, lit, not lit)Frens/ManageVenuesModal- Venue management
Testing in App
bash
npm run devNavigate to:
http://localhost:5173/#/frens- Frens listhttp://localhost:5173/#/frens/1- Fren profile (mock data)
Data Model (Preview)
javascript
// Firestore: connections/{connectionId}
{
connectionId: "abc123",
user1Id: "user123",
user2Id: "user456",
// Venue-specific broadcasting
user1Broadcasts: [
{ venueId: "coffee-house", venueName: "Coffee House", addedDate: "2026-01-09" }
],
user2Broadcasts: [],
// Metadata
metAt: "Coffee House",
metDate: "2026-01-09",
isMutual: false,
// Cached profile data
user1LanternName: "Amber Beacon",
user1Interests: ["Jazz", "Coffee", "Art"]
}Success Metrics (Proposed)
Engagement
- % of wave acceptances → saves
- Average frens per user
- Average venues per mutual connection
- Reconnection rate (7+ days later)
Privacy Health
- % users with >10 broadcast venues (spam indicator)
- Venue expansion rate
- Connection removal rate
Feature Adoption
- % users with ≥1 fren
- % users with ≥1 mutual fren
- Frens feature DAU/MAU
Related Documentation
- Complete System Docs - Full technical specification
- Quick Reference - At-a-glance guide
- Privacy-First Profiles - Profile system
- Wave-to-Meet - Connection initiation
- Zero-Knowledge Encryption - Security model
Design Highlights
Visual Language
- Amber glow: Active/lit lanterns
- Purple badges: Mutual connections
- Gray dots: Inactive status
- Pulse animation: Real-time activity
UX Patterns
- Progressive disclosure: Only show complexity when needed
- Educational empty states: Guide users to first action
- Celebration moments: Mutual save notification
- Clear affordances: What's clickable is obvious
Accessibility
- Color contrast: WCAG AA compliant
- Focus states: Keyboard navigation support
- Screen reader labels: Semantic HTML
- Touch targets: 44px minimum
Status: Ready for Firebase backend integration. All frontend components are functional with mock data and fully documented.