Skip to main content

Property #1 Launch Roadmap — 2026-05-06

Source: property-1-launch-review-2026-05-06.md (audit verdict: NO-GO; 11 RED + 2 AMBER + 0 GREEN; ~73 P0 findings). Decision target: ship a credible Property #1 launch in 6–8 weeks. Team assumption: 5 senior engineers across services + 1 PM/release engineer.


§0 — Wave plan (one-page summary)​

WaveWindowThemeExit gate
W0Day 0–3Decision & containmentBoot guards in place; flags flipped; route disablements done; CLAUDE.md drift fixed; team committed to a wave plan. No code changes that introduce risk; only switches/guards.
W1Week 1–2Money & compliance hard blockersA guest cannot complete a booking that bypasses HMAC; FRRO is enforced on every check-in path; invoice numbers are gap-free; e-invoice cannot run in mock in prod.
W2Week 3–4Operational completenessTape Chart can perform every operation a front-desk agent needs; night audit is idempotent at the DB level; KPI tiles render correct numbers; reports respect property timezone.
W3Week 5–6Hardening & P1 sweepBuild script fails on TS errors; xPrisma migration plan signed-off (not necessarily complete); audit trail on every privileged mutation; mobile HK photo flow works.
W4Week 7–8Launch gate & soakHero-feature E2E suite ≥ 20 specs all green; real NIC IRP sandbox passes 50 invoices end-to-end; one-week soak run on QA with synthetic traffic; security + compliance signoff.

Each wave has an explicit gate. No wave starts until prior gate passes. The gate is the launch contract.


§1 — Tracks (work splits within each wave)​

Five concurrent tracks let 5 engineers operate without stepping on each other:

TrackOwner skillServices touchedWave 0 → 4 commitment
A — Money flowBackend + paymentsreservation, payment, frontdesk, notification60% / 100% / 60% / 40% / 30%
B — ComplianceBackend + Indian regulatoryfrontdesk, guest, notification80% / 100% / 40% / 20% / 30%
C — Operations UXFrontend + dashboardhmp-web-dashboard, hmp-mobile-apps20% / 60% / 100% / 40% / 30%
D — Data & reportsBackend + analyticsanalytics, reservation, property20% / 30% / 80% / 80% / 30%
E — Platform hygieneDevEx + infrashared-packages, infrastructure, all services60% / 30% / 30% / 100% / 60%

Percentages are share of the engineer's week dedicated to that track during the wave.


§2 — Wave 0 — Decision & Containment (Day 0–3)​

Goal: stop the worst outcomes from happening while we plan the real fixes. No new features, only switches, guards, and disablements. Each item ≤ 0.5 day.

W0.1 — Production boot guards​

IDActionFileOwnerEffortDone when
W0.1.1Add boot validator: throw when NODE_ENV='production' && EINVOICE_MOCK !== 'false'hmp-frontdesk-service/src/einvoice/einvoice.module.tsTrack B0.25dService refuses to start in prod with mock IRN
W0.1.2Add boot validator: throw when NODE_ENV='production' && (RAZORPAY_KEY_ID undefined OR RAZORPAY_KEY_SECRET undefined) for any property using booking enginehmp-payment-service/src/main.ts + hmp-reservation-service/src/booking-engine/booking-engine.module.tsTrack A0.5dService refuses to start without keys
W0.1.3Add boot validator: ENCRYPTION_KEY required in frontdesk-service for ID document storagehmp-frontdesk-service/src/checkin/checkin.module.tsTrack B0.25dService refuses fallback-to-plaintext path in prod

W0.2 — Route / endpoint disablements​

IDActionFileOwnerEffortDone when
W0.2.1Disable POST /express-check-in until W1 implements it (return 503 "feature disabled")hmp-frontdesk-service/src/checkin/checkin.controller.tsTrack B0.25dRoute returns 503
W0.2.2Add API-key gate to booking-engine search/availability/calendar (currently REQUIRE_API_KEY=false)hmp-reservation-service/src/booking-engine/booking-engine.controller.ts:71,86,94,104Track A0.5dAnonymous request → 401
W0.2.3Add gateway rate-limit bucket for booking-engine search (10/min/IP)hmp-api-gateway/src/middleware/rate-limit.middleware.tsTrack A0.5dBurst denied with 429

W0.3 — Documentation drift​

