# Flow — Return → Review → Outsource (Maintenance Team Leader)

> Persona: **Vikram Rana** (MTL), Game Zone Ahmedabad-1. The exception path: a Technician **can't fix** a WO internally and **returns** it with a reason; Vikram reviews and **escalates an outsource report to the Store Manager** — the only WO state that reaches the SM. Source: `FOUNDATION_SPEC §4a` (WorkOrder state machine), `CHANGE_LIST_v1.1.md CL-2`. Screens: `MTL-WO-QUEUE` → `MTL-WO-REVIEW` → `MTL-WO-ESCALATE`. Modals: `modals/escalate-outsource-confirm.html`, `modals/reassign-confirm.html`, `modals/photo-lightbox.html`.

---

## Preconditions
- **WO-1039** (Warrior Assault Daily · "Grip handle loose on wall 3") was routed and assigned to **Arjun Mehta** (`ASSIGNED → IN_PROGRESS`). Arjun finds the mounting bracket cracked through (a welded part, no stock) and **returns** it.
  → `PATCH /work-orders/:id/return { reason }` → `IN_PROGRESS → RETURNED` (reason required, optional return photo). Vikram is notified; the WO surfaces in his **Returned** queue, flagged **over SLA**.

## Steps

1. **Spot the return.** On `MTL-DASH` the **Returned** KPI is non-zero; `MTL-WO-QUEUE` (Returned filter) shows WO-1039 with the `wo-returned` (amber) badge + a red over-SLA badge.
   → `GET /work-orders?scope=own&state=RETURNED`.

2. **Review it.** Vikram clicks **Review →** → `MTL-WO-REVIEW`.
   → `GET /work-orders/:id` + `GET …/timeline`. The screen shows the **technician's return reason** + return photo, the **original A-item** context, and the WorkOrder-variant timeline (`Routed ✓ → Assigned ✓ → Returned (Arjun) → Maintenance TL (you, decide)`).

3. **Decide.** Three options on the decision bar:
   - **Close internally (resolved)** — green; if Vikram judges it actually fixed / not needed → `DONE` (closes at maintenance, SM not notified).
   - **Reassign to a technician** — orange; opens the **reassign-confirm modal**; `RETURNED → ASSIGNED` with a fresh tech (e.g. Deepak). Use when another tech could still fix it internally.
   - **Escalate / Outsource to SM** — navy; the path here, since it needs a fabricator.

4. **Compose the outsource report.** Vikram clicks **Escalate / Outsource** → `MTL-WO-ESCALATE`. The report is pre-addressed to **Rohit Shah (Store Manager)**; Vikram writes the **required** reason/action-needed text; the WO's issue + return photos are carried over automatically (he can add more).

5. **Confirm + send.** Vikram clicks **Send to Store Manager** → the **escalate-outsource-confirm modal** ("this is the only WO action that reaches the SM") → confirm.
   → `PATCH /work-orders/:id/outsource { note }` → `RETURNED → OUTSOURCED`. The WO surfaces on the SM's **Outsource / Action-needed inbox** (`SM-WO-OUTSOURCE`). A blank reason is rejected client-side **and** server-side (**422**).

6. **Last WO closes → un-HOLD.** `OUTSOURCED` is terminal for the maintenance track. If WO-1039 was the **last** open WO on Warrior Assault Daily, the parent instance auto-releases **HELD → TL_APPROVED** and the inspection checklist resumes its cascade. (The physical fix continues out-of-band via the SM's outsourcing — that's tracked on the SM side, not as a maintenance WO.)

## Rules enforced in this flow
- **Only OUTSOURCED reaches the SM (CL-2, locked):** `DONE` closes silently; `OUTSOURCED` is the single escalation channel.
- **Reason required:** both `return` (technician) and `outsource` (MTL) require a reason — 422 if blank.
- **Reassign vs outsource:** reassign keeps it internal (`→ ASSIGNED`); outsource exits internal handling (`→ OUTSOURCED`).
- **Own-GZ scope:** the SM who receives the outsource is this GZ's SM (Rohit Shah).
- **HELD release counts WOs:** the source checklist un-holds only when *every* A-item WO is `DONE`/`OUTSOURCED`.

## Result
- WO-1039 is **Outsourced** to the Store Manager with a reason + photos. If it was the last open WO, **Warrior Assault Daily** un-holds and resumes its approval cascade.
