# Team Leader (Web) — Developer Handoff

> Handoff pack for **dev-mode v1.0 slot 6 — Step 3b, first pack mirrored off the ANCHOR** (`staff-court-monitor-mobile`). Built 2026-06-18 from the locked design (`docs/design/SCREEN_LIST.md` TL block, `docs/design/DESIGN_SYSTEM.md`, `docs/dev-mode-v1.0/FOUNDATION_SPEC.md`).
> Persona: **Priya Nair** · Team Leader · Game Zone Ahmedabad-1 · reports to Rohit Shah (SM) · team = {Ramesh (MON), Karan (SCM), Suresh (CS)} · Trampoline + Toddler certified.
> Surface: **Web (Next.js), 1440×900.** Covers **Team Leader AND Trainee TL** — identical nav/screens; **Trainee TL = assist-only** (Approve/Send-back/Route disabled, CL-3 — amends `§9 #4`). **The TL mobile companion is a separate mobile sub-phase deliverable.**
> **Change List v1.1 applied (2026-06-19):** + `TL-CHK-UPLOAD` (team-scoped Upload Check List, CL-1) · `TL-CHK-VERIFY` Route-to-Maintenance + single-track Hold (CL-2) · Trainee-TL assist-only (CL-3) · `TL-ROSTER-REASSIGN` mid-shift reassign (CL-4). **TL is now 12 role screens / 14 mockups.**

---

## Who consumes which file