IDActionFileOwnerEffortDone when
W0.3.1Remove SUBSCRIPTION_VIA_PAYMENT_SERVICE_ENABLED flag claim from root CLAUDE.md (flag is gone from code)CLAUDE.mdTrack E0.25dCLAUDE.md matches code
W0.3.2Remove MenuItem.hsnCode exists claim from hmp-pos-service/CLAUDE.md (column does not exist)hmp-pos-service/CLAUDE.mdTrack E0.25dDoc matches schema
W0.3.3Replace JWT_PUBLIC_KEY hard-coded PEM in docker-compose.dev-all.yml:32 with env-var resolution; rotate the leaked key in any environment that used ithmp-infrastructure/docker/docker-compose.dev-all.ymlTrack E0.5dNo PEM in master
W0.3.4Move hmp-booking-engine from feature/be-goat-phase-8 back to master (or accept the branch is the launch artifact and document it)hmp-booking-engine repoTrack AdecisionDecision recorded; branch policy clear

W0.4 — Wave plan signoff​

IDActionOwnerDone when
W0.4.1PM + tech leads review this roadmap; assign engineers to tracks; set start-of-wave-1 datePMAll-hands signoff captured in writing
W0.4.2Decide which P1 items get pulled into W1–W2 vs deferred to W3PM + leadsTagged in this document

W0 exit gate (must all be green to start W1):

  • All boot guards merged and deployed to staging.
  • Express check-in route disabled in staging + prod compose.
  • Booking-engine search behind API key + rate limit.
  • CLAUDE.md drift fixed.
  • JWT PEM rotated out of dev-all compose; old key revoked from any system that trusted it.
  • Roadmap signed off; engineers assigned to tracks.

§3 — Wave 1 — Money & Compliance Hard Blockers (Week 1–2)​

Goal: close every defect that costs money or violates Indian law. Two highest-blast-radius areas: the booking → payment → folio money path, and the FRRO / IRN compliance surface.

W1 — Track A: Money flow​

IDBlockerFilesEffortAcceptance criteria
W1.A.1Booking last-room race — add SELECT … FOR UPDATE per (propertyId, roomTypeId, date) lock row inside createBooking transaction; add @@unique([propertyId, roomTypeId, date]) on a per-night inventory rowhmp-reservation-service/src/booking-engine/booking-engine.service.ts:981-1068; prisma/schema.prisma:1873dConcurrency regression test: N parallel createBooking calls for last room produce exactly 1 CONFIRMED
W1.A.2Razorpay verifyPayment HMAC bypass — remove the "mock fallback for dev/demo" branch; force verifyPayment to fail closed when keys absenthmp-reservation-service/src/booking-engine/booking-engine.service.ts:1741-1754, 1888-19381dTest asserts: PENDING → CONFIRMED only on valid HMAC; missing keys = 500, never auto-confirm
W1.A.3Idempotency-Key on createBookingFromEnginehmp-reservation-service/src/booking-engine/booking-engine.service.ts:15080.5dDouble-click test: duplicate request → 1 reservation
W1.A.4FOLIO_PAYMENT_RECEIVED publish from inline checkout paymentshmp-frontdesk-service/src/checkout/checkout.service.ts:2360.5dReservation paidAmount/balanceDue updates after every checkout payment
W1.A.5IRN ack number overwrites sequential invoice number — drop the overwrite; keep sequential valuehmp-frontdesk-service/src/einvoice/einvoice-job.processor.ts:640.5dAfter IRN, Folio.invoiceNumber retains FY-sequential value; Folio.ackNumber holds NIC ack
W1.A.6Two divergent invoice-number generators — delete getNextInvoiceNumber in invoice-pdf.service.ts; pull from canonical FoliosService.getNextInvoiceNumberhmp-frontdesk-service/src/einvoice/invoice-pdf.service.ts:601-6181dSingle-source-of-truth test
W1.A.7Split-payment support at checkout — extend CheckOutDto to payments: { mode, amount, reference, cardLast4? }[]; loop inline settlehmp-frontdesk-service/src/checkout/dto/checkout.dto.ts:30; checkout.service.ts:215-2673dCash + card split test passes; Payment.cardLast4/cardType populated
W1.A.8Invoice attachment on thank-you email — publish typed folio.settled event; dispatcher fetches PDF and attaches via SendGridhmp-frontdesk-service/src/checkout/checkout.service.ts; hmp-notification-service/src/dispatcher/dispatcher.service.ts:130-1321.5dTest: checkout → email arrives with PDF attachment
W1.A.9Service-charge GST hardcoded 0.18 — read from property tax confighmp-pos-service/src/orders/orders.service.ts:140, 807, 9520.5dGST-exempt property has 0% service-charge GST
W1.A.10Razorpay terminal adapter sends defunct X-Payment-Idempotency-Keyhmp-payment-service/src/adapters/razorpay/razorpay-terminal.adapter.ts:184, 2930.25dHeader replaced with X-Razorpay-Idempotency-Key matching gateway adapter

