# Flow: Visit / Online Consultation

**Actors**: Patient, Doctor
**Phase**: 3 (doctor portal) for the diagnosis/report part; Phase 5 (Agora) for the video part

## In-clinic visit

1. Patient physically attends at the scheduled time (no system action required to "start" it —
   it's real-world).
2. Doctor opens the booking from `Doctor\ScheduleController::index()` → `Doctor\VisitController::show($booking)`.
3. Doctor marks the visit as started/in-progress (optional UX nicety) and, after the exam,
   records diagnosis/prescription/report — see step 4 below (shared with online).

## Online video consultation (Phase 5, Agora)

1. At/near `scheduled_at`, both sides open `Doctor\ConsultationController::show($booking)` /
   `Site\Clinic\...` (or the mobile app's equivalent) for that booking.
2. Backend `AgoraTokenService::tokenFor($booking, $role)` generates a join token scoped to a
   channel name derived from `booking.id` (e.g. `clinic-booking-{id}`), one token per participant
   role (doctor/patient).
3. Both join the Agora channel client-side using their token; the booking is marked
   `status` stays `'confirmed'` until the call ends, then flipped to `'completed'`
   (`Doctor\ConsultationController::end($booking)` or an Agora webhook if available, whichever is
   simpler to implement reliably — **decide during Phase 5** based on Agora's actual webhook
   support at implementation time).

## Shared: recording the medical record (both visit types)

4. `Doctor\VisitController::store(Booking $booking)` → `MedicalRecordService::create()` — creates
   the `MedicalRecord` row (diagnosis/prescription/report), sets `published_at`, flips
   `Booking.status` to `'completed'`.
5. Patient is notified (`NotificationService`) that a new report/prescription is available.
6. Patient reads it via `Site\Clinic\MedicalRecordController::index()`/`show()`.

## Editing after publish

7. `Doctor\VisitController::update(MedicalRecord $record)` → `MedicalRecordService::update()` —
   updates the fields, sets `last_edited_at`, writes an `ActivityLog` entry (doctor id, what
   changed, when), and dispatches a "your report was updated" notification to the patient — per
   the brief's explicit rule (edit allowed, but dated and the patient must be told).

## Triggers the rating step

8. Once `Booking.status` becomes `'completed'`, `Site\Clinic\ReviewController::create($booking)`
   becomes available to the patient — see `06-rating-flow.md`.
