# Liv Hospital International — Trip State Machine & Operational State Rules

### 1. State Model Architecture
The lifecycle of a patient transfer is governed by a **Deterministic Finite State Machine (FSM)**.

To prevent state explosion and maintain operational truth, state is separated into:
1. **Primary Trip Stage (`primary_status`)**: Represents the physical and operational progression of the journey. Primary states are non-cyclical and irreversible under normal operation.
2. **Orthogonal Operational Flags**: Boolean indicators representing temporary operational health conditions (`is_delayed`, `is_incident_open`, `is_waiting_for_replacement`, `is_tracking_offline`). An incident or delay never erases or replaces the underlying physical stage.
3. **Assignment Execution Authority (`has_execution_authority`)**: A strict boolean flag attached to `transfer_assignments`. Exactly one assignment may hold `has_execution_authority = TRUE` for an active trip.

---

### 2. Primary Trip States Reference
| State Code | Human-Readable Name | Description |
| :--- | :--- | :--- |
| `new` | New Request | Initial draft created by Patient Relations or Coordinator; awaiting verification. |
| `awaiting_assignment` | Awaiting Assignment | Request verified; queued for Sabit fleet assignment or Destek company referral. |
| `confirmed` | Confirmed | Driver and vehicle assigned and accepted; trip locked for execution. |
| `en_route_to_pickup` | En Route to Pickup | Driver has departed towards the patient's pickup location. Live tracking active. |
| `arrived_at_pickup` | Arrived at Pickup | Driver arrived at pickup location/gate. Waiting grace period countdown begins. |
| `passenger_onboard` | Passenger Onboard / In Progress | Patient and luggage onboard; traveling towards destination. |
| `arrived_at_destination` | Arrived at Destination | Vehicle arrived at destination (hospital, hotel, airport terminal). |
| `completed` | Completed | Patient safely received by clinic/hotel/airline; trip closed and archived. |
| `cancelled` | Cancelled | Cancelled prior to passenger boarding with documented reason. |
| `no_show` | No-Show | Patient failed to appear within waiting window after verified contact attempts. |
| `terminated` | Terminated | Abrupt early termination *after* passenger boarded (e.g. emergency hospital detour). |

---

### 3. Detailed Transition Matrix

#### Transition 1: `new` $\rightarrow$ `awaiting_assignment`
- **Authorized Actor**: Transport Coordinator, Patient Relations Employee
- **Preconditions**:
  - Valid patient assigned with E.164 phone.
  - Pickup and dropoff locations verified with valid geographic coordinates.
  - Scheduled pickup time is in the future.
  - If medical transport review required, must be approved.
- **Required Data**: `scheduled_pickup_time_utc`, `passenger_count`, `execution_type` (`sabit` / `destek`).
- **Resulting Event**: `TransferSubmittedForAssignment`
- **Notifications**: None to patient yet. Internal dashboard badge updated.
- **Correction / Reversal**: Can be updated or cancelled by coordinator.

#### Transition 2: `awaiting_assignment` $\rightarrow$ `confirmed`
- **Authorized Actor**:
  - Sabit: Assigned Driver (via Acceptance action) or Coordinator (direct administrative dispatch).
  - Destek: External Dispatcher (upon completing referral with vehicle/driver) followed by driver confirmation.
- **Preconditions**:
  - Driver assigned and verified available.
  - Vehicle assigned with sufficient passenger seats and luggage capacity.
  - Vehicle status is `available`.
  - Assignment record created and `has_execution_authority` set to `TRUE`.
- **Required Data**: `driver_id`, `vehicle_id`, `plate_number`.
- **Resulting Event**: `TransferConfirmed`
- **Notifications**:
  - **Patient**: WhatsApp template `trip_confirmed` in patient's preferred language with tracking link.
  - **Companion**: WhatsApp template `trip_confirmed` if authorized.
  - **Driver**: Mobile push notification with trip summary.
- **Correction / Reversal**: If reassigned before departure, coordinator initiates reassignment workflow.

#### Transition 3: `confirmed` $\rightarrow$ `en_route_to_pickup`
- **Authorized Actor**: Active Assigned Driver (holding execution authority)
- **Preconditions**:
  - `has_execution_authority == TRUE`.
  - Current timestamp within acceptable operational dispatch window (e.g., up to 2 hours before scheduled pickup).
