Property #1 Launch Readiness Review — Reviewer Prompt
Paste everything below into a fresh Claude Code session whose working directory is
C:\CLProjects\HMP. The reviewer must be allowed to read every repo and to spawn sub-agents. No code changes. Output is a single audit report.
0. Mission
You are conducting a launch-blocker review for KeyNova / HMP (Hotel Management Platform) ahead of going live with Property #1. The business owners have given us a list of 13 minimum business flows that must work. Your job is to determine, from the actual code, database schema, running services, and frontend UI, what truly works end-to-end vs. what is stubbed, half-wired, or missing.
Deliverable: one report file that a release-manager can read and act on without needing to dig into the repo themselves.
1. Non-negotiable rules
These are absolute. Violating any of them invalidates the report.
-
Do NOT trust documentation. Treat the following as suspect, possibly stale, possibly aspirational:
- Every
CLAUDE.md(root, per-repo, per-module). - Every entry in
~/.claude/projects/.../memory/MEMORY.mdand any memory file. - Every file under
hmp-docs/docs/platform-registry/(prior audits, gold-standard plans, golive readiness, session reports). They are dated and partial. - Every spec/plan in
hmp-docs/docs/superpowers/specs/and…/plans/that claims "SHIPPED" or "✅". - Any commit message that says "complete", "done", "wired". You may open these to find pointers (file paths, model names, endpoint paths) but you must re-verify each claim against the actual code, schema, or running output before reporting it.
- Every
-
Evidence or it didn't happen. Every finding in your report must cite at least one of:
repo/path/to/file.ts:123(with line number, ideally with quoted snippet).- Prisma schema model + field name from a specific
schema.prisma. - A controller/route mapping (
@Get('foo')inxxx.controller.ts). - A test file path + test name (
xxx.spec.ts > it("…")). - A UI component/page path. No prose claims like "looks implemented" without a citation.
-
Brutal honesty. No encouraging words. The report is not a status update for stakeholders, it's a punch list. Forbidden phrases include but are not limited to: "good progress", "mostly complete", "foundation is solid", "on track", "impressive", "well-structured", "close to launch". Replace with verifiable percentages, counts, and file references.
-
PMS/OTA domain perspective. Review as a senior engineer who has shipped property-management systems and channel manager integrations before. Apply industry-standard expectations (reservation state machine, folio lifecycle, night audit semantics, ARI push, Form C / FRRO, GST e-invoice IRN, ESC/POS, tape chart conflict resolution). When the platform deviates from industry norms, call it out.
-
Code/DB/UI first; tests second; docs never. When two sources disagree, the running code and the actual Prisma schema win.
-
Read-only. Do not modify any source file. You may run read-only commands (
grep,npx prisma format,npm ls,docker compose config,nest --help, running services in dev for behavior checks). Do not run destructive commands, do not push to remotes, do not start migrations, do not run seeds against shared DBs.
2. Reviewer persona
Adopt the perspective of:
A staff-level engineer with 10+ years in hospitality SaaS, having shipped at least one PMS, one channel manager integration (Booking.com / Expedia / ResAvenue), one POS, and one night-audit batch. Familiar with Indian compliance: GST (CGST/SGST/IGST), e-invoicing (NIC IRN), Form C / FRRO foreigner registration, CERT-In incident reporting, TRAI DND for SMS, PCI DSS for card data, GSTIN/HSN/SAC.
If a feature works but in a way no real hotel would accept (e.g., check-in without ID capture, folio without taxes split, OTA push without idempotency), it counts as not ready for launch even if the happy path renders.
3. Repo & service map (anchors only — verify against reality)
Working dir: C:\CLProjects\HMP. Multi-repo, all on master, each its own git
repo. Backend services (NestJS), frontends (Next.js / Vite / RN). Confirm each
exists; do not assume.
Backend services and ports (verify in each repo's src/main.ts and
docker-compose.dev-all.yml):
| Repo | Default port | Owns |
|---|---|---|
hmp-api-gateway | 3010 | Routing, proxy |
hmp-auth-service | 3001 | Auth, tenants, billing, subscriptions |
hmp-property-service | 3002 | Properties, rooms, room types, rate plans, taxes |
hmp-reservation-service | 3003 | Reservations, availability, groups, booking-engine support endpoints |
hmp-guest-service | 3004 | Guests, preferences, loyalty, DSAR |
hmp-frontdesk-service | 3005 | Check-in/out, folios, e-invoice |
hmp-housekeeping-service | 3006 | Room status, tasks, discrepancies |
hmp-pos-service | 3007 | Outlets, menus, orders, KOT, kitchen WS |
hmp-banquet-service | 3008 | Events, venues |
hmp-channel-service | 3009 | OTA / channel manager (ResAvenue etc.) |
hmp-notification-service | 3008* | Email, SMS, push, WA |
hmp-crm-service | 3012 | CRM, communications, RateAgreement, AR/commission |
hmp-analytics-service | 3013 | Reports, dashboards, MV consumers |
hmp-payment-service | 3014 | Payments, merchant accounts, Razorpay webhook |
hmp-spa-service | 3015 | Spa |
hmp-asset-service | 3016 | Assets, work orders, PPM/AMC, spares |
*Port collision between banquet and notification — this is itself a finding to
verify.
Frontends: hmp-web-dashboard (Next.js, staff), hmp-admin-portal (Next.js,
super-admin), hmp-booking-engine (Vite, guest), hmp-mobile-apps (RN), hmp-kds-kiosk (kitchen).
Shared packages: under hmp-shared-packages/packages/ — @hmp/api-contracts,
@hmp/service-clients, @hmp/database, @hmp/auth, @hmp/payments,
@hmp/messaging, @hmp/template-engine, @hmp/notification-contracts,
@hmp/rule-engine, etc.
Verify that each repo actually contains what's claimed. List discrepancies.
4. The 13 launch flows (review targets)
Reproduced verbatim from the business team — these are the launch gates:
- Tenant onboarding
- Property onboarding: name + address + Google Map directions; property pictures; room types (with pictures, amenities); number of rooms; rate plans; tax info; cancellation policy.
- Booking engine integration: customer books a room, reservation appears.
- Staff verifies reservation details are correct.
- Front desk / housekeeping upcoming-guest updates: room move, extend stay, all housekeeping functions.
- Front-desk check-in with all mandatory details: Indian guest; international guest.
- Guest orders room service (in-room dining): charges post to folio correctly.
- Guest check-out: invoice generated correctly.
- Night audit runs correctly.
- Reports / dashboards show correct data.
- ResAvenue integration: push rates, push inventory, stop-sale, all channel-manager / OTA primitives.
- POS terminal & payment gateway integration.
- Tape Chart Calendar (hero feature): most front-desk and reservation operations performable from this view, intuitively.
5. Per-flow review methodology (apply this template to every single flow)
For each flow, run the following verification track. Each step must produce a fact or a gap, never an impression.
5.1 Define the flow concretely
Write 3–7 numbered user-visible steps. State the user role at each step (guest, front-desk agent, GM, system). State which service(s) own each step. If steps are ambiguous, state your assumption explicitly.
5.2 Data layer (Prisma + DB)
For each domain object the flow touches:
- Locate the
schema.prismaof the owning service (<repo>/prisma/schema.prisma). - List every required field. Verify each exists with the right type, nullability, and indexes. Cite the line.
- Verify
tenantIdandpropertyIdare present with@db.Uuidand indexed. - Verify state-machine columns (e.g.,
Reservation.status,Folio.status,WorkOrder.status) exist as enums and that the enum values match the flow's required transitions. - Verify cross-service soft FKs (no
@relationacross services) — call out any illegal cross-service@relationblock. - For any field added by a recent migration, open the migration SQL in
prisma/migrations/*/migration.sqland confirm it ran (or note that it has not). - Red flag: any field stored as
Jsonthat should be a typed column (e.g., guest ID document fields, GST breakdown, cancellation policy rules). Call out by field path.
5.3 Backend endpoint inventory
For each step that requires a backend call:
- Find the controller + route (search controllers across services). Cite
repo/src/.../*.controller.ts:line. - Verify
@Roles(...)and@UseGuards(JwtAuthGuard, RolesGuard)(or@Public,@ApiKey) are correct for the flow's actor. - Verify tenant scoping: query path includes
where: { tenantId, ... }or invokesassertPropertyTenant. Cite the service-level enforcement. - Two-file rule for gateway: confirm BOTH
hmp-api-gateway/src/config/services.config.tshas the prefix ANDproxy.controller.tshas matching@All('<prefix>')+@All('<prefix>/*'). Missing either = 404. - Verify request DTO and response DTO. If DTO accepts
any,unknown, or has no class-validator decorators on user-supplied fields, flag. - Verify idempotency on mutating endpoints (booking confirm, payment capture,
check-in, check-out, night-audit start, OTA inbound). Look for
Idempotency-Keyheaders, dedup tables, or unique constraints. Cite the dedup mechanism.
5.4 Cross-service call graph
- For every cross-service read in this flow, verify it uses
@hmp/service-clients(PropertyServiceClient,ReservationServiceClient, etc.). Search for anyxPrismaor direct foreign-Prisma imports — those are the legacy anti-pattern and crash at runtime. - Verify the receiver calls
assertPropertyTenant(propertyId, tenantId). - Verify
INTERNAL_SERVICE_TOKENis the auth, not a per-tenant JWT.
5.5 Event / messaging
- For every event the flow emits or consumes, find the publisher
(
@hmp/messagingor direct stream write) and the consumer subscription. - Confirm the topic name matches across publisher and consumer. (Past incidents
had publisher writing
reservation.createdand consumer subscribingreservation:created.) - Confirm consumer has dedup (Redis SETNX or idempotency table).
- Verify
SKIP_EVENT_SUBSCRIPTIONSis false in target compose files for services that need to consume.
5.6 Frontend screens
For each user-visible step:
- Locate the page/component in the relevant frontend repo. Cite path.
- Walk every form field and every displayed field against the flow's required data. Mark missing fields.
- Verify
extractApiError(err, fallback)is used in mutation error handlers, not rawerr.response?.data?.message. - Verify
HeaderZoneis used for page headers (not the deprecatedPageHeader). - Verify the screen uses real endpoints from
lib/api/*.ts— notmock/TODO/ hard-coded JSON. - Verify loading + empty + error states exist (look for
LoadingState/EmptyState/ErrorStateon booking engine;Skeletonon dashboard). - Verify mobile responsiveness for guest-facing screens; verify dark-zone
(navy) usage of
KpiCardon dashboard. - Verify accessibility hooks: form labels, focus traps on modals, contrast.
5.7 Test coverage
- Inventory tests under each repo's
src/**/*.spec.tsandtests/**/*.test.tsande2e/**. Cite counts. - For this flow: map each user step to a test (unit, integration, flow, or E2E). Mark "no test" steps explicitly. Do not count snapshot tests as flow tests.
- Verify happy-path test exists end-to-end (call the API, assert DB state, assert resulting screen).
- Verify at least one negative test (validation error, RBAC denial, tenant isolation, conflict, idempotency replay).
- For Playwright/Cypress E2E: verify a test file actually walks the flow in a browser. List the file or note its absence.
5.8 Domain-correctness checks (PMS rules)
Per-flow specifics in §7 below. Every flow must have at least one PMS-domain verification (e.g., "no overbooking under concurrent confirms", "tax breakdown matches GST rules", "Form C captured on international check-in").
5.9 Verdict for the flow
Produce one of these labels with a one-line justification:
- GREEN — every required step has data + endpoint + UI + at least one happy + one negative test, idempotency where required, domain-correct.
- AMBER — happy path works in code but ≥1 of: missing negative test, missing idempotency, missing UI field, missing domain rule. Specific to-do list.
- RED — at least one user step is missing one of {data, endpoint, UI}, or domain rule is violated, or known crash.
- UNKNOWN — could not verify in the time budget; specify what blocked verification.
No flow can be GREEN unless every sub-check passed with cited evidence.
6. Output format
Write exactly one markdown file:
hmp-docs/docs/platform-registry/property-1-launch-review-2026-05-06.md
(If today's date differs, use the actual date.)
The file MUST contain these sections, in order:
6.1 Header
- Title.
- Reviewer model + run timestamp (UTC + IST).
- Total review duration.
- Working dir.
- Git HEADs of each repo at review time (
git -C <repo> rev-parse --short HEAD).
6.2 Executive verdict (≤ 1 page)
- One sentence: GO / NO-GO for property #1, with reason.
- Counts: GREEN / AMBER / RED / UNKNOWN across the 13 flows.
- Top 5 launch blockers, each one line with file pointer.
- Top 3 cross-cutting risks (security, data integrity, etc.).
6.3 Flow status table
A table with columns: Flow # | Name | Verdict | Blocker count | Top blocker | Effort to GREEN.
6.4 Per-flow detailed findings (13 sections)
For each flow, in order, with these sub-headings:
- Flow definition (5.1)
- Data layer findings (5.2)
- Backend endpoint findings (5.3)
- Cross-service / messaging findings (5.4–5.5)
- Frontend findings (5.6)
- Test coverage (5.7) — include numeric coverage if extractable
- Domain-correctness findings (5.8)
- Verdict + remediation list (5.9)
Each finding line: [severity] short title — file:line — what's wrong — what's needed.
Severity scale: P0 (blocks launch), P1 (must fix in 14 days post-launch),
P2 (cosmetic / nice-to-have).
6.5 Cross-cutting findings
A separate section for issues that span multiple flows:
- Tenant isolation gaps.
- JWT / RBAC drift.
- Missing gateway routes (two-file rule violations).
- xPrisma / cross-service Prisma anti-patterns still in code.
- Idempotency gaps on critical paths.
- Build/runtime crashes (esbuild externals missing, DI failures, etc.).
- Compose / k8s misconfig (env vars, port collisions,
SKIP_EVENT_SUBSCRIPTIONS). - Compliance: GST/IRN, Form C, FRRO, CERT-In, TRAI DND, PCI.
- Schema drift across services (UUID vs text, enum mismatch, missing fields).
- Dead code / mocked code paths still wired.
6.6 Top 20 P0 blockers, prioritized
A numbered list. For each: title, files, owner service, effort estimate (person-days), suggested fix.
6.7 Effort summary
Sum P0 effort. Sum P1 effort. State whether the team's stated headcount × calendar days can absorb it.
6.8 Appendix: verification log
For each flow, attach the actual commands run and files opened (paths only, no full content). This is the audit trail for anyone who wants to re-run.
7. Per-flow checklists (apply 5.1–5.9, plus these specifics)
Flow 1 — Tenant onboarding
Owning service: hmp-auth-service, with hand-off to property-service,
notification-service, payment-service.
Specifics to verify:
- Self-serve sign-up route + admin-driven create route both exist and are gated correctly (admin route requires SUPER_ADMIN).
Tenantmodel fields:legalName,tradeName,gstin,pan,billingContactName/Email/Phone,dataResidency,subscriptionPlan,status. Verify GSTIN regex validation. Verify nullable vs required matches Indian regs.- Email verification + password reset flow — actual mail send, not stubbed.
- Initial admin user creation: role assignment, MFA enrollment offered/required for ADMIN.
- Tenant status state machine: PENDING → ACTIVE → SUSPENDED → CANCELLED. Verify each transition has an endpoint and is auditable.
- Subscription wiring:
TenantSubscriptionrow created on activation. Verify Razorpay/payment-service plumbing perSUBSCRIPTION_VIA_PAYMENT_SERVICE_ENABLEDflag — confirm the flag's both code paths (legacy adapter + payment-service) actually work or honestly note one is fictional. - Data residency / DPDPA: the tenant's data must be stored in the right region; verify schema column + any RLS / per-tenant DB partitioning claims.
- Audit log:
audit-servicewrites onboarding events. Confirm via grep foraudit.writecalls in the tenant-create handler.
UI: admin-portal "create tenant" page + dashboard "my organization" page. Verify all fields editable post-create.
Flow 2 — Property onboarding
Owning: hmp-property-service. UI: dashboard + admin-portal.
Sub-flows: each must work standalone:
2.i Name + address + Google Map directions
Propertyschema:name,legalName,addressLine1/2,city,state,country,pinCode,latitude,longitude,googleMapsUrl,timezone,currency,localeDefault. Verify lat/lon areDecimalnot float-as-string. Verify pinCode validation (Indian 6-digit).- Endpoint to create + update.
- UI: address autocomplete (Google Places API key wired? confirm via env or
lib/maps.ts). Verify coordinates persist. Verify embedded map shows on the property summary page.
2.ii Property pictures
PropertyImagemodel with S3/CDN URL, alt text, display order, hero flag. Verify fields.- Upload endpoint: multipart or signed-URL pre-sign. Confirm storage backend (S3 vs local). Verify content-type whitelist + size limit + virus scan or note absence.
- CDN URL persisted (CloudFront/Cloudflare? confirm). Booking engine must serve from CDN, not the API.
- UI: drag-reorder, set hero, delete. Mobile thumbnail rendering.
- Booking engine displays the same images, in same order. Verify by reading the booking-engine property-detail page component.
2.iii Room types
RoomTypemodel:name,code,description,maxOccupancy,defaultOccupancy,extraBedAllowed,bedConfiguration,sizeSqft/SqM,smoking,images[],amenities[]. Verify pictures are stored per-room-type, not just per-property. Verify amenities are typed (icon + label) not free-text JSON.- CRUD endpoints + dashboard UI.
- Booking engine must show RoomType cards with images + amenities. Verify field-by-field.
2.iv Number of rooms
Roommodel:roomNumber,roomTypeId,floor,building,status(CLEAN/DIRTY/INSPECTED/OOO/OOS),housekeepingStatus. Verify@@unique([propertyId, roomNumber]).- Bulk create endpoint. UI: add/remove rooms or bulk import. Verify a property with 100 rooms can be onboarded without 100 manual clicks.
2.v Rate plans
RatePlanmodel:name,code,currency,mealPlan(RO/CP/MAP/AP),cancellationPolicyId,minLOS,maxLOS,advancePurchase,mostRestrictiveTier,derivationStrategy(BASE/PCT_OF/AMOUNT_OFF). Verify rate-plan-to-room-type mapping.RatePlanPricingper date / per occupancy / per BAR/promotional tier. Verify storage shape — flat rows by date or compressed ranges?- UI: rate calendar to set rates per date. Verify bulk-edit (select date range, set rate). Verify currency-aware rendering (₹ prefix for INR, no $).
2.vi Tax info
Tax/TaxRulemodel:name,taxType(CGST/SGST/IGST/VAT/SERVICE_CHARGE),rate,appliesTo(ROOM/POS/SPA/BANQUET),hsnSacCode,inclusivity,slabRules(e.g., GST 12% under ₹7,500 vs 18% above). Verify slab logic actually exists for Indian hotel GST tiering, not just a flat rate field.- Endpoint to define + apply. Verify the folio-line tax-application code reads from these rules and not from hard-coded values.
- E-invoice IRN: GSTIN of property + counter-party, IRN field on Invoice. Verify the NIC IRP integration is real or honestly mocked (look for
EINVOICE_MOCK=trueand confirm a real client exists for the unmocked path).
2.vii Cancellation policy
CancellationPolicymodel with rules (e.g., 100% refund > 7 days, 50% < 48 hrs, no-show forfeits 1 night). Verify rules are typed not free-text.- Linked to RatePlan + reservation snapshot.
- UI: form to define policy, attach to rate plan. Booking engine displays policy on the rate card. Verify the actual displayed text matches the policy data — sometimes the UI renders a hard-coded paragraph.
Flow 3 — Booking engine integration
Owning: hmp-booking-engine + hmp-reservation-service (with @Public /
API-key gated proxy endpoints) + hmp-payment-service.
Specifics:
- Search availability endpoint (
/api/booking-engine/...via gateway). Verify request DTO validates dates, occupancy, propertyId/destination. Verify response includes available room types, rate plans, prices including taxes, cancellation policy, images. - Hold (10-min freeze) → confirm flow: verify
Reservation.statusgoesHOLD→CONFIRMEDonly on payment success (orPAY_AT_HOTEL). Verify hold expires (background job or TTL). Verify expired holds don't block new bookings. - Concurrency: two guests booking the last room must not both succeed. Look for an explicit lock or unique constraint. If none, RED.
- Payment flow uses payment-service via
PaymentServiceClient(perVITE_FEATURE_PAYMENT_SERVICE_ENABLED). Verify the non-flag path also works honestly. - Reservation appears in dashboard within ≤ 5 seconds of confirm. Verify the read path: does the dashboard hit reservation-service directly or via analytics-service MV? If MV, confirm the consumer is wired (§5.5).
- Reservation summary in dashboard contains: guest name, check-in/out, room type, rate plan, mealPlan, total, taxes, payment status, balance, source (=BOOKING_ENGINE), special requests.
- Confirmation email sent? Notification-service consumer exists? Verify
reservation.createdevent is consumed and a templated email goes out. Confirm via the template in@hmp/template-engineregistry.
Flow 4 — Staff verifies reservation details
Owning: hmp-web-dashboard reservations module.
Specifics:
- Reservations list page: filter by date range, status, source, guest name. Verify pagination + sort. Verify the columns include all fields a front-desk agent needs (CTA, ETA, special requests, balance).
- Reservation detail page: every field from §3 above must be visible and editable where appropriate. Verify the audit log of changes.
- Verify guest profile section pulls from guest-service via
GuestServiceClient, not fromReservation.guestSnapshot. - Verify bill/folio tab shows folio rows for that reservation (frontdesk-service).
- Verify reservation modify endpoint returns the updated record and invalidates caches.
Flow 5 — Front desk / housekeeping upcoming-guest updates
Three sub-flows:
5.i Room move (during stay)
- Endpoint to move a checked-in guest to a new room. Verify it: (a) blocks the new room, (b) frees the old room for housekeeping, (c) appends a
RoomMoverow to history, (d) updates the folio's room-charge line going forward not retroactively (industry rule: charge old rate up to move date, new rate after), (e) emits an event to housekeeping. - UI: a button on the reservation detail page or tape chart. Verify both work.
5.ii Extend stay
- Endpoint to extend departure date. Verify: (a) availability check on the additional nights, (b) rate calculation for added nights (use current rate plan or a manual override), (c) folio additional-nights posting, (d) cancellation-policy timer reset or carried, (e) housekeeping schedule updated, (f) channel manager push updates the OTA inventory for those nights.
5.iii Housekeeping functionality
- Room-status board: by floor/building. Verify real-time WebSocket updates (
HousekeepingGatewaynamespace). Verify JWT auth on socket. Open a room status, change in DB, confirm UI updates without refresh. - Tasks: assign cleaning task to attendant, start, complete, supervisor inspect. Verify task lifecycle states match industry norms (READY/IN_PROGRESS/COMPLETED/INSPECTED/REJECTED).
- Discrepancies: front-desk system says "occupied", housekeeping says "vacant" — discrepancy report + resolution flow. Verify it exists.
- Mobile view: housekeeper opens the mobile app, sees their tasks, marks complete with photo proof. Verify in
hmp-mobile-appsactually wires to these endpoints.
Flow 6 — Front-desk check-in
Two sub-flows:
6.i Indian guest
- Mandatory fields: full name, DOB, gender, mobile (E.164), email (optional but recommended), permanent address, ID type (Aadhaar / driving license / voter ID / passport), ID number (validated format), ID image upload, purpose of visit, expected departure, signature capture (digital or physical).
- Verify the schema has these fields. Verify Aadhaar number is NOT stored in plaintext — must be hashed or last-4-only per UIDAI/DPDPA. If full Aadhaar is stored, RED.
- ID image uploaded to encrypted storage (server-side encryption at rest).
- "Form C" exemption applies (Form C is for foreigners). However, Indian hotel guest registers (state-level, e.g., Maharashtra Hotel Act) — verify a guest register table is maintained.
- Folio opened with billing instructions + corporate billing if applicable.
- Key allocation:
RoomLockintegration if hardware is wired, or mock receipt ifHARDWARE_MOCK=true.
6.ii International guest
- All Indian fields plus: nationality, passport number, passport expiry, visa type, visa number, visa expiry, port of entry, date of arrival in India, date of departure from India, next destination.
- Form C generation: this is mandatory for foreigners. Within 24 hours of check-in, hotel must submit Form C to the FRRO (online portal:
indianfrro.gov.in). Verify either: (a) an integration submits automatically, or (b) a clear download/print of Form C is generated. If neither, RED — this is a regulatory requirement. - C-Form ledger (audit trail) maintained.
- Currency declaration if relevant.
Flow 7 — Guest orders room service (in-room dining)
Owning: hmp-pos-service + hmp-frontdesk-service (folio).
Specifics:
- POS outlet "In-Room Dining" exists with a menu (
Outlet,MenuCategory,MenuItem, modifiers, taxes per item with HSN/SAC). - Order creation: guest's room number → resolves to active reservation → opens / appends to in-room-dining tab.
- KOT (kitchen order ticket) routes to the right station via
KitchenGatewayWS namespace. Verify in KDS app. - Order completion → folio posting via the
PosFolioConsumer(or equivalent). Verify the event exists, is consumed, and the resultingFolioLinehas correct: outletId, orderId reference (idempotency key), items detail, HSN/SAC, CGST/SGST split, total. If the consumer dedup key is missing, replays will double-post. - Tip handling: separate folio line, no GST.
- Service charge handling: separate line, taxable. Verify rules.
- UI: dashboard reservation/folio tab shows the dining charge with drill-down to the order.
Flow 8 — Guest check-out
Owning: hmp-frontdesk-service.
Specifics:
- Pre-checkout: outstanding balance computation. Verify late checkout charge auto-applied if past checkout time.
- Settlement: cash, card, UPI, wallet, BTC (bill-to-company), split payments. Verify each path posts a
Paymentrow, updates folio balance, and on full settlement closes the folio. - Invoice generation: GST-compliant tax invoice with: invoice number (sequential, no gaps, per-property prefix), invoice date, GSTIN of property, GSTIN of guest if provided (B2B), HSN/SAC per line, taxable value, CGST + SGST or IGST, total tax, total amount, amount in words, place of supply, signatory.
- E-invoice IRN: for B2B invoices > ₹5 crore aggregate turnover, IRN must be generated. Verify the NIC IRP integration. If
EINVOICE_MOCK=trueis the only path, RED for production. - PDF + ESC/POS receipt. Verify
generateFolioReceiptin@hmp/common/printing/receipt-templates.tsis invoked. Open the test file and confirm 47 byte-level tests pass. - Email + SMS / WhatsApp delivery to guest. Verify notification-service consumes
folio.closedand dispatches a templated invoice email. - Room status flips to DIRTY for housekeeping. Verify HK consumer wires.
- Guest stay history updated; loyalty points accrued if member.
Flow 9 — Night audit
Owning: hmp-frontdesk-service (typically) — verify ownership.
Industry definition: at end-of-day cutoff, the system: (a) posts room + tax for all in-house guests, (b) advances business date, (c) processes no-shows (charges 1 night, releases room or marks NO_SHOW), (d) reconciles all payments / receivables, (e) generates daily reports (daily revenue, manager flash, occupancy), (f) closes outlets.
Verify:
- A scheduled job or manual trigger exists. Cite the
@Crondecorator or trigger endpoint. - Idempotent: running twice for the same business date must not double-post charges. Verify dedup mechanism (e.g.,
BusinessDateRollrow with unique constraint on(propertyId, businessDate)). - Per-property timezone handling: business date rolls at the property's
nightAuditCutoff(e.g., 03:00 IST) not server UTC midnight. - All in-house reservations get their nightly room+tax posted. Check via integration test or by manual schema walk.
- No-show handling: reservations with
expectedArrival < businessDateand not checked in get NO_SHOW status + cancellation fee posted. - Generates an audit report PDF / CSV. Where is it stored, who can view, retention policy.
- Failure recovery: if the job crashes mid-way, it must resume or rollback. Verify via the job's transaction boundaries.
- Pre-night-audit checklist (open folios, unposted charges, missing signatures) — does the system surface these?
- POS day-close cascade: outlets must close before night audit; verify the dependency.
Flow 10 — Reports & dashboards
Owning: hmp-analytics-service (MVs + endpoints) + dashboard pages.
Specifics:
- Inventory reports/dashboards needed for property #1: occupancy %, ADR, RevPAR, arrivals today, departures today, in-house, daily revenue (room + F&B + spa + other), top room types, channel mix, source mix, year-over-year vs prior period.
- For each: locate the materialised view (
MvOccupancyDaily, etc.), the consumer that maintains it (EventDispatcherService), and the dashboard page that reads it. - Verify the numbers match a manual computation. Pick one report and trace it: open a sample reservation set, compute the metric by hand, run the API, compare. Document the calculation.
- Verify date filters (today / yesterday / month-to-date / custom) all work. Verify timezone (IST).
- Verify multi-property aggregation works for chains and single-property filter works.
- Verify CSV export, PDF export. Verify the saved-views feature actually persists per user.
- Verify the legacy
/reportspage is no longer wired to the analytics-service old code path (per recent migration); confirm by reading the dashboard'sapp/reportsdirectory. - Anomaly / exceptions page:
/anomalies. Verify it loads from a real endpoint and not stubbed JSON.
Flow 11 — ResAvenue (channel manager) integration
Owning: hmp-channel-service.
Industry primitives the channel manager must support:
- Push to OTAs: rates (per ratePlan / room type / date), inventory (per room type / date), restrictions (CTA, CTD, MinLOS, MaxLOS), stop-sale flag.
- Pull from OTAs: bookings (new / modified / cancelled), with idempotency keys.
- Webhook receiver with signature verification.
- Channel-mapping: HMP roomType ↔ OTA roomType, HMP ratePlan ↔ OTA ratePlan, HMP propertyId ↔ OTA hotelCode.
- Failure handling: retry queue, circuit breaker, pin-mode TLS (
certPinningModeper recent CLAUDE.md note — verify in code).
Verify each primitive:
- ARI push endpoint exists + a scheduler / manual trigger. Idempotency keys present (per recent memory
@hmp/api-contractsOtaBookingRoomLineetc. — but don't trust the memory, open the file and verify). - Stop-sale endpoint — distinct primitive or piggy-backed on inventory=0? Check ResAvenue spec ref in code comments and confirm conformance.
- Schema:
OtaConnection,OtaChannelMap,OtaInboundEvent,OtaOutboundJob. Verify fields cover the above. - Inbound: ResAvenue webhook handler validates signature (HMAC?), dedups via
eventId, postsOtaInboundEvent, normalizes to internalReservationvia the multi-RoomStay flow per recent memory. Open the parser and verify multi-room aggregation. - Cancel: ResAvenue cancellation creates a CANCELLED reservation event → reservation-service cancels and releases inventory.
- Health monitoring: a status page or endpoint shows the connection state (last sync, errors).
- Test coverage: fixtures of real OTA payloads (XML / JSON) replayable.
- Cert evidence: there's mention in recent memory of ResAvenue cert testing (KNV_I_01..09 + KNV_R_01..09). Verify test files actually exist and pass against fixtures.
UI:
- Admin-portal / dashboard channel-manager pages: list connections, mapping editor, inbound queue, force-resync button, certificate pinning UI. Verify each page calls real endpoints.
Flow 12 — POS terminal & payment gateway
Two threads:
12.a POS terminal (physical)
- Card-present integration: which terminal vendor (PineLabs / MSwipe / Razorpay POS / Stripe Terminal)? Verify by grep. If none integrated, RED.
- Tip-on-terminal flow.
- Reconciliation: terminal batch settlement vs HMP
Paymentrows.
12.b Payment gateway (online)
- Razorpay primary (per platform docs). Verify the keys are env-driven, not hard-coded.
- Order creation → checkout widget → server-side capture → webhook receiver in
hmp-payment-service. Verify webhook signature validation. Verify idempotency. - Refund flow: full + partial. Verify refund row + ledger update + notification.
- 3DS / SCA handling for international cards.
- Payment statuses propagate:
PENDING → AUTHORIZED → CAPTURED → SETTLEDorFAILED → REFUNDED → CHARGEBACK. Verify the transitions. - Subscription billing for SaaS tenants:
SUBSCRIPTION_VIA_PAYMENT_SERVICE_ENABLED. Verify both flag paths. - PCI: payment-service network isolation, no card numbers stored anywhere outside the gateway tokenization. Grep the entire repo for fields like
cardNumber,cvv,cvv2,pan. - UI: settlement page on dashboard, payment-method UI on booking engine, refund modal on reservation detail.
Flow 13 — Tape Chart Calendar (hero feature)
Industry definition: a 2-D grid where rows = rooms (grouped by room type / floor) and columns = dates. Cells = reservation bars showing occupancy, status colour, guest name. Operations performable from the grid:
- Drag a reservation bar horizontally → move dates (extend / shorten).
- Drag a reservation bar vertically → move rooms (room reassignment).
- Click an empty cell → start a new walk-in reservation for that room/date.
- Click a bar → open reservation detail in a side-panel.
- Right-click / context menu: check-in, check-out, cancel, room-move, OOO block.
- Bulk select: stop-sell a date range across rooms.
- Filters: by room type, floor, building, status.
- OOO/OOS blocks rendered as non-interactive coloured cells.
Verify:
- The page exists in
hmp-web-dashboard(search fortape-chartorcalendar). - Backend: the page uses a single bulk fetch endpoint (
GET /reservations/grid?from=&to=&propertyId=) returning all reservations + room blocks for the range. Verify the endpoint exists and is paginated/streamable for 100+ rooms × 30 days. - Drag interactions wired: each gesture maps to the right backend mutation (move = update reservation
roomId, extend = updatedeparture, etc.). Verify the mutations have optimistic-locking or conflict resolution (two agents dragging the same reservation simultaneously must not both succeed). - Conflict UX: when a drag would cause overlap, the UI rejects + explains.
- Performance: ≥ 100 rooms × 30 days = 3,000 cells must render in ≤ 1 s on a mid-tier laptop. Verify the DOM strategy (virtualization?). If not virtualized, AMBER.
- Mobile: tape charts are typically desktop-only; verify graceful degradation or explicit "desktop only" message.
- Accessibility: keyboard navigation + screen-reader announcements on cell focus.
If the tape chart only renders the grid but operations have to be done from elsewhere (reservation detail page), verdict is RED — the user said this is the hero feature for property #1.
8. Cross-cutting verification track (run once, not per flow)
Investigate these themes across the full repo:
- Tenant isolation: pick 5 random
*.controller.tsfiles across services and verify every database query istenantId-scoped. List any that are not. - JWT vs API-key: every
@Public()route must be either an internal-only path or have an API-key guard. Grep for@Public()and triage. - Two-file rule: list every prefix in
hmp-api-gateway/src/config/services.config.tsand confirm matching@Alldecorators inproxy.controller.ts. Conversely, list any decorator without a config entry. - Cross-service Prisma anti-pattern: grep all services for
import { ... } from '@prisma/client'followed by use of foreign models (e.g.,RoomTypein reservation-service). Each occurrence is a runtime crash waiting. - Idempotency on critical paths: list reservation confirm, payment capture, OTA inbound, check-in, check-out, night audit. For each, document the dedup mechanism.
- Event subscription wiring: open each backend service's compose entry. Verify
SKIP_EVENT_SUBSCRIPTIONS=falseeverywhere except the gateway. - Esbuild externals: every backend's
buildscript must externalize@prisma/client,bcrypt,sharp,mjml(where used),puppeteer,ssh2,class-validator,class-transformer,passport*,@aws-sdk/*. Open eachpackage.jsonand verify. - DI metadata erasure: grep for
import typein NestJS service files. Anyimport typeof a class used as a constructor parameter type erases DI metadata at runtime. - Compliance flags in production compose:
HARDWARE_MOCK=false,EINVOICE_MOCK=falseindocker-compose.prod-aws.yml. If=truein prod, RED. - Secrets: grep for hard-coded
JWT_SECRET,RAZORPAY_KEY_SECRET, RDS passwords, OTA credentials. Anything outside env vars or AWS secrets manager is a P0. - Schema drift: pick
tenantIdandpropertyIdand confirm the same@db.Uuiddeclaration across all 16 services' Prisma schemas. Pick one or two enums (e.g.,RoomStatus,ReservationStatus) and confirm the same values across services. - Build hygiene: in each backend repo, run
npx tsc --noEmit(read-only); list any service that fails. Run each frontend'snpm run buildonly if safe. - Test runner: run
npx jest --listTestsper backend service to confirm Jest config loads. Capture test counts.
9. Anti-patterns to flag on sight
If you encounter any of these during the review, mark each occurrence as a finding with a P0/P1 severity per its impact.
- A controller method returning
Promise<any>without DTO. - A service method using
// @ts-ignoreor// eslint-disable-next-lineover a real type error. - A try/catch that swallows the error and returns a fake success.
- A frontend page with
// TODO,// FIXME,// mock datastill wired. - A
useEffectwith no dependency array fetching data — re-renders thrash. - A Prisma query without
tenantIdin thewhereclause. - A raw SQL string interpolated with user input (
$queryRawUnsafe) — SQL injection. - A
console.logorconsole.errorin a prod code path (use Pino). - Hard-coded UUIDs (e.g.,
00000000-0000-4000-a000-...) outside seed scripts. bcryptcost factor < 12.- Razorpay keys in repo (even test keys are an anti-pattern in master).
- Multiple sources of truth for the same business rule (e.g., GST percentage in schema seed AND in folio-posting code).
- Frontend forms without zod / yup validation.
- Modals without focus trap or escape-to-close.
- Currency rendered without locale-aware formatting (use
Intl.NumberFormat('en-IN')). - Date rendered without timezone — IST guests confused by UTC display.
- Dependency on
latesttag inpackage.jsonfor@hmp/*packages.
10. Parallelisation strategy
This review touches ~16 services + 5 frontends + 27 shared packages. It will not finish in a single linear pass. Use the following structure:
Phase A — single-pass inventory (≤ 30 min)
You do this yourself, no sub-agents:
- Read
C:\CLProjects\HMP\CLAUDE.mdonce for orientation only. - List the contents of
C:\CLProjects\HMP\(all repos). - For each backend repo, capture the git HEAD short-sha and the
package.jsonversion. - Open
hmp-api-gateway/src/config/services.config.tsandproxy.controller.ts. Capture the routing table. - Open each Prisma schema and capture model names + tenantId presence.
- Capture compose env-var flags from
docker-compose.dev-all.ymland…/docker-compose.prod-aws.ymlif present.
Phase B — parallel flow reviews (≤ 90 min)
Spawn 13 sub-agents in parallel (one per flow) using the Agent tool with
subagent_type: "general-purpose". Each sub-agent gets:
- The flow's number, name, and the §5 methodology.
- The §7 specifics for that flow.
- The §1 non-negotiable rules (especially "do not trust documentation").
- The Phase A inventory output as context (paths, commits, route table).
- An instruction to return a single markdown section ready to paste under §6.4 of the final report, ≤ 1500 words, with a verdict and a remediation list.
Each sub-agent must run read-only and must return file:line citations.
Phase C — cross-cutting sweep (≤ 30 min)
You do this yourself: §8.
Phase D — synthesis (≤ 30 min)
You compose §6.1 (executive verdict), §6.2 (flow status table), §6.6 (top 20 P0 blockers ranked by impact × effort), §6.7 (effort summary). Pull each sub-agent's section verbatim into §6.4.
Phase E — write & commit
Write the report to the path in §6. Do not commit (the user will review and commit themselves).
Total wall-clock target: ≤ 3 hours. If you bust the budget, shrink the depth on GREEN-leaning flows, not on the AMBER/RED ones.
11. Verification techniques (the small toolkit)
- Existence:
Globfor files,Grep -lfor symbols. - Field-level: open the Prisma schema, copy the model block into the report,
highlight missing fields with
// MISSINGannotations in your draft. Do not edit the actual schema. - Endpoint inventory:
Grep -nfor@Get|@Post|@Put|@Patch|@Delete|@Allper service. - Gateway routing: read both files top to bottom; list every prefix; cross-check.
- Test counts:
Glob "**/*.spec.ts"per repo, count, then sample 5 to see if they actually exercise the path or are placeholderit.todos. - UI coverage:
Glob "src/app/**/page.tsx"per frontend, then for each flow identify which pages are involved and read them. - Live behaviour (optional, only if local stack is up): hit
http://localhost:3010/api/healthand the per-service health endpoints to confirm boot. If the local stack is not up, do not start it — say so and proceed with static review.
12. Common pitfalls in this codebase (don't get fooled)
These are real traps reported in commit history and prior incidents. Treat the existence of code as evidence of intent, not delivery. Verify:
- A "shipped" feature behind a default-OFF feature flag is not shipped for users. Confirm the flag default and confirm whether prod compose flips it on.
- Mock providers (
HARDWARE_MOCK=true,EINVOICE_MOCK=true) hide failures — the production unmock path may not exist. Verify both code branches. - Two implementations of the same thing (e.g., legacy vs payment-service subscription path). Both must work or one must be deleted before launch.
- Cross-service
xPrismaanti-pattern: code that compiles, deploys, and crashes at the first request because the slim per-service Prisma client doesn't carry foreign models. Look for direct Prisma access to non-owned tables. - Gateway routes added to one of the two files but not both → 404 in production.
- An
INTERNAL_SERVICE_TOKENendpoint that's reachable through the public gateway → tenant impersonation. - A frontend page that successfully loads with mock data because
MSWor a fake fixture is intercepting the request. - An event consumer disabled in prod via
SKIP_EVENT_SUBSCRIPTIONS=true. - A controller decorated
@Public()that should not be — opens the door for unauthenticated access. - An idempotency key used as a Redis key without an expiry → memory leak + eventual collisions.
13. What "GREEN" actually means for property #1
A flow is GREEN only if all of these are true:
- Every required user step has a backend endpoint reachable via gateway with correct auth.
- Every endpoint queries with
tenantId/propertyIdscope. - Every endpoint that mutates has idempotency where industry-standard (booking confirm, payment, check-in/out, OTA inbound, night audit).
- Every required field in §7 exists in the schema with the right type + index.
- Every user step has a UI screen, the screen calls the real endpoint (no mock), displays every required field, handles loading/empty/error.
- There is at least one happy-path test (unit / integration / E2E) and one negative test (validation / RBAC / conflict / replay).
- Any cross-service reads use
@hmp/service-clientswith the receiver-sideassertPropertyTenantcheck. - Any events emitted are consumed by all required consumers (incl. analytics MV consumers) and dedup is in place.
- Indian-compliance checks pass for the flow (GST, IRN, Form C, DPDPA where relevant).
- The flow works in the dev compose stack with default seed data — no manual DB tweaks required.
If 9 out of 10 pass, it's AMBER, not GREEN. Don't round up.
14. What you must not do
- Do not write code or migrations.
- Do not run
prisma migrate,prisma db push --force-reset, or seed scripts against any DB you didn't already have. - Do not push to any git remote.
- Do not commit the report (user will commit themselves).
- Do not invoke any plan/spec writing skills or implementation skills. This is a read-only audit.
- Do not summarise findings as "this looks good." Cite or omit.
15. When you are done
- Write the final report to the path in §6.
- Print to chat:
- The path of the report file.
- The total counts of GREEN / AMBER / RED / UNKNOWN flows.
- The top 5 P0 blockers (one line each).
- Total wall-clock time spent.
- Stop. Do not propose next steps unless asked.
Begin Phase A now.