J-19 — Auto-Cleaning on Checkout (Online)
One-liner: Guest checks out; housekeeping automatically receives the room as "Vacant Dirty"; AI suggests an assignment; lead assigns; housekeeper completes; status updates everywhere.
1. Purpose
Upon a guest checking out (J-06), housekeeping receives the room as "Vacant Dirty" automatically; AI suggests an assignment based on housekeepers' workload + zone; lead reviews + assigns; housekeeper updates progress; on completion, room moves to "Clean / Inspected"; front desk knows it's available. Outcome: minimal latency from checkout to "ready to sell" with full visibility.
2. Persona Context
- Personas: Housekeeping Lead (assigner); Housekeeper (executor).
- Surface: Electron Desktop.
- Primary BFF:
bff-backoffice-service.
- Backing services:
housekeeping-service, front-desk-service, ai-orchestrator-service, audit-service.
- Preconditions: Housekeepers configured with zones; AI assignment guardrails set.
- Trigger:
melmastoon.front_desk.checkout.completed.v1 event arrives via SSE / outbox.
3. Entry Points
| # | Entry | Notes |
|---|
| 1 | SSE event from checkout | Default |
| 2 | Manual "Add cleaning task" by lead | Adhoc |
4. Screen-by-Screen Flow
4.1 HousekeepingKanbanScreen (Lead view)
- Layout: Kanban columns: Vacant Dirty / In Progress / Clean / Inspected; tiles per room with assignee avatar, ETA, priority pill; AI suggestion banner at top "5 new tasks - assign automatically".
- Components:
KanbanBoard, RoomTaskTile, AiSuggestionBanner.
- Offline: Reads from SQLite snapshot; status changes queued.
- AI: AI auto-assigns by guardrails (workload, zone) with HITL UI; lead can accept all, modify, or reject per task.
- Errors: AI degraded -> "Manual assignment only" banner.
- Loading: Sub-200 ms.
- A11y: Kanban is keyboard-navigable (per WAI APG); tiles have full aria-label.
- RTL: Mirror.
- Perf: Mount <= 200 ms; SSE updates <= 1 s.
- Telemetry:
frontend.housekeeping.kanban_viewed; frontend.housekeeping.ai_assign_action { action }.
4.2 AssignTaskModal
- Layout: Pick housekeeper (current load shown), priority, notes, ETA.
- Components:
Form, HousekeeperPicker, PrioritySelect.
- Offline: Local persist; queued.
- AI: None on modal itself.
- Errors: Validation per field.
- Loading: Submit <= 200 ms local / <= 500 ms online.
- A11y: Field labels.
- RTL: Mirror.
- Perf: <= 500 ms.
- Telemetry:
frontend.housekeeping.assigned { taskId, housekeeperId }.
4.3 HousekeeperTaskListScreen (Housekeeper view)
- Layout: Today's task list; per-task: room, status, "Start" / "Pause" / "Complete" actions; checklists (linens, bathroom, mini-bar restock).
- Components:
TaskList, Checklist, Button (variants).
- Offline: Local edits; queued.
- AI: None.
- Errors: Status conflict (already started) -> banner.
- Loading: Sub-200 ms.
- A11y: Each task is a tab stop; checklist items are checkboxes.
- RTL: Mirror.
- Perf: <= 200 ms.
- Telemetry:
frontend.housekeeping.task_started / _completed { taskId }.
4.4 InspectionScreen (Lead view)
- Layout: Per-room inspection checklist; pass/fail; notes; photo upload; "Mark inspected" CTA.
- Components:
InspectionChecklist, PhotoUpload, Button.
- Offline: Local edits; queued.
- AI: None.
- Errors: Validation.
- Loading: Submit <= 500 ms.
- A11y: Checkboxes labelled; photo upload has accessible progress.
- RTL: Mirror.
- Perf: <= 500 ms.
- Telemetry:
frontend.housekeeping.inspected { taskId, pass }.
5. State Machine
6. Data Requirements
6.1 Server state
GET /api/v1/housekeeping/tasks?propertyId=...&day=...
POST /api/v1/housekeeping/tasks/:id/assign (idempotent)
PATCH /api/v1/housekeeping/tasks/:id/status (idempotent)
POST /api/v1/housekeeping/tasks/:id/inspect (idempotent)
- SSE:
/api/v1/housekeeping/stream
6.2 Local persistence
- SQLite
housekeeping_tasks_local, outbox.
6.3 Idempotency
- All mutations carry
X-Idempotency-Key.
7. AI Behavior
| Surface | Purpose | Model | Edge / Cloud | HITL | Provenance | Fallback |
|---|
AiSuggestionBanner | Suggest auto-assignment | hk-assign-v1 | Cloud | Lead accepts/modifies/rejects per task | Pill | Manual assignment |
8. Offline Behavior
- Kanban from SQLite.
- Assignments local; flush on reconnect.
- AI degraded -> manual only.
9. Error States
| Error | Trigger | UX shown | Recovery | Telemetry |
|---|
AI_ASSIGN_DEGRADED | AI 5xx | Banner: "Manual assignment only" | Manual flow | error.surfaced { code } |
STATUS_CONFLICT | Concurrent status change | Banner with refresh | User refreshes | frontend.housekeeping.status_conflict |
INSPECTION_FAIL_REWORK | Inspection fail | Task back to InProgress; notes captured | Housekeeper fixes | frontend.housekeeping.rework { taskId } |
10. E2E Test Gates
- Composite gate
G-HK-1: checkout -> task created -> AI suggest -> assign -> in progress -> complete -> inspect -> available.
- AI degraded fallback.
- Inspection fail rework loop.
| Metric | Target |
|---|
| Kanban mount | <= 200 ms |
| SSE update | <= 1 s |
| Assign submit | <= 500 ms p95 |
12. Accessibility Requirements
- Kanban keyboard-navigable per WAI APG.
- Status changes announced.
- Photo upload progress accessible.
13. Telemetry
Frontend events
frontend.housekeeping.kanban_viewed
frontend.housekeeping.ai_assign_action { action }
frontend.housekeeping.assigned { taskId, housekeeperId }
frontend.housekeeping.task_started / _completed
frontend.housekeeping.inspected { taskId, pass }
Domain events emitted
melmastoon.housekeeping.task.created.v1
melmastoon.housekeeping.task.assigned.v1
melmastoon.housekeeping.task.status.changed.v1
melmastoon.housekeeping.task.inspected.v1
melmastoon.audit.recorded.v1
14. Success Criteria
- Time from checkout to "Available to sell" minimised; SSE refresh <= 1 s.
- AI suggestions follow HITL pattern.
- Inspection rework loop works correctly.
- Audit log records all assignments and status changes.
References