Skip to main content

Sprint 4 Plan — Production Readiness Demo Blockers

Source inputs:

Total raw findings: 134. After dedup: ~110 unique. Top 30 in Sprint 4.

Sprint structure​

SprintThemeDaysItems
4Demo blockers (silent failures, dead handlers, contract gaps, state-machine fixes, UUID leaks, hardcoded mocks)5-7~30
5Missing cross-module flows (POS↔folio, checkout payment collection, tax invoice for non-GST, key encoder, tape chart drag-drop, mobile app testing)7-10~12
6UX polish (alignment, time-precision tape chart, transition-history tabs, confirm dialog standardisation)3-4~10

Sprint 4 — ranked execution​

Block A — Silent-failure / fake-success patterns (Day 1, ~6 items)​

Highest priority because users see "success" toasts when nothing actually happened. Operationally dangerous.

#ItemFilesCloses
4-1Replace 5× catch { toast.success(...) } with real error toastcontrol-center/exceptions/page.tsx:201,213,527, control-center/actions/page.tsx:204,223Audit A-7
4-2key-cards/page.tsx replaceMutation.onError → real error toastfront-desk/key-cards/page.tsx:189-194A-8
4-3key-cards/page.tsx Encode New Card → real form dialog (not empty payload)front-desk/key-cards/page.tsx:215-218A-8
4-4keynova.tsx arrival cards onClick={() => {}} → router.push(dashboard)/keynova.tsx:320A-12
4-5"View full profile" Button onClick → Link href=/crm/guests/{id}reservations/[id]/keynova.tsx:1050Issue #4, A-13
4-6"View all →" span → Link to /housekeeping/staffhousekeeping/keynova.tsx:544A-15
4-7revenue-manager/strategy handleSave → real useUpdateRevenueStrategy() mutation OR hide page behind FLAGS.revenueManagerEnabled (default OFF)revenue-manager/strategy/page.tsx:117A-2

Block B — State machine post-action redirects (Day 1-2, ~7 items)​

#ItemFilesCloses
4-8Check-in success → router.replace('/front-desk/folio/' + id)front-desk/check-in/[id]/keynova.tsx:933Issue #1, C-1
4-9Folio detail page: read folio.status, gate Settle/Post Charge/Record Payment buttons; show SETTLED badgefront-desk/folio/[id]/page.tsxC-6
4-10Settle Folio onSuccess → router.push to /front-desk/check-out/${reservationId} if reservation is CHECKED_INfront-desk/folio/[id]/page.tsx:365C-7
4-11Add "Mark No-Show" action to /reservations/[id] overflow menureservations/[id]/keynova.tsxC-2
4-12Add "Confirm" button for PENDING reservationsreservations/[id]/keynova.tsxC-3
4-13Add "Cancel Order" / "Void Order" action to POS detail panelpos/orders/keynova.tsx:685C-12
4-14Universal guard-page improvement: every "wrong status" guard gets router.push CTAcheck-in :1026, check-out :325C-23

Block C — DTO contract critical fixes (Day 2-3, ~9 items)​

#ItemCloses
4-15Frontdesk Check-In DTO: required idDocumentType/Number, send reservationId in body, rename signature → signatureImageUrlB-10
4-16Settings Add User: add tenantId from session, type role against backend enum, validate password ≥12 charsB-3, B-5
4-17CRM Create Campaign + Drip Step: rebuild DTO with propertyId/channel/segmentRules/createdBy, uppercase all enumsB-6, B-19, Issue #3
4-18Guest Create: inject propertyId from store, uppercase Gender enumB-7
4-19Settings Create Rate Plan / Cancellation Policy: add propertyId, uppercase enumsB-8, B-9
4-20Folio Post Charge / Payment / Void: include folioId in body, uppercase enums, sanitize transactionCode regex, require reason ≥ 3 chars on voidB-11, B-12, B-13, Issue #17 path
4-21Housekeeping Create Task assignee: replace <Input> with user picker bound to housekeepingStaffApi.list()B-2, Issue #8
4-22Room Update Status: fix path to PATCH /rooms/:id/status; reconcile HousekeepingStatus enum (drop OUT_OF_ORDER/OUT_OF_SERVICE — those belong on RoomStatus)B-14, C-9, Issue #6
4-23DSAR enum: reconcile 5 backend ↔ 4 frontend states, add explicit translation layerC-19