Track A wave-1 effort: ≈ 11.75 engineer-days.

W1 — Track B: Compliance​

IDBlockerFilesEffortAcceptance criteria
W1.B.1ID photo upload — switch to S3 presigned uploadhmp-web-dashboard/src/app/(dashboard)/front-desk/check-in/[id]/keynova.tsx:444-446, 966; hmp-frontdesk-service/src/checkin/dto/checkin.dto.ts:152-1592dE2E: file picked → uploaded to S3 → check-in submitted with HTTPS URL → 201
W1.B.2Empty-nationality bypass FRRO — reject check-in with nationality === '' OR nullhmp-frontdesk-service/src/checkin/checkin.service.ts:189-1940.5dTest: nationality blank → 400 with message "Nationality required"
W1.B.3Walk-in path FRRO enforcement — add identical FRRO block to walkIn(); WalkInDto accepts formChmp-frontdesk-service/src/checkin/checkin.service.ts walkIn(); dto/checkin.dto.ts:212-2781dTest: foreign walk-in without formC → 400
W1.B.4Express check-in implementation — full check-in flow OR keep route disabled with explicit dochmp-frontdesk-service/src/checkin/checkin.service.ts:691-7521dEither implemented (with FRRO) or disabled with operator-facing notice
W1.B.5Police-register PII feed — decrypt formCDataEncrypted, populate columns, respect DPDPA logginghmp-frontdesk-service/src/reporting-feeds/reporting-feeds.service.ts:4582dTest: feed includes passport/Aadhaar last-4 with audit trail of access
W1.B.6arrivedFrom / purposeOfVisit / visaType plumbing — dashboard inputs flow through to Form C PDFhmp-frontdesk-service/src/cform/cform.service.ts:312, 318-319; dashboard check-in page1dTest: PDF includes operator-supplied arrivedFrom, visaType
W1.B.7Signature field name mismatch — rename or add aliashmp-web-dashboard/src/lib/api/front-desk.ts:37; hmp-frontdesk-service/src/checkin/dto/checkin.dto.ts:1560.25dSignature persisted from dashboard payload
W1.B.8GuestIdVerification plaintext fallback — hard-fail in prod when ENCRYPTION_KEY absent (boot guard W0.1.3 already deployed; remove fallback path)hmp-frontdesk-service/src/checkin/checkin.service.ts:91-950.5dPlaintext branch removed
W1.B.9HOUSEKEEPING_TASK_CREATED dedup at HK consumerhmp-housekeeping-service/src/events/events.service.ts:1550.5dTest: checkout → 1 HK task, not 2
W1.B.10Folio.guestGstin field for individual B2B guests; place-of-supply inference for B2Chmp-frontdesk-service/prisma/schema.prisma; einvoice.service.ts:99-1101.5dTest: B2C guest from different state → IGST split

Track B wave-1 effort: ≈ 10.25 engineer-days.

W1 — Track E: Platform support (parallel)​

IDBlockerFilesEffortAcceptance criteria
W1.E.1Build script || true removed in 16 backend servicesevery backend package.json "build" field1dTS error → build fails → CI red
W1.E.2Two-file rule fixes — /extra-charges, /seasons decorator/config additionshmp-api-gateway/src/proxy/proxy.controller.ts; src/config/services.config.ts0.5dSmoke test: paths route correctly

Track E wave-1 effort: ≈ 1.5 engineer-days.

Wave 1 total effort: ≈ 23.5 engineer-days. Across 5 engineers × 10 working days = 50 engineer-days available. Slack for context-switch + reviews + bugs.

W1 exit gate:

  • Concurrency test in CI proves last-room race is closed.
  • No code path exists to confirm a reservation without HMAC verification.
  • Foreign-guest check-in (booking engine, walk-in, dashboard) all enforce FRRO; empty nationality is rejected.
  • ID photo + signature persist correctly end-to-end on a real S3 bucket.
  • Police-register feed returns real (decrypted, audited) data.
  • Invoice numbers are gap-free per FY; IRN does not overwrite the sequential value.
  • One end-to-end test covers: booking → payment → check-in (Indian) → folio → checkout → invoice email with PDF.
  • One end-to-end test covers: booking → payment → check-in (international, with FRRO) → folio → checkout → invoice email.

