# Cleaning Supervisor (Mobile) — Developer Task Breakdown

> Source-of-truth task list for the Cleaning Supervisor slot (dev-mode v1.0, Step 3b). One row per screen + the shared dependencies. Surface = Flutter mobile portrait.
> **This is a CLONE of the anchor** (`staff-court-monitor-mobile`). If the anchor's Flutter screens are role-generic (render nav + items from `/me` + instance data), most rows below are **"reuse anchor widget; supply cleaning data"** rather than net-new UI.
> **Team for this slot:** Mobile (Flutter) FE + Backend (shared with TL/SM cascade) + Tester. No web-FE (mobile-primary role).
> **Priority:** P0 (must-ship Phase 1) · P1 (nice-to-have).
> **Dependencies** are topological — build in order. Foundation (Wave 0) precedes everything: schema, auth, runtime RBAC resolver, auto-assign engine, approval cascade, `/me`, photo endpoint, Flutter DS parity, generated Dart models. The anchor (MON) precedes this clone.

---

## Columns
| Column | Meaning |
|---|---|
| Screen ID | Stable short ID (cross-refs `spec.md`, `api-contract.md`). |
| Screen file | Path under `screens/` (the pixel target). |
| States / sheets | The `states/` + `bottom-sheets/` variants to wire. |
| Dependencies | What must exist first. |
| Mobile-FE tasks | Flutter widget/route/repository work (mostly anchor reuse). |
| Backend tasks | Endpoint(s) + logic + migration notes (most are Wave-0 shared). |
| Pri | P0 / P1. |

---

## Auth + bootstrap

### AUTH-LOGIN — Login
| Field | Value |
|---|---|
| Screen file | `screens/01-login.html` |
| States / sheets | `states/locked.html`, `states/error.html` |
| Dependencies | Wave-0 auth + `/me` (reuse anchor login screen verbatim) |
| Mobile-FE tasks | **Reuse anchor login** — no change; on success `GET /me` → route by role (resolves CS). |
| Backend tasks | (Wave 0) `POST /auth/login` (bcrypt, JWT access+refresh, rate-limit→423/429); refresh/logout/forgot/reset; `POST /devices/register`. |
| Pri | P0 |

### CS-DASH — Cleaning Supervisor Home (role-resolved)
| Field | Value |
|---|---|
| Screen file | `screens/02-dashboard.html` |
| States / sheets | `states/loading.html`, `states/empty.html` |
| Dependencies | AUTH-LOGIN; Wave-0 `/me`; **cleaning auto-assign branch** (BE — see gap) |
| Mobile-FE tasks | Reuse the anchor mobile shell (navy top bar + Game-Zone scope strip + 5-slot bottom nav + FAB); **slot 2 renders "Cleaning" / `spray-can` from `/me.nav`**; shift card + KPI tiles + today's cleaning checklist list; overdue badge; nothing-assigned empty; loading skeleton. |
| Backend tasks | `GET /me/dashboard` (own GZ + own assignments; counts by state; shift). `/me.nav` returns the CS slot config. |
| Pri | P0 |

## Checklist core (the clone flow)

### CS-CHK-TODAY — Today's Checklists
| Field | Value |
|---|---|
| Screen file | `screens/03-today-checklists.html` |
| States / sheets | `states/loading.html`, `states/empty.html`, `states/error.html`, `states/forbidden.html` |
| Dependencies | CS-DASH; cleaning auto-assign branch (Wave 0 + CS branch) |
| Mobile-FE tasks | Reuse anchor list widget: `ChecklistInstance` rows (template name + frequency tag + item-count + `StatusBadge` + "📷 needed"); tap → fill / status; loud Sent-back row + Re-fill. Data = cleaning/hygiene instances. |
| Backend tasks | `GET /me/checklists/today` (own assignments, own GZ; category `cleaning_hygiene` rows). |
| Pri | P0 |

