Sponsor/Sponsee Relationships
The sponsor relationship is hierarchical and private. Only the two parties should know about it.
Key concepts:
- Invite-based connection (sponsor generates code, sponsee accepts)
- Time-limited invite codes (24h expiration)
- Private by design - no public visibility
- One sponsor per program, unlimited sponsees
Hooks provided:
useSponsorInvite() - Generate and accept invite codesuseSponsorRelationships() - List sponsors and sponsees
Components:
GenerateSponsorInvite - Sponsor creates shareable codeAcceptSponsorInvite - Sponsee enters code to connectSponsorDashboard - View all sponsor/sponsee relationships
> See: references/sponsor-sponsee.md for full implementation
---
Meeting-Based Groups
Groups that form organically around meetings. Ephemeral by default but can be made permanent.
Key concepts:
- Tied to specific meetings or standalone
- Ephemeral groups auto-delete after 24 hours
- Visibility options: public, private, invite-only
- Member limits prevent overcrowding
Group Settings:
```typescript
interface GroupSettings {
name: string;
meetingId?: string; // Link to meeting
visibility: 'public' | 'private' | 'invite';
ephemeral: boolean; // Auto-delete after 24h
maxMembers: number; // Member limit
}
```
| Visibility | Who Can See | Who Can Join |
|------------|-------------|--------------|
| public | Anyone | Anyone |
| private | Members only | Invite only |
| invite | Members only | Has invite code |
Hooks provided:
useMeetingGroup() - Create, join, leave groups
Components:
QuickMeetingGroup - One-tap group creation at meetings
> See: references/groups.md for full implementation
---
Friend Connections
Peer-to-peer connections without hierarchy. Mutual consent required.
Key concepts:
- Request/accept flow (no auto-follows)
- Real-time updates via Supabase subscriptions
- Blocking supported (one-way, discreet)
- Status: pending, accepted, blocked
Hooks provided:
useFriendships() - Full friendship management with real-time sync
Components:
FriendRequestButton - Context-aware add/pending/friends statesPendingFriendRequests - Accept/decline UI
> See: references/friendships.md for full implementation
---
Safe Messaging
Recovery-appropriate messaging with crisis detection and safety features.
Key concepts:
- Real-time message delivery via Supabase
- Crisis keyword detection (non-blocking, shows resources)
- Soft-delete (messages hidden, not destroyed)
- Privacy-first (no read receipts by default)
Crisis Keywords (trigger resource prompt):
```typescript
const CRISIS_KEYWORDS = [
// Suicidal ideation
'suicide', 'kill myself', 'want to die', 'end it all',
// Relapse indicators
'relapse', 'using again', 'fell off the wagon',
// Self-harm
'hurt myself', 'cutting', 'self-harm',
];
```
Best Practices:
- Non-blocking - Crisis prompts suggest resources, don't block messages
- Privacy-first - Don't log or report crisis keywords automatically
- Helpful tone - Gentle, non-judgmental language
- Direct resources - Link to crisis page, not external sites
- Offline capable - Cache crisis resources for offline access
Hooks provided:
useMessages() - Real-time message thread with Supabase subscriptions
Components:
MessageInput - Input with crisis detection overlay
> See: references/messaging.md for full implementation
---
Accountability Features
Sharing recovery progress with trusted connections.
Check-In Sharing:
- Share daily check-ins with selected sponsors
- HALT tracking (Hungry, Angry, Lonely, Tired)
- Mood and gratitude logging
Sobriety Visibility Settings:
| Level | Who Can See | Use Case |
|-------|-------------|----------|
| private | Only self | Maximum privacy |
| sponsors | Self + sponsors | Accountability focus |
| friends | Self + sponsors + friends | Peer support |
| community | All app users | Public milestone celebrations |
HALT Check-In Data:
```typescript
interface DailyCheckIn {
date: string;
mood: 1 | 2 | 3 | 4 | 5; // 1=worst, 5=best
halt: {
hungry: boolean;
angry: boolean;
lonely: boolean;
tired: boolean;
};
gratitude?: string;
notes?: string;
}
```
Components:
ShareCheckIn - Select sponsors to share withSobrietyVisibility - Privacy level picker
> See: references/accountability.md for full implementation
---
Safety & Moderation
Content moderation and user blocking for safe communities.
Moderation Categories:
| Category | Description | Action |
|----------|-------------|--------|
| crisis | Suicidal ideation, self-harm | Show resources, don't block |
| sourcing | Drug seeking, dealing | Block + flag for review |
| harassment | Personal attacks, threats | Block + flag for review |
| spam | Promotional content | Block |
| explicit | Sexual/graphic content | Block |
Blocking Behavior:
- Blocked user cannot send messages
- Blocked user cannot see blocker's profile
- Blocked user cannot see blocker in groups
- Existing messages are hidden (not deleted)
- Blocking is one-way (blocked user doesn't know)
RLS Policy Pattern:
```sql
-- Hide content from blocked users
CREATE POLICY "Hide messages from blocked users" ON messages
FOR SELECT USING (
NOT EXISTS (
SELECT 1 FROM friendships
WHERE status = 'blocked'
AND (
(requester_id = auth.uid() AND addressee_id = sender_id)
OR (addressee_id = auth.uid() AND requester_id = sender_id)
)
)
);
```
Hooks provided:
useContentModeration() - Check content against moderation APIuseBlocking() - Block/unblock users, check block status
> See: references/moderation.md for full implementation
---