§4 — Wave 2 — Operational Completeness (Week 3–4)​

Goal: the front desk and operations dashboards become trustable. Tape Chart works as advertised. Night audit is safe under crash + concurrency. Reports show real numbers.

W2 — Track C: Tape Chart hero feature​

IDBlockerFilesEffortAcceptance criteria
W2.C.1Wire BarContextMenu + CellContextMenu into v2 shellhmp-web-dashboard/src/components/modules/front-desk/tape-chart-v2/tape-chart-v2-shell.tsx:339-3721dRight-click bar → menu opens; click action → mutation fires
W2.C.2Replace 'coming in Phase 2' placeholder toasts with real handler dispatchtape-chart-v2-shell.tsx:365-3720.5dCheck-in / check-out / cancel from DetailPanel actually work
W2.C.3Replace v2 chart-grid.tsx body with v1 virtualized renderertape-chart-v2/chart-grid.tsx:143-265; reuse tape-chart/virtual/virtual-row-renderer.tsx1d100×30 grid renders in ≤ 1s on mid-tier laptop
W2.C.4Reservation version: Int @default(0) for optimistic concurrency + If-Match headerhmp-reservation-service/prisma/schema.prisma; drag handlers2dTest: simultaneous drag → second write rejected with 412
W2.C.5Restore BulkActionToolbar in v2; add OOO range-block actiontape-chart-v2/ + reuse tape-chart/bulk/1.5dMulti-select + stop-sell across rooms × dates works
W2.C.620-spec Playwright suite for tape chart — drag-move, drag-extend, walk-in click, context-menu cancel, conflict reject, overlap rejection, virtualization perf assertionhmp-web-dashboard/e2e/tape-chart-*.spec.ts2dSuite runs green in CI

Track C wave-2 effort: ≈ 8 engineer-days.

W2 — Track D: Night audit + reports​

IDBlockerFilesEffortAcceptance criteria
W2.D.1@@unique([propertyId, auditDate]) on frontdesk NightAuditLog; remove "proceeding without lock" pathhmp-frontdesk-service/prisma/schema.prisma:346-367; night-audit.service.ts:1470.75dConcurrency test: 2 parallel runs → 1 succeeds, 1 errors with unique violation
W2.D.2Dedup window timezone math — property-local midnight to property-local-tomorrow windowhmp-frontdesk-service/src/night-audit/night-audit.service.ts:453-455, 2250.5dTest for IST property at 23:00 IST: dedup excludes UTC-day-boundary charges correctly
W2.D.3Read today's nightly rate from RatePlanRate instead of rateAmount/nights averagehmp-frontdesk-service/src/night-audit/night-audit.service.ts:392-4101dMid-stay rate change reflected in next night's posting
W2.D.4Cancellation-policy-aware no-show feehmp-frontdesk-service/src/night-audit/night-audit.service.ts:559-6551dTest matrix: prepaid plan / refundable plan / pay-at-hotel — each gets right fee
W2.D.5Outbox pattern for reservation.no_show + night.audit.completedhmp-frontdesk-service/src/night-audit/night-audit.service.ts:691-703, 295-3042dBroker outage test: events still delivered after recovery
W2.D.6POS day-close cascade — POST /pos/outlets/:id/close-business-day; gate night-audit start on all outlets closedhmp-pos-service/src/outlets/; hmp-frontdesk-service/src/night-audit/night-audit.service.ts2dTest: open outlet at 02:00 IST → audit refuses to start with clear message
W2.D.7PDF + JSON snapshot to S3 with 5-year retentionhmp-frontdesk-service/src/night-audit/night-audit-pdf.service.ts + S3 lifecycle policy1dTest: completed audit → S3 object with retention metadata
W2.D.8validatePreAudit failure mode tightening — cross-service unavailability surfaces RED, not zerohmp-frontdesk-service/src/night-audit/night-audit.service.ts:1028-1083, 1207-12170.5dProperty-service offline → pre-audit shows ERROR not "all clear"

Track D wave-2 effort: ≈ 8.75 engineer-days.

W2 — Track A: Money flow continued​