| Role | Primary file | Why |
|---|---|---|
| **Web Frontend (Next.js) Developer** | `tasks.md` Web-FE column → filter `Priority=P0`, sort by Dependencies. Build queue. Pixel target = `screens/*.html` at 1440px. | Builds the verify→approve / send-back flow + team dashboard/overview/roster/report from the web design-system; photo-viewer lightbox + approve/send-back modals + the (optional) TL fill flow. |
| **Backend Developer** | `tasks.md` Backend column + `api-contract.md` + `FOUNDATION_SPEC §3/§4`. | The endpoints in `api-contract.md`; the **approve / sendback** consumer side (the anchor's submit producer lands here); resolver-gated approve-by-level; team-scoped roster + reassign. |
| **Tester** | `spec.md` acceptance summary + the two `flows/`. | API + UI tests: approve transitions, send-back-to-filler + reason-required, cascade-restart-from-TL, derived Pending above TL, team-only scope, TL-can't-self-approve. |
| **Mobile (Flutter) Developer** | **Deferred to the TL mobile sub-phase** — the TL mobile companion (`TL-DASH`, `TL-CHK-VERIFY`, `TL-ROSTER-VIEW` on the 5-slot bottom-nav) reuses this pack's contracts. | — |

---

## Definition of Done for slot-6 (TL web) implementation

The slot ships when all P0 behaviours in `spec.md` pass in a UAT build, evidenced by:

1. **Login → role-resolve:** login routes to the TL Dashboard via `GET /me`; the sidebar (**7 items**, incl. Upload Check List) + permissions (incl. `checklist.approve` scope `own_team`) come from the server — **no hardcoded role logic**.
2. **Dashboard integrity:** `TL-DASH` shows the **awaiting-my-approval** queue + team today-progress + overdue/gaps, scoped to own team + Game Zone; KPI counts match the overview.
3. **Verify review (read-only):** `TL-CHK-VERIFY` renders the filler's G/A items + notes + time + initials and all photos via the **photo-viewer lightbox** (`§6.12` viewer mode); the TL cannot edit responses.
4. **Approve (DESIGN_SYSTEM §6.4):** Approve = green; on confirm the instance → `TL_APPROVED`, `ApprovalStep[1].APPROVE` + `ApprovalLog` written, **SM notified**, row leaves the queue, timeline flips to `TL Approved ✓`.
5. **Send-back to filler (§9 #3):** Send-back = red, **reason required** (UI blocks empty + server 422); on confirm → `SENT_BACK`, returns to the **original filler** (not the previous approver), filler notified.
6. **Cascade restart (§9 #8):** after a sent-back re-fill + re-submit, the instance re-enters the TL verify queue (fresh cascade from TL).
7. **Derived Pending above TL (§9 #5):** once TL approves, SM/OH read **Pending** at their level; the TL's own overview shows the **real sub-state** climbing above (SM Approved / Done) — via the shared `renderStatusForViewer()`.
8. **TL can fill:** `TL-CHK-FILL` runs the same photo-gated fill→submit flow (G/A toggle, completion + per-A photo, submit blocked UI+422); a TL-filled submission routes to **SM** next (TL can't self-approve); time = **server time**, initials **auto-derived** (`§9 #9`).
9. **Team roster + report:** `TL-ROSTER` builds team-scoped roster + **publish fires auto-assign for the team**; out-of-team user → 403. `TL-REP-NEGATIVE` shows A items + issue photos with all-clear empty state + export.
10. **States:** loading (skeleton), empty/all-clear, error+retry, **offline-retry preserving the in-memory draft**, locked (login), 403 (out-of-team / out-of-Game-Zone) all render and are reachable.
11. **Chrome + scope:** navy 240px sidebar + topbar **branch badge + team indicator** (no Game-Zone selector — OH only), matching `DESIGN_SYSTEM §8.1`; no cross-team / cross-Game-Zone data leak; CI TS-model drift gate green.
12. **Route-to-Maintenance + Hold (CL-2):** an A-item on a verified checklist routes via `POST /work-orders` → `WorkOrder ROUTED`, Maintenance TL notified, instance **`HELD`**; HeldBanner shows and **Approve is locked** until **every** WO closes (`DONE`/`OUTSOURCED`) → `HELD → TL_APPROVED`. Held surfaces on `TL-DASH` + `TL-CHK-OVERVIEW`.
13. **Trainee TL assist-only (CL-3):** same nav/screens; Approve / Send-back / Route / reassign / template-write render **disabled** driven by `/me` permission flags (`allowed:false`), never hardcoded role checks — `states/trainee-tl-assist-only.html`.
14. **Mid-shift reassign (CL-4):** `PATCH /roster-entries/:id/reassign` re-targets the new ride's **`NOT_STARTED`** instances to the monitor, moves the old ride to its current holder, FCM-updates both mobiles live; **`IN_PROGRESS`/`SUBMITTED` never withdrawn**; certified-on-new-ride gated.
15. **Upload Check List (CL-1):** team-scoped ChecklistBuilder (`TL-CHK-UPLOAD`) creates/assigns/edits templates constrained to own team + Game Zone (GZ-wide → 403); feeds auto-assign.

P1 items are nice-to-have for the slot; out-of-slot items (SM/OH approval, branch-wide roster + bulk upload, positive/overdue reports, user onboarding, **GZ-wide/cross-team template authoring**, **maintenance WO working** — assign/close/outsource, TL mobile companion) are explicitly not here.

---

## Slot scope at a glance

- **14 screen mockups** (login, dashboard, team, member-detail, checklist-overview, verify, fill, roster-builder, **roster-reassign**, roster-view, assign, **checklist-upload**, profile, negative-report) · **7 state variants** (+ trainee-tl-assist-only) · **6 modals** (+ route-to-maintenance, reassign-monitor) = **27 HTML artifacts** (PNG render is a later step).
- Endpoints consumed: auth (login/refresh/logout/forgot/reset), `/me`, team dashboard, team list + member detail, team checklist overview, **instance detail + approve + sendback** (NEW vs anchor), **`POST /work-orders` route-to-maintenance** (CL-2), fill (responses/submit/photos), team roster + publish, instance reassign, **`PATCH /roster-entries/:id/reassign` + `/me/team/floor`** (CL-4), **team checklist-template CRUD** (CL-1), team negative report + export, notifications, device register.
- **This pack mirrors the anchor's structure** (same file set, web → `modals/`) but is **not a clone** — it adds the first-approver Verify/Approve + Send-back + team-roster + negative-report screens the filler anchor excluded. SM and OH packs will reuse this pack's approval + report shapes at cascade levels 2/3.

## Blocking questions / decisions before fan-out (resolved + remaining)

> Most anchor blockers were resolved in `PROJECT_PLAN §9`. Re-stated here with TL-specific notes:

- [x] **Send-back destination** (`§9 #3`): straight to the **original filler** — locked. TL UI reflects this (returns to Ramesh, not down one step).
- [x] **Re-fill after send-back** (`§9 #8`): cascade **restarts from TL** — locked. TL verify queue re-receives the instance.
- [x] **Time-stamp + initials** (`§9 #9`): **server time** + **auto-derived initials** — locked. `TL-CHK-FILL` shows them read-only.
- [x] **Trainee TL rights** (`§9 #4`, **amended by CL-3**): **assist-only** — same nav/screens, but Approve/Send-back/Route/reassign/template-write resolve `allowed:false`. One pack, one nav, **two permission sets** (TL vs Trainee), resolver-gated.
- [ ] **WO terminal → hold release (CL-2):** confirm the engine releases `HELD → TL_APPROVED` only when **every** `WorkOrder` for the instance is `DONE`/`OUTSOURCED` (computed from `WorkOrder @@unique(responseId)` counts). Flag for BE; cross-pack with `maintenance-tl-web`.
- [ ] **Reassign in-progress safety (CL-4):** confirm only `NOT_STARTED` instances re-target on `PATCH …/reassign`; `IN_PROGRESS`/`SUBMITTED` stay with the original filler. Flag for BE.
- [ ] **TL self-approval guard:** confirmed that a TL-filled instance routes to **SM** (a TL cannot approve its own submission) — needs the resolver rule (`fillerId == caller.id` ⇒ no level-1 approve grant on that instance). Flag for BE.
- [ ] **TL roster publish scope:** can a TL publish its **team's** entries independently, or only the SM publishes branch-wide? Spec assumes TL may publish its own team window (Team scope, access matrix). Confirm at demo whether publish is TL-allowed or SM-only.
- [ ] **Ride↔template auto-assign map** (`§9 #2`, `DEV_EXECUTION_PLAN D4`): the engine is generic; the seed rows (which templates per ride, which shift role is the 114-pt opener) are confirmed at the client demo — affects what lands on the TL's team progress + overview.
- [ ] **FCM on web/iOS** (`§9 #10`): provision FCM (web push) + APNs (for the later TL mobile companion) so the SM-notify-on-TL-approve touchpoint is testable end-to-end.
- [ ] **Tester model** (`§9 #11`): pooled tester owns the approve/sendback + cascade-restart integration suite shared across TL/SM/OH packs.

---

## File references
- Pack root: `docs/design/dev-mode-v1.0/team-leader-web/`
- Anchor (mirrored): `docs/design/dev-mode-v1.0/staff-court-monitor-mobile/`
- Screens: `screens/*.html` · States: `states/*.html` · Modals: `modals/*.html`
- Spec: `spec.md` · API: `api-contract.md` · Handoffs: `HANDOFFS.md` · Flows: `flows/*.md`
- Foundation: `docs/dev-mode-v1.0/FOUNDATION_SPEC.md` · Dev plan: `docs/dev-mode-v1.0/DEV_EXECUTION_PLAN.md`
- Project plan: `docs/PROJECT_PLAN.md` · Design system: `docs/design/DESIGN_SYSTEM.md` · Workflow: `docs/WORKFLOW_GUIDE.md`
