# Flow: Chat

**Actors**: Patient, Doctor
**Phase**: 4 (`05-roadmap.md`) — real-time via Laravel Reverb (confirmed dependency)
**Important**: independent of any booking — a chat inquiry is explicitly **not** a consultation booking, per the brief.

## Steps

1. Patient opens (or starts) a conversation with a doctor: `Site\Clinic\ChatController::index($doctor)`
   — loads existing `clinic_chat_messages` for `(doctor_id, patient_id)`, or an empty thread if
   none exist yet.
2. Patient sends a message (text, and/or an image/file attachment):
   `Site\Clinic\ChatController::store()` → `ChatService::send($doctor, $patient, $body, $attachment, sender_type='patient')`.
3. `ChatService::send()`:
   - Creates the `ChatMessage` row.
   - Broadcasts a `NewClinicChatMessage` event on a private Reverb channel scoped to
     `chat.doctor.{doctor_id}.patient.{patient_id}`.
   - If the recipient (doctor) isn't currently subscribed to that channel, also calls
     `NotificationService` to create a database notification ("new message from {patient}"),
     following the existing `DatabaseNotification::create()` pattern.
4. Doctor sees the message live (if connected) via `Doctor\ChatController` listening on the same
   channel, or via the notification if offline, then opens `Doctor\ChatController::index($patient)`.
5. Doctor replies: same `ChatService::send()` call with `sender_type='doctor'`, reversing the
   broadcast/notification direction.
6. Either side marks messages `read_at` when the thread is opened
   (`ChatService::markRead($doctor, $patient, $readerType)`).

## Attachments

- Images/files reuse the app's existing upload-handling trait(s) (check `ImageUploadTrait`/
  `ImageProcessing` under `app/Traits` before writing new upload code) rather than a new pipeline.
- Stored path on `ChatMessage.attachment_path`, mime-derived `attachment_type` for rendering
  (image inline vs. a file download link) — per the brief's explicit examples (prescriptions,
  scans, reports).

## Out of scope for this flow

- Group chats, read receipts beyond a single `read_at` timestamp, message deletion/editing — the
  brief doesn't call for any of these; add only if a later requirement surfaces one.