IDBlockerFilesEffortAcceptance criteria
W2.A.1POS v2 GST split read at receiverhmp-frontdesk-service/src/folios/consumers/pos-folio-charge.consumer.ts:108-155, 373-383; folios.service.ts:507-5161dTest: POS event with explicit CGST/SGST split → folio line carries the split, not re-derived
W2.A.2MenuItem.hsnCode + gstRate + admin UI + seed migration + propagation into v2 eventhmp-pos-service/prisma/schema.prisma:111-139; admin menu page; v2 event payload3dNew menu item carries HSN; e-invoice line gets HSN
W2.A.3Refund modal in dashboardhmp-web-dashboard/src/app/(dashboard)/front-desk/folio/[id]/page.tsx; payment-service refund endpoint already exists1.5dFrontdesk manager triggers partial refund from UI
W2.A.4PineLabs batch-settlement reconciliation OR explicit "card-present launch out of scope" decisionhmp-payment-service/src/adapters/pinelabs/pinelabs-terminal.adapter.ts:246-252; new reconciliation service4d (if implemented)Daily T+1 reconciliation report; mismatches flagged

Track A wave-2 effort: ≈ 9.5 engineer-days (or 5.5 if W2.A.4 is descoped).

W2 — Track D: Reports correctness​

IDBlockerFilesEffortAcceptance criteria
W2.D.9KPI tile reportIds — fix every wrong ID in tile componentshmp-web-dashboard/src/components/modules/operations-hub/tiles/kpi/{revpar,adr,occupancy,arrivals-today,departures-today,inhouse-count,no-shows-today}.tile.tsx0.5dVitest contract test: every tile-registry id ∈ definitions-registry
W2.D.10Reports timezone (UTC → property TZ)hmp-analytics-service/src/reporting/reports/shared/period-helpers.ts:9-40; reservation.consumer.ts:103,221,249,286; night-audit.consumer.ts:121; dashboard.service.ts:255,12432dTest: report run at 23:00 IST returns IST-day data
W2.D.11roomsSold increments per room-night, not per bookinghmp-analytics-service/src/consumers/reservation.consumer.ts:175,2000.5dADR for 3-night reservation = total / 3, not total / 1
W2.D.12MvDailyOccupancy.totalRooms seeding at 00:00 IST not lazy on first eventhmp-analytics-service/src/backfill/; new daily cron1dRevPAR shows real value at 00:01 IST every day
W2.D.13Top-room-types report — add MvRoomTypeRevenue MV + folio consumer write pathhmp-analytics-service/prisma/schema.prisma; room-type-revenue.definition.ts:372dReport runs in ≤ 200ms, not O(events)

Track D wave-2 effort: ≈ 6 engineer-days.

Wave 2 total: ≈ 32.25 engineer-days (or 28.25 if PineLabs deferred). 50 engineer-days available across 5 × 10 days. Comfortable.

W2 exit gate:

  • Tape Chart Playwright suite ≥ 20 specs all green; performance p95 ≤ 1s for 100×30.
  • Night audit cannot double-post for same (propertyId, businessDate) even with Redis down.
  • No-show fees match cancellation-policy contract terms.
  • POS open shift blocks night audit start.
  • All Operations Hub home tiles render numbers (not error/empty cards).
  • One report run between 18:30 IST and midnight returns IST-day data, not UTC-day data.
  • Refund flow demoable from dashboard.

§5 — Wave 3 — Hardening & P1 Sweep (Week 5–6)​

Goal: clean up the architecture debt that the audit surfaced as cross-cutting risks. The platform should stay shippable, not just become shippable.

W3 — Track E: Platform hygiene​

IDItemFilesEffortAcceptance criteria
W3.E.1xPrisma migration plan — choose for each foreign-model read site: (a) keep as read-model + harden sync consumer with replay test, (b) replace with @hmp/service-clients call. Decide per service. Document.79 sites in channel-service + reservation-service (per audit cross-cutting §4.2)5d (plan + 10 highest-risk migrations); rest in W4Decision matrix committed; 10 highest-risk sites migrated; replay-drift test added per remaining read-model
W3.E.2Webhook idempotency race in channel-service — @@unique partial index OR Redis SETNXhmp-channel-service/prisma/schema.prisma:317-355; resavenue-webhook.controller.ts:480-488, 758-7651dConcurrent retry test: 1 event accepted, retry returns same deduped: true
W3.E.3itemsProcessed count fixhmp-channel-service/src/intermediary/providers/resavenue/resavenue-xml.parser.ts:27,310.5d360-rate push reads as itemsProcessed=360
W3.E.4Stay-only restrictions surfaced as errorshmp-channel-service/src/intermediary/providers/resavenue/resavenue.adapter.ts:84-890.5dStay-only push returns 200 with errors[] non-empty OR auto-routes via pushRates
W3.E.5DB-level idempotency on outbound retries in channel-servicehmp-channel-service/src/sync/sync.service.ts:130-1561dRetry with same payload doesn't duplicate provider-side
W3.E.6Audit-log writes for tenant lifecyclehmp-auth-service/src/tenants/tenants.service.ts:29, 225, 248; onboarding.service.ts:65-1641dAll signup/suspend/reactivate/start/activate produce hash-chained audit rows
W3.E.7Email verification flowhmp-auth-service/src/tenants/; User.emailVerified column; verify landing page in admin portal2.5dNew tenant cannot log in until verified
W3.E.8TenantStatus state machine replaces isActive booleanhmp-auth-service/prisma/schema.prisma:19-58 and consumers2dPENDING / ACTIVE / SUSPENDED / CANCELLED transitions enforced
W3.E.9MFA enrollment forced for ADMIN at createhmp-auth-service/src/tenants/tenants.service.ts:72-84; onboarding.service.ts:128-1401dNew admin's first login requires /auth/mfa/setup completion
W3.E.10Tenant suspension session invalidationhmp-auth-service/src/tenants/tenants.service.ts:236-2430.5dSuspended tenant's user is logged out within 60 seconds