Block D — Stub data hidden behind flags (Day 3-4, ~5 items)​

#ItemCloses
4-24Whole /revenue-manager section behind FLAGS.revenueManagerEnabled (default OFF). 5 pages of 100% mock data.A-1 to A-5
4-25Spa therapists/treatments/packages: replace placeholders with real EmptyState componentsA-9
4-26Housekeeping VIP_CHECKLIST hardcoded → load from existing /housekeeping/checklists endpoint per room typeA-14, Issue #7b
4-27Check-in keynova members hardcoded + handleEncodeKey fake toast → hide section OR wire to /front-desk/key-cards/encodeA-16, Issue #5 part
4-28POS receipt propertyName: 'Hotel' hardcoded → read from useAppStore.currentProperty.nameA-36

Block E — UUID rendering fixes (Day 4, batch ~6)​

#ItemCloses
4-29Backend addition + frontend rendering for performedByName/createdByName/assignedToName in 6 places: cash-management/safe, front-desk/phone, crm/dsar audit, housekeeping/inventory/reorder, pos/hardware, housekeeping/maintenanceA-30 to A-35, Issue #8 part, Issue #12
4-30Tape chart "(empty note) UUID" → check why note.text is empty for those rows + suppress display when emptyIssue #12

Sprint 5 — Missing cross-module flows (separate plan, 7-10 days)​

#ItemIssue
5-1POS → folio room charge end-to-end: pos/orders Charge to Room → reservation lookup → folio.postCharge → folio shows lineIssue #10
5-2Collect payment from checkout: Outstanding-balance error → "Settle now" button → opens folio settle dialog → returns to checkoutIssue #17
5-3Tax invoice for non-GST properties: e-invoice GST-regime gate → fall-through to plain Tax Invoice PDFIssue #16
5-4Tape chart drag-drop wiring: move room, extend stay, assign unassigned guest — all 3 silent todayIssues #13, #14, #15
5-5Move Key Setup panel from Folio tab to its own tab on /reservations/[id]Issue #5a
5-6Wire real key encoder hardware (already has env config; need driver + UI)Issue #5b
5-7Mobile app testing scaffold for housekeeping (currently hmp-mobile-apps exists but no test path)Issue #7d

Sprint 6 — UX polish + remaining (3-4 days)​

#ItemIssue
6-1Activity panel text/timeline overlapIssue #2
6-2Tape chart bar use clock-time positioning (12 noon → 11 AM proportional) instead of whole-day cellsIssue #11
6-3Adopt banquet's STATUS_TRANSITIONS declarative pattern for reservation, folio, POS order, HK task, DSARC-6
6-4Add transition history tab to all status-bearing entitiesC-24
6-5Standardise confirm dialogs (AlertDialog for any irreversible transition)C-27

Execution rhythm​

Same as Sprint 1/2/3:

  • Per item: edit → typecheck → commit → push
  • Every 5 items: rebuild dashboard, restart local container, smoke check
  • End of each block: deploy to QA, do manual smoke on the affected surface
  • Tasks tracked via TaskCreate/TaskUpdate

Approval gate​

This plan covers 30 Sprint 4 items. If approved, I'll execute in order — Block A → B → C → D → E. Each block ends with a commit batch + QA deploy. ETA 5-7 working days at the same pace as Sprint 1/2/3.

If you want to compress: I can skip Block C frontend-only fixes for items where the bug is a backend response issue you'd rather fix on the backend (like POS Add Menu Item isAvailable → adding to backend DTO instead of removing from form).

Otherwise, proceeding with execution starting from item 4-1.