- **Required Data**: Driver GPS coordinates at departure.
- **Resulting Event**: `DriverDepartedForPickup`
- **Notifications**:
  - **Patient**: WhatsApp template `driver_en_route` with updated live ETA and vehicle plate.
  - **Tracking Page**: Live map opens for public tracking token.
- **Correction / Reversal**: Driver cannot reverse. Coordinator override requires documented administrative reason.

#### Transition 4: `en_route_to_pickup` $\rightarrow$ `arrived_at_pickup`
- **Authorized Actor**: Active Assigned Driver
- **Preconditions**:
  - Driver is within arrival radius (geofence trigger) or manually confirms with coordinate check.
  - `primary_status == en_route_to_pickup`.
- **Required Data**: Arrival GPS coordinates, timestamp.
- **Resulting Event**: `DriverArrivedAtPickup`
- **Notifications**:
  - **Patient**: WhatsApp template `driver_arrived` with specific meeting point instructions and driver contact button.
  - **Companions**: WhatsApp alert in companion's language.
- **Correction / Reversal**: None. Starts the `allowed_waiting_minutes` countdown timer.

#### Transition 5: `arrived_at_pickup` $\rightarrow$ `passenger_onboard`
- **Authorized Actor**: Active Assigned Driver
- **Preconditions**:
  - Driver confirms patient identity and boarding.
  - `primary_status == arrived_at_pickup`.
- **Required Data**: Boarding confirmation, passenger count verified, luggage count.
- **Resulting Event**: `PassengerBoarded`
- **Notifications**:
  - **Coordinator**: Dashboard status turns green (In-Transit).
  - **Authorized Reception**: Alert sent to hospital clinic or hotel reception.
- **Critical Business Rule**: **Once this state is entered, standard pre-trip cancellation is strictly forbidden.**

#### Transition 6: `passenger_onboard` $\rightarrow$ `arrived_at_destination`
- **Authorized Actor**: Active Assigned Driver
- **Preconditions**:
  - Driver arrived at final destination coordinates.
  - `primary_status == passenger_onboard`.
- **Required Data**: Arrival coordinates, timestamp.
- **Resulting Event**: `ArrivedAtDestination`
- **Notifications**:
  - **Coordinator**: Destination arrival logged.
  - **Reception / Patient Relations**: Arrival alert.
- **Correction / Reversal**: None.

#### Transition 7: `arrived_at_destination` $\rightarrow$ `completed`
- **Authorized Actor**: Active Assigned Driver or Coordinator
- **Preconditions**:
  - Patient safely disembarked; luggage handed over.
  - `primary_status == arrived_at_destination`.
- **Required Data**: Disembarkation confirmation.
- **Resulting Event**: `TransferCompleted`
- **Notifications**:
  - **Patient**: WhatsApp template `trip_completed` (thank you message and feedback survey link).
- **Tracking Lifecycle**: Tracking token enters read-only post-trip summary mode; live telemetry broadcasting terminates. Driver and vehicle status reset to `available`.

---

### 4. Exception & Incident State Transitions

#### Transition 8: (`new`, `awaiting_assignment`, `confirmed`, `en_route_to_pickup`) $\rightarrow$ `cancelled`
- **Authorized Actor**: Transport Coordinator (Patient cancellation requests require coordinator review).
- **Preconditions**: Patient has **NOT** boarded (`primary_status != passenger_onboard`).
- **Required Data**: `cancellation_reason`, `cancelled_by_user_id`.
- **Resulting Event**: `TransferCancelled`
- **Notifications**:
  - **Patient & Companion**: WhatsApp cancellation notice.
  - **Driver & External Dispatcher**: Immediate cancellation notice; release vehicle/driver.
- **Authority Revocation**: Active assignment authority revoked; driver returned to `available`.

#### Transition 9: `arrived_at_pickup` $\rightarrow$ `no_show`
- **Authorized Actor**: Transport Coordinator (Driver submits candidate report; Coordinator confirms).
- **Preconditions**:
  - Driver waited $\ge \text{allowed\_waiting\_minutes}$ (e.g. 45 min at airport, 20 min at hotel).
  - At least 2 documented `contact_attempts` recorded in database.
- **Required Data**: Logged call attempts, coordinator approval.
- **Resulting Event**: `PatientNoShowRecorded`
- **Notifications**:
  - **Patient**: WhatsApp no-show notification with coordinator hotline.
  - **Driver**: Released from assignment.