### CS-CHK-FILL — Fill Checklist (CRITICAL)
| Field | Value |
|---|---|
| Screen file | `screens/04-checklist-fill.html` |
| States / sheets | `bottom-sheets/photo-capture.html`, `bottom-sheets/a-item-note-photo.html`, `states/offline.html` |
| Dependencies | CS-CHK-TODAY; photo endpoint (Wave 0); instance detail |
| Mobile-FE tasks | Reuse anchor fill widget: sectioned `ChecklistItem` rows with 44px **G/A segmented toggle** (G green / A red-orange, color+icon+label); **read-only server time + auto initials** ("SY", §9 #9 — client does NOT enter them); on **A** open the A-note+photo sheet + flag photo-required; completion-photo `PhotoUpload` tile → photo-capture sheet; multipart upload; save responses (`PATCH …/responses`, `If-Match`) as draft; **offline: hold draft in memory + retry**; FAB = camera. Item text = cleaning/hygiene. |
| Backend tasks | `GET /checklist-instances/:id` (filler+GZ scoped, version/ETag); `PATCH …/responses` (upsert; **stamp `recordedAt`=server time + `initials`=derived**; set `fillerId`; bump version; 409 stale; audit); `POST /uploads/photos` (multipart → **local disk**, `sharp` thumb, `Photo` row); `DELETE /uploads/photos/:id`. |
| Pri | P0 |

### CS-CHK-SUBMIT — Submit Checklist
| Field | Value |
|---|---|
| Screen file | `screens/05-checklist-submit.html` |
| States / sheets | `bottom-sheets/confirm-submit.html`, `states/offline.html`, `states/error.html` |
| Dependencies | CS-CHK-FILL; cascade engine (Wave 0) |
| Mobile-FE tasks | Reuse anchor submit widget: review summary (G/A counts, completion + A-item thumbnails); enforce the photo/answer **gate client-side** (≥1 completion photo, §9 #7) with inline danger; confirm-submit sheet; `POST …/submit`; handle 422; on success route to status. |
| Backend tasks | `POST /checklist-instances/:id/submit` — **re-check gate (422 if untouched item / no completion photo / missing A-photo)**; state→`SUBMITTED`; create TL/SM/OH `ApprovalStep`s; **notify TL (FCM + in-app)**; audit. (Same handler as anchor.) |
| Pri | P0 |

### CS-CHK-STATUS — My Checklist Status
| Field | Value |
|---|---|
| Screen file | `screens/06-my-status.html` |
| States / sheets | `states/empty.html`, sent-back banner (inline) |
| Dependencies | CS-CHK-SUBMIT; cascade (Wave 0); send-back from TL/SM/OH packs |
| Mobile-FE tasks | Reuse anchor `ApprovalTimeline` vertical stepper (Filled→TL→SM→OH) with actor/role/timestamp + `StatusBadge`; show **real sub-state** (never Pending); **Sent-back red banner + reason + Re-fill** → reopen fill; `/me/submissions` list. Filled-by node reads "Suresh (Cleaning Supervisor)". |
| Backend tasks | `GET /me/submissions`; `GET /checklist-instances/:id/timeline`; `renderStatusForViewer()` (shared, Wave 0). |
| Pri | P0 |

## Supporting screens

### CS-ROSTER-OWN — My Roster (read-only)
| Field | Value |
|---|---|
| Screen file | `screens/08-my-roster.html` |
| States / sheets | `states/empty.html`, day/week toggle |
| Dependencies | Wave-0 roster |
| Mobile-FE tasks | Reuse anchor roster widget: day/week toggle; own `RosterEntry` rows (cleaning area + shift, template-colored blocks); leave overlay; **no create/edit affordance**. |
| Backend tasks | `GET /me/roster?date=` / `?weekOf=` (own entries only; roster-create denied to CS by resolver). |
| Pri | P0 |

### SH-PROFILE — Profile / More
| Field | Value |
|---|---|
| Screen file | `screens/07-profile.html` |
| States / sheets | — |
| Dependencies | Wave-0 `/me` |
| Mobile-FE tasks | Reuse anchor profile widget: name, role ("Cleaning Supervisor"), Game Zone, reports-to, **cleaning areas** (chips); Alerts entry; logout (confirm → clear tokens → login). |
| Backend tasks | `GET /me/profile`; `POST /auth/logout`; `GET /me/notifications` + read. |
| Pri | P0 |

---

## Net-new work for this clone (everything else is anchor reuse)
1. **(BE)** Cleaning auto-assign branch — match `cleaning_hygiene` templates by role + cleaning area + shift (NOT ride-cert). See the gap in `api-contract.md`; confirm option (a)/(b) at the demo.
2. **(Seed)** "Cleaning / Hygiene — Daily" + washroom/café/court hygiene templates with their G/A items + frequencies.
3. **(FE)** Confirm `/me.nav` slot 2 renders "Cleaning" / `spray-can`; supply cleaning copy. No bespoke screen code if anchor widgets are role-generic.
4. **(Test)** Re-run the anchor integration suite with cleaning seed data (photo-gate, send-back-to-filler, scope).

## Build order (topological)
1. **(Wave 0)** auth, `/me`, RBAC resolver, schema, auto-assign (+ cleaning branch), cascade, photo endpoint, Flutter DS, Dart models — and the **anchor (MON)** built first.
2. `AUTH-LOGIN` → `CS-DASH` (shell + role-resolve + slot-2 "Cleaning").
3. `CS-CHK-TODAY` → `CS-CHK-FILL` → `CS-CHK-SUBMIT` (clone the anchor flow with cleaning data).
4. `CS-CHK-STATUS` (depends on submit + cascade + the TL send-back touchpoint).
5. `CS-ROSTER-OWN`, `SH-PROFILE` (independent; can run in parallel).

> The CS demo gate: **Suresh logs in → opens Cleaning / Hygiene — Daily → ticks G/A with a completion photo + an A-item photo → submit blocked then passes → submitted → TL notified → status timeline shows awaiting-TL → (TL sends back) red banner + Re-fill.** Because this clones the anchor, closing it should be a short re-skin + the cleaning auto-assign branch.
