# Meeting Completion Logic

## Overview
The system now properly handles meeting completion based on who ends the meeting.

## Meeting End Scenarios

### 1. Host Ends Meeting (COMPLETED ✅)
- **Trigger**: Host clicks "End Meeting" or inactivity timeout (frontend)
- **API Call**: `POST /schedule/:id/end-meeting`
- **Process**:
  1. Frontend calls end-meeting API with reason
  2. API marks meeting status as COMPLETED
  3. API sets endedAt timestamp
  4. 100ms webhook receives session.close.success
  5. Webhook sees meeting is already COMPLETED
  6. Updates participants with leaveReason: 'meeting_ended_by_host'

### 2. Technical Issues / All Participants Leave (LIVE 🔄)
- **Trigger**: 100ms session closes due to technical issues or no participants
- **Process**:
  1. 100ms webhook receives session.close.success
  2. Webhook sees meeting is still LIVE
  3. Does NOT mark as COMPLETED
  4. Updates participants with leaveReason: 'session_closed_automatically'
  5. Meeting remains LIVE for host to rejoin or manually end

### 3. Individual Participant Leaves (NO CHANGE 👤)
- **Trigger**: Participant leaves meeting
- **Process**:
  1. 100ms webhook receives peer.leave.success
  2. Updates only that participant's leftAt and watchDuration
  3. Meeting status unchanged
  4. Other participants remain active

## Database States

### Meeting (Schedule table)
```typescript
// Host ended meeting
status: 'COMPLETED'
endedAt: Date

// Technical issue/auto-close
status: 'LIVE' (unchanged)
endedAt: null
```

### Participants (ScheduleParticipant table)
```typescript
// Host ended meeting
leaveReason: 'meeting_ended_by_host'
leftAt: meeting_end_time
watchDuration: calculated

// Auto session close
leaveReason: 'session_closed_automatically' 
leftAt: session_close_time
watchDuration: calculated

// Individual leave
leaveReason: 'peer_left_100ms'
leftAt: leave_time
watchDuration: calculated
```

## API Endpoints

### End Meeting (Host Only)
```
POST /schedule/:id/end-meeting
Body: { reason: string }
Auth: Required (JWT)
Access: Creator only
```

### Webhook (100ms)
```
POST /schedule/webhook/100ms
Body: 100ms webhook payload
Auth: Public
Access: 100ms servers only
```

## Frontend Integration

### Inactivity Detection
```typescript
// After 5 minutes of inactivity
if (isCreator) {
  await api.post(`/schedule/${meetingId}/end-meeting`, { 
    reason: 'inactivity_timeout' 
  });
}
```

### Manual End Button
```typescript
const endMeeting = async () => {
  await api.post(`/schedule/${meetingId}/end-meeting`, { 
    reason: 'manual_end' 
  });
};
```

## Benefits

1. **Accurate Completion Tracking**: Only hosts can mark meetings as COMPLETED
2. **Resilient to Technical Issues**: Auto session close doesn't mark as completed
3. **Proper Activity Tracking**: All participants get accurate leave times and reasons
4. **Host Control**: Only meeting creators can officially end meetings
5. **Webhook Integration**: Automatic participant tracking via 100ms webhooks

## Monitoring

Check participant leave reasons:
```sql
SELECT 
  s.title,
  sp.userId,
  sp.leaveReason,
  sp.leftAt,
  sp.watchDuration
FROM "ScheduleParticipant" sp
JOIN "Schedule" s ON s.id = sp.scheduleId
WHERE sp.leftAt IS NOT NULL
ORDER BY sp.leftAt DESC;
```