#### Transition 10: `passenger_onboard` $\rightarrow$ `terminated` (Post-Boarding Emergency)
- **Authorized Actor**: Transport Coordinator in coordination with Driver
- **Preconditions**:
  - Patient already onboard.
  - Journey cannot proceed to original destination (e.g., patient requests emergency stop, critical diversion to nearest emergency room, impassable road closure).
- **Required Data**: `actual_dropoff_location`, `dropoff_latitude`, `dropoff_longitude`, `termination_reason`, `passenger_disposition` (handed over to emergency services, returned home, etc.).
- **Resulting Event**: `TransferTerminatedEarly`
- **Notifications**:
  - **Coordinator, Patient Relations, Medical Team**: High-priority incident notification.

---

### 5. Breakdown & In-Transit Vehicle Replacement Protocol

When a vehicle breaks down with a patient onboard:

```mermaid
sequenceDiagram
    autonumber
    actor DriverA as Original Driver (Sabit)
    participant Core as State Machine & FSM
    actor Coord as Transport Coordinator
    participant Prov as Replacement Provider (Sabit / Destek)
    actor DriverB as Replacement Driver
    actor Patient as Patient / Tracking Page

    DriverA->>Core: Report Incident (Breakdown, Patient Onboard=True)
    Core->>Core: Set is_incident_open=TRUE, is_waiting_for_replacement=TRUE<br/>(primary_status remains PASSENGER_ONBOARD)
    Core->>Coord: High-Priority Incident Alert
    Coord->>Prov: Dispatch Replacement Request (Sabit or Destek)
    Prov->>Core: Propose Vehicle B & Driver B
    Coord->>Core: Confirm Replacement & Approve Safe Handover Waypoint
    Core->>Core: Set Replacement Assignment status=OFFERED
    DriverB->>Core: Accept Replacement Assignment
    Core->>DriverB: Route to Safe Roadside Handover Waypoint
    DriverB->>Core: Arrive at Handover Waypoint
    DriverA->>Core: Confirm Luggage & Patient Handover
    DriverB->>Core: Confirm Luggage & Patient Received
    Core->>Core: ATOMIC TRANSACTION:<br/>1. Revoke Driver A authority (REVOKED)<br/>2. Grant Driver B authority (ACTIVE)<br/>3. Clear is_waiting_for_replacement<br/>4. Close replacement request
    Core->>Patient: Send WhatsApp: "Vehicle replaced. Driver B is continuing your journey"
    Patient->>Core: Same Tracking URL (/track/{token}) now displays Driver B & Vehicle B
    DriverB->>Core: Resume journey to original destination
```

#### Invariance & Integrity Rules for Replacement:
1. **Transfer Reference Unchanged**: Reference stays `TR-YYYY-XXXXX`.
2. **Stable Patient Tracking URL**: The tracking token and `/track/{token}` URL remain identical. The client socket or polling endpoint seamlessly renders Vehicle B without patient intervention.
3. **Atomic Authority Swap**: Executed in a single database transaction with row locks:
   ```sql
   UPDATE transfer_assignments SET has_execution_authority = FALSE, status = 'revoked', authority_revoked_at_utc = UTC_TIMESTAMP() WHERE id = :old_id;
   UPDATE transfer_assignments SET has_execution_authority = TRUE, status = 'active', authority_granted_at_utc = UTC_TIMESTAMP() WHERE id = :new_id;
   ```
4. **Driver A Lockout**: Once revoked, Driver A's mobile application is immediately stripped of write permissions on this trip. Any subsequent transition attempt by Driver A returns `403 Forbidden: Assignment authority revoked`.

---

### 6. Retention, Timezones & Operational Data Standards
- **Timezone**: All internal timestamps are stored strictly in **UTC**. The presentation layer converts to `Europe/Istanbul` (default) or the recipient's branch timezone.
- **Telemetry Retention**:
  - Raw GPS coordinates in `location_updates` are retained at full 5-second fidelity for **30 days**.
  - After 30 days, a scheduled cleanup job aggregates coordinates into trip polyline summaries and purges raw point rows.
- **Audit Logs**: Records in `audit_logs` and `transfer_events` are strictly **immutable** (`DELETE` operations disabled).
- **Patient Tokens**: Token hashes in `tracking_tokens` expire **6 hours** after trip completion. Revoked tokens return HTTP 410 Gone immediately.