Track E wave-3 effort: ≈ 15 engineer-days (significant — likely 2 engineers).

W3 — Track A/B/C residual P1s​

IDItemFilesEffort
W3.A.1OnboardingService migrates to SubscriptionsModule (typed TenantSubscription row)hmp-auth-service/src/onboarding/onboarding.service.ts:401; subscriptions/subscription.service.ts2d
W3.A.2seedPropertyDefaults real implementation — non-stubhmp-shared-packages/.../property-service.client.ts:530-550; new endpoint in hmp-property-service/src/onboarding/2d
W3.B.1Aadhaar Verhoeff checksumhmp-guest-service/src/guests/guests.service.ts:1040.5d
W3.B.2DPDPA 90-day retention timer for GuestIdVerification rowshmp-frontdesk-service/src/checkin/; cron job1d
W3.B.3S3 SSE explicit on uploadshmp-shared-packages/packages/infra/src/lib/storage/storage.service.ts:60-1090.5d
W3.C.1Reservation list search box wires query → backendhmp-web-dashboard/src/lib/api/reservations.ts:124; reservations.service.ts:2210-23020.5d
W3.C.2Modify and Reg card buttons wiredhmp-web-dashboard/src/app/(dashboard)/reservations/.../keynova.tsx:1388-13931d
W3.C.3Folio tab on detail page reads real folios from frontdesk-servicekeynova.tsx:947-9921d
W3.C.4Guest profile reads via GuestServiceClient not local Prismahmp-reservation-service/src/reservations/reservations.service.ts:1438, 2286, 1339, 1399, 16651.5d
W3.C.5Cmd+K global search — implement aggregator OR delete the affordancehmp-web-dashboard/src/lib/hooks/use-global-search.ts:85; new gateway endpoint OR removal2d
W3.C.6Mobile housekeeping <PhotoUpload taskId={task.id}> widgethmp-mobile-apps/apps/housekeeping/app/task/[id].tsx; components/PhotoUpload.tsx:161d
W3.C.7Two /room-move controllers — delete duplicate; route gateway to canonicalhmp-frontdesk-service/src/checkin/checkin.controller.ts:97; room-ops.controller.ts:130.5d
W3.C.8Folio realignment on room move (date-segmented rate schedule)hmp-frontdesk-service/src/room-ops/room-ops.service.ts:118-122; folio CHARGE adjustment posting2d
W3.C.9Explicit POST /reservations/:id/extend with availability + rate + policy + OTA pushhmp-reservation-service/src/reservations/reservations.service.ts:1606-16472d
W3.C.10ENABLE_POS_FOLIO_CHARGE_CONSUMER default ON (or in-tx writes)hmp-frontdesk-service/src/folios/consumers/pos-folio-charge.consumer.ts:700.25d
W3.D.1Reports v2 saved-views frontend completenesshmp-web-dashboard/src/app/(dashboard)/reports/v2/saved/2d
W3.D.2/actions endpoint OR remove ActionsQueueSectionhmp-analytics-service/src/; hmp-web-dashboard/src/components/modules/operations-hub/actions-queue-section.tsx1.5d

Track residual wave-3 effort: ≈ 21.25 engineer-days.

Wave 3 total: ≈ 36 engineer-days. Tight on 50-day budget; expect to defer 1–2 items into W4.

