# Maintenance Team Leader (Web) — Cross-Role Handoffs

> The cross-role touchpoints this role fires into / receives from. The MTL is the **maintenance branch** of the cascade — it **receives** A-item work-orders routed by the operations Team Leader, **assigns** them to Technicians, **reviews** results, and either **closes internally** or **escalates only outsource cases** to the Store Manager. Closing the last WO **un-HOLDs** the source checklist back into the TL→SM→OH cascade. WO mechanics live in `FOUNDATION_SPEC §4 / §4a`; the single-track hold in `FOUNDATION_SPEC §4` + `CHANGE_LIST_v1.1.md CL-2`.

---

## Upstream input (what arrives at the Maintenance TL)

| From | Trigger | What the MTL receives | Surfaces on |
|---|---|---|---|
| **Operations Team Leader** | TL verifies a submitted checklist with A-items and **routes** each A-item (`TL-CHK-VERIFY` → "Route to Maintenance") | One `WorkOrder` per A-response (`state = ROUTED`); parent `ChecklistInstance → HELD`; MTL notified (in-app + companion push) | `MTL-WO-QUEUE` (new Routed rows) → `MTL-WO-DETAIL`; `MTL-DASH` New/Routed KPI |
| **Technician** | Tech marks **Done** (+fix photo) | `IN_PROGRESS → DONE`; WO closes at maintenance level (no further action needed); fix photo viewable | `MTL-WO-QUEUE` (drops to Done/closed); audit on `MTL-WO-DETAIL` |
| **Technician** | Tech **returns** ("can't fix internally", reason) | `IN_PROGRESS → RETURNED { reason }`; MTL must decide | `MTL-DASH` Returned KPI · `MTL-WO-QUEUE` Returned filter → `MTL-WO-REVIEW` |
| **Overdue sweep** | `now() > SLA` on an open WO | WO flagged over-SLA | `MTL-DASH` Overdue KPI · `MTL-WO-QUEUE` Overdue chip |

## Downstream output (what the Maintenance TL fires)

| To | Trigger | What fires | Lands on |
|---|---|---|---|
| **Technician** (`technician-mobile`) | MTL **assigns / reassigns** (`MTL-WO-ASSIGN` → `PATCH …/assign`) | `ROUTED → ASSIGNED` (or `RETURNED → ASSIGNED`); `assignedToId = technician`; tech notified | Technician's `TECH-WO-TODAY` (new WO in their list) |
| **The work-order (terminal, internal)** | MTL **closes internally** (`MTL-WO-REVIEW` → `PATCH …/close`) — or the Technician marked Done | `→ DONE`; closes at the maintenance level; **Store Manager NOT notified**; `WorkOrderEvent` logged | drops off the MTL queue; counted in Closed today |
| **Store Manager** (`SM-WO-OUTSOURCE`) | MTL **escalates / outsources** (`MTL-WO-ESCALATE` → `PATCH …/outsource`, note required) | `RETURNED → OUTSOURCED`; report + photos sent to **this GZ's SM** — **the only WO state that reaches the SM** | SM's `SM-WO-OUTSOURCE` inbox (review + decide outsourcing) |
| **The source checklist (un-HOLD)** | the **last** open WO on an instance closes (`DONE`/`OUTSOURCED`) | parent `ChecklistInstance` auto-releases `HELD → TL_APPROVED`; cascade resumes; SM notified of the now-approvable checklist | operations TL/SM cascade (`*-CHK-OVERVIEW`); the inspection climbs to Done |

## The closed loop (where the MTL sits)

```
filler fills (A-item) ─submit─▶ operations TL verify
                                     │ (A-items present)
                                     ▼
                       route A-items ──▶ WorkOrder(s) ROUTED + parent checklist HELD
                                                 │
                                                 ▼
                       ┌──────────────  Maintenance TL (own GZ)  ──────────────┐
                       │  MTL-WO-QUEUE → DETAIL → ASSIGN  ──▶ Technician        │
                       │     Technician: start → DONE(+photo)  → closes here    │
                       │                 or → RETURNED(reason) → MTL-WO-REVIEW   │
                       │                         ├─ Reassign → ASSIGNED          │
                       │                         ├─ Close internally → DONE      │
                       │                         └─ Escalate → OUTSOURCED ──▶ SM │
                       └────────────────────────────────────────────────────────┘
                                                 │
                       last WO closes (DONE/OUTSOURCED) ──▶ checklist HELD → TL_APPROVED
                                                          (resumes TL → SM → OH cascade)
```

## Contract notes for the BE dev
- The MTL **never creates** WOs — `POST /work-orders` is the **operations TL's** call (from `TL-CHK-VERIFY`). The MTL consumes the resulting `ROUTED` rows.
- **Only `OUTSOURCED` notifies the SM (locked):** the `close`/`done` handler must **not** notify the SM. The `outsource` handler is the single MTL→SM channel; it surfaces on `SM-WO-OUTSOURCE` and carries the required `note` + photos.
- **HELD release is computed, not manual:** when any WO transitions to a terminal state (`DONE`/`OUTSOURCED`), the engine counts remaining non-terminal WOs for the parent instance (`WorkOrder @@unique(responseId)`); if zero, release `HELD → TL_APPROVED` and notify the SM. Implement once in the cascade engine; both `close` and `outsource` call it.
- **`If-Match` matters:** a Technician may return/start a WO while the MTL has the drawer open; an MTL assign/close/outsource on a stale version returns **409** so the two can't double-apply. The UI refetches the timeline.
- **MTL scope = own (L5):** the MTL only sees / acts on WOs in its own Game Zone; the outsource recipient is that GZ's SM. No cross-GZ WO is reachable (403).
- Do **not** expose fill / approval / photo-upload endpoints to the MTL — the resolver denies them. This pack is a work-order assigner + reviewer + escalator only.