W3 exit gate:

  • Build script fails CI on TS error.
  • xPrisma migration plan published; 10 highest-risk read sites migrated; replay-drift tests added.
  • Tenant lifecycle has audit trail + state machine + email verification + MFA enforcement.
  • Mobile HK photo flow works end-to-end.
  • Reservation list search and detail page render real data with no client-side fabrication.
  • Refund flow demoable; subscription row landing in typed table.

§6 — Wave 4 — Launch Gate & Soak (Week 7–8)​

Goal: prove the system runs cleanly for a week of synthetic-traffic soak. Capture compliance evidence. Sign off launch.

W4.1 — Test matrices​

IDItemEffortDone when
W4.1.1E2E suite: 50-spec property-#1 happy + adversarial path coverage5dAll green in CI for 3 consecutive nights
W4.1.2Hero feature (Tape Chart) E2E ≥ 20 specs(covered in W2)Already done in W2
W4.1.3Concurrency: 100 parallel bookings for 1 last-room property1dExactly 1 succeeds; 99 get 409
W4.1.4Night audit chaos: kill the process at 5 different points; verify resume / rollback1.5dNo double-post; clean rollback
W4.1.5OTA storm: replay 24h of ResAvenue webhook traffic at 10× speed1dAll inbound dedup'd; folio totals match expected

W4.2 — Compliance evidence packet​

IDItemEffortDone when
W4.2.1Real NIC IRP sandbox: 50 invoices end-to-end (B2B + B2C, intra + inter-state, GST 12% + 18%)2dAll 50 have valid IRN + ACK; cancellation path verified
W4.2.2FRRO Form C generation evidence: 20 sample foreign-guest check-ins; PDFs verified by FRRO submission template1d20 PDFs in hmp-docs/Integrations/FRRO/cert-evidence-2026-XX-XX.md
W4.2.3GSTR-1 reconciliation: invoice numbers gap-free for the soak week1dSQL query confirms
W4.2.4DPDPA evidence: ID document encrypted at rest; access audited; retention timer firing0.5dS3 object inspection + audit log review
W4.2.5Police register: state guest-register CSV generated for the soak week0.5dCSV with real (decrypted, audited) PII
W4.2.6PCI evidence: log-redaction proven across all paths; SAQ-A scope confirmed1dSanitizer test + log review
W4.2.7CERT-In incident-reporting wiring smoke test0.5dDummy incident → 6h SLA timer fires

W4.3 — Operational readiness​

IDItemEffortDone when
W4.3.1Runbook for night-audit failure recovery1dOperator can rollback + resume
W4.3.2Runbook for OTA outage0.5dStop-sell procedure + DLQ replay
W4.3.3Runbook for payment provider outage0.5dPay-at-hotel fallback procedure
W4.3.4Performance baseline: dashboard p95, tape chart render p95, search p951dNumbers captured; SLO defined
W4.3.5Security review (external + internal pen test on staging)3dFindings triaged; high-severity closed
W4.3.6Monitoring alerts: 16+ alert rules per CLAUDE.md verified firing in chaos drills1dAll alerts proven; PagerDuty routing verified

Wave 4 total: ≈ 20 engineer-days. Mostly testing + signoff, lighter than build waves.

W4 exit gate (launch readiness):

  • All E2E suites green for 3 consecutive nights.
  • One full week of QA soak complete with no P0/P1 regressions.
  • Compliance evidence packet committed to hmp-docs/Integrations/.
  • All runbooks reviewed by ops.
  • Pen test report signed off.
  • Property #1 GM has done a 4-hour scripted walkthrough on QA without finding a blocker.
  • Go/no-go meeting recorded.

§7 — Effort summary​

WaveEffort (eng-days)Available (5 eng × 10 working days)Slack
W0~5d5d (3 calendar days × 2 of the team)tight
W1~23.5d50dcomfortable
W2~32.25d (or 28.25 with PineLabs deferred)50dcomfortable
W3~36d50dtight (defer 1-2 items expected)
W4~20d50dlots of slack for fix-on-find
Total~117d (105d if PineLabs descoped)200d availableenough headroom

Audit identified ~73 P0 + ~80 P1. Roadmap addresses all P0 in W0–W2 and all P1 in W3. Anything not in this roadmap is post-launch P2.


§8 — Dependencies​

W0 ──► W1 ──► W2 ──► W3 ──► W4
│ │
│ ├── Track A: Money flow ─── continues into W3 with refund modal
│ ├── Track B: Compliance ─── continues into W4 with NIC IRP cert
│ └── Track D: Reports ────── continues into W3 with saved-views
│
└── Track E: Platform hygiene ───── biggest in W3 (xPrisma)

Hard dependencies:

  • W1.A.1 (booking lock) blocks W4.1.3 (concurrency test).
  • W1.A.5+A.6 (invoice numbering) blocks W4.2.3 (GSTR-1 reconciliation).
  • W2.A.2 (HSN codes) blocks W4.2.1 (NIC IRP sandbox).
  • W2.D.1 (night-audit unique constraint) blocks W4.1.4 (chaos test).
  • W2.C.1+C.2+C.3 (tape chart wiring) blocks W2.C.6 (E2E suite).
  • W3.E.6 (audit log) blocks W4.2.4 (DPDPA evidence).

Soft dependencies: W3.E.1 (xPrisma) is large; if it slips into W4, the soak still passes — just leaves architecture debt for post-launch.


§9 — Risks & escape hatches​

RiskLikelihoodImpactMitigation
Real NIC IRP sandbox enrolment delayedMediumHighStart enrolment on day 1 of W0; if sandbox is unreachable by start of W4, ship with EINVOICE_MOCK=true flagged at GM-aware "draft" watermark on every invoice — formal launch gated on real IRN going forward.
Tape Chart v1→v2 plumbing breaks more than it fixesMediumMediumKeep v1 shell as fallback flag; ship v2 behind FLAG_TAPE_CHART_V2; flip per property only after operator validation.
xPrisma migration drags onHighMediumCap at 10 sites in W3; defer the rest with replay-drift tests as the bridge.
Booking concurrency test reveals deeper schema redesignLowHighWorst case escalates W1.A.1 from 3d → 8d; absorb via W3 slack.
ResAvenue partner response on cert v2 evidence delayedMediumMediumOps-only switch; not on the launch critical path; can launch direct-only.
PineLabs reconciliation requires new cron job we don't have time forHighMediumDescope card-present launch; manual EOD reconciliation as documented operator procedure.
Pen test finds new P0 in W4MediumHighReserve 5d of W4 slack; have a 1-week rollover plan if findings are deep.

§10 — Decisions needed (before W0 ends)​

#DecisionDefaultStakeholder
D1Property #1 launches with card-present POS terminal?YES → adds 4d to W2Property GM + finance
D2Property #1 launches with real NIC IRP integration?YES → adds 2d to W4Compliance/finance lead
D3Property #1 launches with Cmd+K global search?NO (delete affordance, save 2d)Product
D4xPrisma migration scope in W3: 10 sites or all 79?10 sites + drift testsEngineering lead
D5hmp-booking-engine GoaT Phase 8 features ship with launch?NO — launch from master after merging only the urgent fixesProduct + engineering
D6Mobile housekeeping app ships with launch?YES — needed for HK photo proof flowProperty GM
D7Express check-in route enabled at launch?NO — keep disabled until W3 implementation landsProperty GM
D8Any P1 deferred to post-launch besides what this roadmap already lists?Capture during W0.4PM + leads

§11 — Single-page status checklist (for daily standups)​

W0 ─ Decision & Containment ─────────────────  [   ]
├─ Boot guards (3) [ ]
├─ Route disablements (3) [ ]
├─ Doc drift fixes (4) [ ]
└─ Plan signoff [ ]

W1 ─ Money & Compliance Hard Blockers ──────── [ ]
├─ Track A: 10 items (~12d) [ ]
├─ Track B: 10 items (~10d) [ ]
└─ Track E: 2 items (~1.5d) [ ]

W2 ─ Operational Completeness ──────────────── [ ]
├─ Tape Chart hero (~8d) [ ]
├─ Night audit (~9d) [ ]
├─ Money flow continued (~9.5d) [ ]
└─ Reports correctness (~6d) [ ]

W3 ─ Hardening & P1 Sweep ──────────────────── [ ]
├─ Platform hygiene (~15d) [ ]
└─ Residual P1 across tracks (~21d) [ ]

W4 ─ Launch Gate & Soak ────────────────────── [ ]
├─ Test matrices (~9d) [ ]
├─ Compliance evidence (~7d) [ ]
└─ Operational readiness (~7d) [ ]

Document owner: PM + tech leads. Update at end of every wave. Close out at GM go-live signoff.

Files for cross-reference:

  • Audit source: hmp-docs/docs/platform-registry/property-1-launch-review-2026-05-06.md
  • Gold-standard charter: hmp-docs/docs/platform-registry/property-1-gold-standard-fix-plan-2026-04-28.md
  • Visual roadmap: hmp-docs/docs/platform-registry/property-1-launch-roadmap-2026-05-06.html