Skip to main content

BF-010 — Banquet Event Lifecycle (Inquiry → Settlement)

Business flow (single-EPIC journey, but cross-service via POS for F&B handoff and payment-service for milestones). Reconciled 2026-05-25 as Wave 2 of the RTM Reconciliation Scale-Out, following the BF-001 template (BF-001-tenant-property-onboarding.md) and the PLAYBOOK.md.

Source per-EPIC RTM: EP-008-rtm.md (11 drift findings, 4 P0). This flow doc inherits those D-NNN refs and surfaces the cross-step composition issues that single-story review cannot see.

Each step names (a) the user story that owns the requirement, (b) the primary code path that runs it, (c) the closest automated test that exercises it, and (d) pre/post-conditions and notes. Where the spec contains no matching catalog story, the step is tagged [SME-PROPOSED] as a NEW story for the SME's intake.

India context — Weddings drive 30–40 % of total property revenue for the typical Indian mid-market hotel. Receptions seat 600–2000 pax. GST is split (5 % food / 18 % venue+AV+decor / state-VAT alcohol). Payment milestones (advance + 50 % pre-event + balance) are non-negotiable. The banquet flow is the single highest-revenue user journey on the platform after multi-night room bookings, and the most regulation-sensitive after e-invoice.

Personas​

PersonaRoleSource
Sales CoordinatorFirst-contact owner — captures inquiry, builds quote, sends proposal[SME-PROPOSED] — no catalog persona row today; surfaced by Step 1
Banquet ManagerOwns the event from CONFIRMED through execution; approves function sheet[SME-PROPOSED] — no catalog persona row today; surfaced by Step 6
Operations / CaptainDay-of-event setup + service supervision; reads BEO[SME-PROPOSED] — no catalog persona row today; surfaced by Step 7
Executive ChefReads function sheet menu section; coordinates kitchen prep[SME-PROPOSED] — no catalog persona row today; surfaced by Step 8
Front Office / CashierPosts final invoice, collects balance, issues GST receipt01-epic-catalog.md (EP-005B) — reused from BF-005
Wedding Client (B2C)Walk-in / phone / web inquiry → primary decision-maker for menu, decor, AVepics/EP-008-banquet-events.md §3
Corporate Client (B2B)Conference / annual-day / product-launch — invoice goes to company GSTINepics/EP-008-banquet-events.md §3

Entry points​

EntryURLBacked by
Dashboard new eventhttps://dashboard.<env>.keynova.ai/banquet/events/newhmp-web-dashboard/src/app/(dashboard)/banquet/events/new/page.tsx (placeholder per EP-008 review; ships only text)
Dashboard event listhttps://dashboard.<env>.keynova.ai/banquet/eventshmp-web-dashboard/src/app/(dashboard)/banquet/events/page.tsx
Public inquiry (proposed)https://book.<env>.keynova.ai/banquet/inquiry[SME-PROPOSED] per EP-008 D-011 — no @Public() inquiry-receive endpoint today
Calendarhttps://dashboard.<env>.keynova.ai/banquethmp-web-dashboard/src/app/(dashboard)/banquet/page.tsx (US-008-008 — Built-Untested per EP-008)

The 11-step journey​

Step 1: Inquiry received (walk-in / phone / web form)​

  • Story: US-008-012 (Event Inquiry to Quotation Flow — catalog says Built, EP-008 verified Not Started as a dedicated workflow). [SME-PROPOSED] companion — US-008-NEW-INQUIRY-INTAKE to model the multi-channel intake (90 % WhatsApp/phone/walk-in, 8 % web, 2 % OTA cross-sell in Indian-wedding market).
  • Code: hmp-banquet-service/src/events/events.controller.ts:31 — @Post('/') creates an EventBooking with status='INQUIRY', @Roles('SUPER_ADMIN','ADMIN','MANAGER') + @RequiresFeature('banquet'). DTO: events/dto/event.dto.ts::CreateEventDto. There is no @Public() inquiry-receive endpoint on booking-engine today (EP-008 D-011).
  • Test: hmp-banquet-service/src/events/events.service.spec.ts :: event-create coverage — PASS (per EP-008 RTM). Flow: banquet-lifecycle.flow.spec.ts :: "Scenario 2 — create event in INQUIRY" — TBD (banquet flag-gated; soft-skip path documented in spec).
  • Pre-conditions: Banquet feature flag ON for the tenant (PROFESSIONAL/ENTERPRISE plan). Property propertyId and at least one Venue row exists (Step 2 implicit prerequisite if venue-first). ADMIN/MANAGER session.
  • Post-conditions: EventBooking row in INQUIRY status with eventNumber (format EVT-YYYYMM-{6-char base36} per code today — EP-008 D-001 notes 3 conflicting formats across catalog/EPIC body/review). Sales coordinator notified.
  • Notes: For walk-in / phone, the sales coordinator captures over voice and types into the form — no intake-form differentiation today. Public booking-engine handoff (proposed under EP-008 D-011) would auto-create INQUIRY rows from a captcha-gated form + auto-acknowledge email.

Step 2: Venue availability check​

  • Story: US-008-002 (Venue Management) + US-008-008 (Event Calendar View).
  • Code: hmp-banquet-service/src/venues/venues.controller.ts :: GET /venues/:id/availability?startDate=&endDate= → venues.service.ts::checkAvailability() returns {isAvailable, conflicts} with multi-day overlap correctly handled. Frontend: calendar lives under hmp-web-dashboard/src/app/(dashboard)/banquet/page.tsx (component not separately tested per EP-008).
  • Test: venues.service.spec.ts :: availability coverage — PASS. Flow: banquet-lifecycle.flow.spec.ts :: "Scenario 1 — a venue exists" — TBD.
  • Pre-conditions: Step 1 ongoing (date-range from inquiry); at least one Venue row in the property.
  • Post-conditions: Sales coordinator sees green/red per requested slot. The conflict list (if any) is shown but does NOT auto-suggest alternative slots.
  • Notes: Indian wedding-season reality — a single Saturday in Nov-Feb may have 4-6 simultaneous functions across 3+ venues. The colour-coded monthly view is inadequate for that load (EP-008 §SME-notes on US-008-008). Drag-to-reschedule / week / day views are missing — flagged as Partial in EPIC body, "Built" in catalog (EP-008 RTM Built-Untested).

Step 3: Tentative hold (status=INQUIRY → TENTATIVE)​

  • Story: US-008-001 (Event Creation, 7-Status Lifecycle) — status-machine portion. [SME-PROPOSED] per EP-008 D-011 — add explicit tentativeHoldHours config + auto-release CRON.
  • Code: hmp-banquet-service/src/events/events.controller.ts:63 :: @Patch(':id/status') → events.service.ts::updateStatus(). State machine: STATUS_TRANSITIONS static map at events.service.ts:22-30. Venue conflict re-checked on every transition via checkVenueConflict() with setup/teardown buffer overlap.
  • Test: events.service.spec.ts :: status-machine specs — PASS. Flow: banquet-lifecycle.flow.spec.ts :: "Scenario 4 — INQUIRY → QUOTATION_SENT → TENTATIVE" — TBD.
  • Pre-conditions: Step 2 returned isAvailable=true; INQUIRY-state event exists.
  • Post-conditions: EventBooking.status=TENTATIVE. Today: no statusChangedAt column timestamp and no CRON to auto-release; the tentative slot will stay held forever until manually advanced or cancelled. Real-world risk: sales coordinator forgets a tentative → venue is silently double-booked at QUOTATION_SENT time for a different client.
  • Notes: Precondition checks are NOT enforced (EP-008 SME-notes on US-008-001): INQUIRY→QUOTATION_SENT does not require items.length > 0; TENTATIVE→CONFIRMED does not require a signed contract or 25 %-of-total payment. This is the highest-severity gap in this story.

Step 4: Quote sent (per-pax pricing + F&B + decor + AV)​

  • Story: US-008-004 (Event Items & Costing) + US-008-007 (BEO / Proposal PDF Generation — catalog Not Started, EP-008 verified Stub).
  • Code: Items: events.controller.ts:93-141 :: POST/GET/PATCH/DELETE /events/:id/items → events.service.ts::addItem() recalculates total = SUM(lineTotal). Categories enum (today): VENUE / FOOD / BEVERAGE / AUDIO_VISUAL / DECORATION / OTHER. Proposal PDF: endpoint does NOT exist today; the closest is contracts.service.ts Puppeteer pipeline for legal contracts (different purpose, no branding, no GST table).
  • Test: costing.service.spec.ts :: food cost calc via PosServiceClient — PASS (per EP-008 RTM). events.service.spec.ts :: item CRUD — PASS. Flow: banquet-lifecycle.flow.spec.ts :: "Scenario 3 — attach FOOD + AV line items" — TBD.
  • Pre-conditions: Event exists (INQUIRY or TENTATIVE state); at least one item type known.
  • Post-conditions: EventItem rows persisted. EventBooking.totalAmount recomputed. Today: no gstRate / gstAmount / totalExclGst / totalInclGst split per item (EP-008 D-005, P0) — folio downstream cannot reconstruct the correct GST breakdown for GSTR-1. No costPrice population — P&L (Step 11 follow-up + US-008-006) is fake (EP-008 D-007). No PDF — sales coordinators export to Word/Excel and email manually.
  • Notes: Per-pax pricing for Indian weddings — typical wedding lunch buffet is ₹1,200–₹2,500/pax (vegetarian) or ₹1,800–₹3,500/pax (mixed). Reception ₹2,500–₹5,000/pax. The current unitPrice * quantity model handles per-pax fine, but the missing 5 % vs 18 % GST split breaks compliance. Category enum drift (3 different taxonomies across catalog / EPIC body / review per EP-008 D-005) means STAFFING (banquet captains, waiters, security) has no item-type today.

Step 5: Confirmation: status=CONFIRMED + payment milestone 1 (advance)​

  • Story: US-008-001 (status machine, CONFIRMED transition) + US-008-005 (Payment Milestones — catalog Built, EP-008 verified Partial).
  • Code: events.service.ts::updateStatus() :: TENTATIVE→CONFIRMED transition + event-group.service.ts::createGroupForEvent() auto-creates a Group row with roomEstimate = ceil(expectedGuests/2) for the room block. Payment: hmp-banquet-service/src/event-payments/event-payments.controller.ts :: POST /events/:eventId/payments records a flat EventPayment row (paymentType: ADVANCE | MILESTONE | FINAL) and recomputes event.paidAmount. There is NO PaymentMilestone schedule — the sales coordinator must MANUALLY remember to record each milestone (EP-008 D-006, P0).
  • Test: event-group.service.spec.ts :: room-block creation — PASS. Flow: banquet-lifecycle.flow.spec.ts :: "Scenario 4 — record 25 % advance" — TBD (also notes BANQUET-01: CONFIRMED transition currently 500s due to room-block Prisma validation gap; spec stops at TENTATIVE).
  • Pre-conditions: Step 4 line items populated; client has verbally / contractually committed.
  • Post-conditions: EventBooking.status=CONFIRMED. Auto-created Group row for room block. EXPECTED but missing: PaymentMilestone rows for Advance / Pre-event / Final with dueDates; payment-link issued via PaymentServiceClient (Razorpay) for UPI advance collection.
  • Notes: Indian-wedding payment realities — 30/40/30 (advance/pre-event/final) is one split; 25/50/25 is another; some properties demand 50 % non-refundable advance + 50 % within 14 days. Hardcoded 25/25/40/10 per review is wrong for most operators. CONFIRMED-transition flow-test 500 (BANQUET-01) is a Plan-blocking bug — the auto-created Group row fails Prisma validation on missing holdUntil field. Until that lands, end-to-end test cannot prove CONFIRMED.

Step 6: BEO / Function Sheet generated​

  • Story: US-008-003 (Function Sheet Management — catalog Built, EP-008 verified Partial) + US-008-007 (BEO PDF — catalog Not Started, EP-008 verified Stub).
  • Code: hmp-banquet-service/src/function-sheets/function-sheets.controller.ts :: GET/PUT /events/:eventId/function-sheet + POST /events/:eventId/function-sheet/approve. Schema: FunctionSheet 1:1 with EventBooking; 6 JSON-blob columns (setupInstructions, seatingArrangement, menuDetails, beverageDetails, avRequirements, timeline, staffAssignments). PDF generation does NOT exist — frontend renders JSON view, ops teams screenshot or print.
  • Test: [CITED-BUT-NOT-FOUND] — no function-sheets.service.spec.ts per EP-008 RTM.
  • Pre-conditions: Step 5 (CONFIRMED) completed; Banquet Manager session.
  • Post-conditions: FunctionSheet row with version=N+1, approvedBy/At populated. Risk: edit-lock NOT enforced after approval (EP-008 D-004 P1) — chef can receive a stale version if anyone edits after approval but before printing.
  • Notes: Function sheet is CORE to Indian banquet operations — chef, AV, housekeeping, security, valet all coordinate from this single document. The Puppeteer pipeline that powers contracts.service.ts is exactly what BEO/Proposal needs; the missing piece is template authoring + content aggregation, not new tooling (EP-008 D-008). Indian-wedding muhurat (auspicious time) needs a structured timeline with IST timezone + eventType enum — the timeline JSON blob today accepts any shape.

Step 7: Day-of-event setup (banquet ops checklist)​

  • Story: US-008-011 (Event Staffing Assignment — catalog Partial, EP-008 verified Partial/proposed-demote-to-Stub).
  • Code: FunctionSheet.staffAssignments JSON blob — free-form text today. NO EventStaffAssignment model, NO conflict-check across simultaneous events, NO link to User table from auth-service. The Banquet Manager / Captain reads the function sheet on a phone or printed copy and executes the setup checklist manually.
  • Test: none enumerated.
  • Pre-conditions: Step 6 approved function sheet; event reaches event.startDateTime - setupTime window.
  • Post-conditions: Tables / chairs / stage / dance floor / buffet / AV physically arranged per layout. Status transition CONFIRMED → IN_PROGRESS happens manually via the dashboard. No precondition check that Date.now() >= event.startDateTime (EP-008 SME-notes on US-008-001).
  • Notes: Real banquet staffing for a 500-pax wedding ≈ 40+ people (1 captain + 2 supervisors + 25 service staff + 4 chefs + 2 AV ops + 2 HK + 4 security). Free-form JSON cannot model this. Karnataka Shops & Establishments Act caps shifts at 8 hours — no compliance gate today (EP-008 D-010).

Step 8: F&B handoff to POS (banquet covers)​

  • Story: US-008-004 (Event Items & Costing, FOOD/BEVERAGE items linked via menuItemId soft-FK to pos-service MenuItem). [SME-PROPOSED] — US-008-NEW-POS-HANDOFF for the explicit covers-handoff path.
  • Code: hmp-banquet-service/src/costing/ :: /events/:id/costing and /menu-items/:id/cost use PosServiceClient to look up ingredient costs when EventItem.menuItemId is set (per CLAUDE.md). The actual KOT / covers handoff to hmp-pos-service outlets (banquet hall outlet, kitchen) is NOT wired today — there is no EventCoversCreatedConsumer in pos-service and no event.covers.created Kafka publisher in banquet-service. The kitchen reads volume from the printed function sheet, not the POS.
  • Test: costing.service.spec.ts — PASS for the cost-lookup path. No tests for cover-handoff.
  • Pre-conditions: Step 7 setup completed; kitchen prep starts ~2 hours before service.
  • Post-conditions (expected, not built): KOT rows created in pos-service for the banquet kitchen with pax counts per dish. F&B revenue posts to the banquet-event folio (not a guest folio) via PosFolioChargeConsumer. Today: ingredient-cost lookup works one-way (event reads from POS), but operational F&B execution remains paper-driven.
  • Notes: This is the highest-frequency cross-service seam the catalog doesn't model. Indian-wedding kitchens run live buffets and live counters (dosa / chaat / paan stations) — each is a sub-cover-count that POS could track for actual-vs-estimated reconciliation at Step 11.

Step 9: Event execution​

  • Story: US-008-001 (IN_PROGRESS state — STATUS_TRANSITIONS allows CONFIRMED → IN_PROGRESS → COMPLETED).
  • Code: events.service.ts::updateStatus() — transitions are mechanical, no event-time check. Frontend shows status on event detail page.
  • Test: events.service.spec.ts — status-machine specs cover the transition.
  • Pre-conditions: Step 7 setup ready; event.startDateTime reached.
  • Post-conditions: EventBooking.status=IN_PROGRESS. During event, no telemetry feedback to the platform (no live cover-count, no service-pace tracking, no incident log).
  • Notes: Multi-day Indian weddings (mehndi / sangeet / wedding / reception) execute as 4 separate EventBooking rows today because multi-venue parent-child is NOT enforced in API (EP-008 D-009, P0). Total revenue / total payments / total guest count do not aggregate across the 4 — the GM gets 4 disconnected views of one wedding. This is the single biggest India-revenue feature gap.

Step 10: Settlement: final invoice + balance payment​

  • Story: US-008-005 (Final milestone) + US-008-001 (IN_PROGRESS → COMPLETED) + cross-EPIC handoff to EP-005B (Folios) + EP-012C (E-Invoice IRN per BF-005).
  • Code: Final payment recorded via the same POST /events/:eventId/payments (Step 5). The event-folio handoff to hmp-frontdesk-service for GST-compliant invoice + IRN generation is NOT modelled today — the frontdesk e-invoice service EInvoiceService operates on guest folios (Folio model), not banquet EventBooking rows. Today the cashier issues a manual GST invoice from a Word template.
  • Test: events.service.spec.ts (status COMPLETED transition) — PASS. No tests for banquet→folio→IRN handoff.
  • Pre-conditions: Step 9 IN_PROGRESS; event end-time reached or operator closes early.
  • Post-conditions (expected, not built): EventBooking.status=COMPLETED, paidAmount === totalAmount. GST e-invoice with IRN generated for the event total (single invoice or split per-day for multi-day weddings — operator decision, no schema support today). Folio reconciled.
  • Notes: India e-invoice for banquet — IRN required when event_total ≥ ₹5 cr aggregate B2B turnover (industry threshold). For wedding (B2C) events, IRN is not mandatory but recommended for >₹2.5 L bills per CBIC guidance. The GST split (5 % food / 18 % venue) per EP-008 D-005 MUST be on the invoice — a flat 18 % invoice over-charges the client by 13 % on the food slice and is rejected by NIC IRP on mismatched HSN/SAC.

Step 11: Post-event feedback + P&L close​

  • Story: US-008-006 (Event P&L Report — catalog Partial, EP-008 verified Partial proposed-Stub). [SME-PROPOSED] — US-008-NEW-POST-EVENT-FEEDBACK for the survey loop (CRM integration).
  • Code: P&L page exists at hmp-web-dashboard/src/app/(dashboard)/banquet/events/[id]/pnl/page.tsx with HARDCODED 35 % F&B + 20 % AV + ₹200/pax staff ratios (EP-008 D-007). There is NO backend /events/:id/pnl endpoint. Post-event feedback survey is NOT wired — no CRM event published on COMPLETED, no email/SMS/WhatsApp templated survey, no EventFeedback model.
  • Test: costing.service.spec.ts covers the ingredient-cost backbone, not P&L. No tests for feedback loop.
  • Pre-conditions: Step 10 COMPLETED.
  • Post-conditions (expected, not built): EventPnL snapshot row written. Survey link sent within 24 h to event.clientEmail / event.clientPhone. Response stored on event for reference in future inquiries from the same client.
  • Notes: The dangerous-UX problem of the hardcoded P&L (EP-008 D-007) is the riskiest banquet finding — a new banquet manager will TRUST a clean P&L page; the numbers are plausible-but-fake. Until the backend endpoint ships, the page MUST carry an "industry-average estimates" banner. Indian-banquet margin reality: weddings 30–40 % gross margin, corporate 50 %+, social 25–35 % — the hardcoded 35 % "looks right" for weddings but is wrong for everything else.

Failure modes worth testing​

#ScenarioExpected behaviourCoverage todayOwning story
F1Two coordinators try to confirm two events on the same venue/date (double-booking)Second confirm → 409 VENUE_CONFLICT with offending event details; checkVenueConflict() re-runs at every status transitionevents.service.spec.ts — venue-conflict specs PASS; flow-spec retries with prime-shift dates due to DB accumulationUS-008-001 + US-008-002
F2Function sheet edited after approval409 FUNCTION_SHEET_LOCKED unless ?force=true&reason=<text> + manager roleNOT IMPLEMENTED (EP-008 D-004 P1) — silent overwrite todayUS-008-003
F3F&B handoff to POS fails (pos-service down)Event remains IN_PROGRESS; outbox retries cover-creation; chef notified via fallback channelNOT WIRED today — no F&B handoff exists; chef reads paper function sheet[SME-PROPOSED] US-008-NEW-POS-HANDOFF
F4Payment milestone overdue (pre-event 50 % missed)Daily 02:00 IST CRON flips PENDING→OVERDUE; publishes banquet.payment.overdue; notification-service sends WhatsApp + SMS reminder (transactional template, registered sender per TRAI DND)NOT IMPLEMENTED (EP-008 D-006 P0) — no PaymentMilestone modelUS-008-005
F5Event cancelled inside refund window (e.g. 7 days before wedding)Evaluate BanquetCancellationPolicy (sliding scale 90d/60d/30d/event-day default), compute charge_pct, adjust against advance via PaymentMilestone, post refund delta via PaymentServiceClient with refundSlaHours=168NOT IMPLEMENTED (EP-008 D-009 + US-008-013 SME-proposed) — free-text cancellation todayUS-008-013
F6Decor vendor no-show on the dayOperator marks EventBooking.notes and triggers backup decor SOP; cancellation policy does NOT apply (vendor-side failure)NO incident-log model; operator notes free-text[SME-PROPOSED] US-008-NEW-INCIDENT-LOG
F7AV equipment shortage (e.g. wireless mic dies mid-speech)Operator marks AV item as requiresReplacement=true; replacement cost auto-adjusts on folio; post-event reconciliation flags variance vs estimateNO AV-incident tracking; operator handles offline[SME-PROPOSED] US-008-NEW-INCIDENT-LOG
F8Multi-day wedding sub-event cancelled (e.g. mehndi cancelled, wedding+reception proceed)Sub-event releases venue + computes proportional charge; master event remains active with reduced total; refund cascades only on the cancelled sub-eventNOT POSSIBLE today — multi-venue parent-child not enforced (EP-008 D-009 P0)US-008-010 + US-008-013
F9Cross-tenant venueId on create (ADMIN of tenant A creates event with venueId from tenant B)403 with ForbiddenException before any write; venueId leaks no tenant info via NotFoundExceptionevents/__tests__/event-cross-tenant-denial.spec.ts (8 tests, shipped 2026-05-24) — PASS but orphaned-test (EP-008 D-002 P0; no story AC)US-008-001 + [SME-PROPOSED] US-008-NEW-VENUE-TENANT-GUARD

Day-2 banquet operations (NOT in BF-010 pilot scope)​

Items typically tackled in the first 30 days of banquet go-live for a property. Not in BF-010 scope but flagged so future BFs / hardening sprints know where to pick up:

  • Wedding-portfolio CRM — repeat clients (DJs, wedding planners, decorators) get a vendor profile; integrate with hmp-crm-service.
  • WhatsApp Business API integration — inquiry funnel via WhatsApp (90 % of Indian-wedding leads per Step 1 SME notes).
  • Vendor master + AMC tracking — banquet's recurring vendors (decor, DJ, photographer, mehndi artist, mandap florist) onboarded via hmp-asset-service Vendor module.
  • OTA cross-sell — small % of inquiries arrive via OTA hotel pages; needs hmp-channel-service to surface banquet inquiry CTA.
  • Banquet outlet config in POS — banquet hall as a PosOutlet for F&B handoff (Step 8 prerequisite).
  • Seasonal venue rate cards — peak-season (Nov-Feb wedding window) vs lean-season (Jun-Sep) per-setup-type pricing per EP-008 D-003 VenueRate proposal.
  • Multi-property banquet roll-up — chain owners want consolidated banquet revenue across properties for the wedding season.
  • Floor plan template library — FloorPlanTemplate reuse across events per EP-008 SME proposal for US-008-009.
  • Integration with kitchen display (KDS) — large-volume buffet stations to show on KDS like an a-la-carte order.
  • Photographer / videographer slot booking — currently free-text on contract; could be EventResource line items.
  • Cake-cutting / muhurat-time SMS reminder to vendors — IST timezone + per-vendor delivery time tracking.

Drift summary​

The 11 EP-008-surfaced drifts that the SME pass must adjudicate, plus 2 BF-010-specific cross-step composition drifts that single-story review cannot see. (P0 = blocks pilot sign-off; P1 = ships next sprint; P2 = backlog.)

IDTypeSeverityDescriptionSurfaced by step
EP-008 D-001Catalog-vs-EPIC-bodyP02-digit vs 3-digit story IDs with different title mappings; reviews follow catalog. EVT- numbering has 3 different formats (catalog/EPIC body/review).Step 1
EP-008 D-002Tests-assert-behavior-story-doesn't-describeP0event-cross-tenant-denial.spec.ts (8 tests) asserts venue-tenant + venue-property cross-checks that no story AC mentions.Step 1 + F9
EP-008 D-003Story-incomplete + India-criticalP1Venue model lacks receptionCapacity despite 600-pax reception scenario in EPIC body. Per-setup-type rate card (VenueRate) missing.Step 2
EP-008 D-004Story-incomplete + ops-criticalP1Function sheet edit-lock NOT enforced after approval; no PDF export; no department-routing Kafka. Chef receives stale versions.Step 6
EP-008 D-005Story-incomplete + GST-blockerP0EventItem has no GST split (5 % food / 18 % venue+AV+decor). Folio cannot reconstruct GSTR-1. Revenue-leakage risk (over-paying GST 13 % on food slice).Step 4 + Step 10
EP-008 D-006Story-incomplete + revenue-protectionP0No PaymentMilestone model; no schedule generation on CONFIRMED; no overdue CRON. Sales coordinator manually remembers each milestone → forgets pre-event 50 % → painful day-of collection.Step 5 + F4
EP-008 D-007Stub-shipped-as-Partial + dangerous-UXP1Dashboard P&L page uses HARDCODED 35 %/20 % ratios but presents as real data. New banquet manager TRUSTS the numbers.Step 11
EP-008 D-008Status-mislabel + revenue-blockerP0BEO/Proposal catalog Not Started but Puppeteer infrastructure HALF-built via contracts.service.ts. Sales teams blocked.Step 4 + Step 6
EP-008 D-009Catalog-priority-mismatch + India-revenue-criticalP0Multi-venue parent-child marked P3 in catalog. For Indian-wedding-focused platform (30-40 % revenue), this is P0. Schema half-built (parentEventId), API enforcement zero.Step 9 + F8
EP-008 D-010Story-incomplete + cross-service-integrationP1Staffing is free-form JSON; no User link, no conflict detection, no labour-compliance gate (Shops & Establishments Act).Step 7
EP-008 D-011Status-mislabel + booking-engine-integration-gapP1Inquiry-to-quotation flow Built in catalog; the status TRANSITION exists, the WORKFLOW does not. No @Public() inquiry endpoint, no TENTATIVE auto-release.Step 1 + Step 3
BF-010 D-012Cross-step compositionP0F&B handoff to POS (Step 8) has NO publisher or consumer — banquet EventBooking does not produce event.covers.created Kafka events; pos-service has no EventCoversCreatedConsumer. Kitchen reads paper, not data. Closes the loop on EP-007 (POS) ↔ EP-008 (Banquet) cross-EPIC gap that neither RTM owns.Step 8
BF-010 D-013Cross-step compositionP0Banquet → Folio → E-Invoice handoff (Step 10) is NOT modelled — EInvoiceService in hmp-frontdesk-service operates on guest Folio rows, not EventBooking. Cashier issues a manual Word-template GST invoice. No IRN registered with NIC IRP for banquet revenue. Compounds with EP-008 D-005 (missing GST split) — even if banquet-service produced an invoice, it would be 18 %-flat and rejected by NIC.Step 10

Cross-EPIC narrative summary​

StepSpansWhy cross-EPIC
1 → 3EP-008 (banquet) — inquiry / venue / tentativeSingle-EPIC; the missing @Public() inquiry endpoint (D-011) would pull EP-003 (booking-engine) into the inquiry funnel.
4 → 5EP-008 ↔ EP-015 (payments)Payment milestone advance via PaymentServiceClient (Razorpay) — not wired today (D-006). Quote PDF reuses contracts.service.ts Puppeteer pipeline (D-008).
6 → 7EP-008 internalFunction sheet + setup checklist all live in banquet-service today. D-010 would pull EP-001 (auth users) into staffing. D-004 PDF-export reuses contracts pipeline.
8EP-008 ↔ EP-007 (POS) — UNCONNECTED TODAY (D-012)F&B handoff: covers, KOT, banquet outlet — the highest-frequency cross-service seam, modelled by zero stories.
9EP-008 internal — IN_PROGRESS stateD-009 multi-venue makes this multi-EPIC the moment the wedding has sub-events (mehndi at venue A, reception at venue B, same parent booking).
10EP-008 ↔ EP-005B (folios) ↔ EP-012C (e-invoice) — UNCONNECTED TODAY (D-013)Settlement: GST-compliant invoice + IRN. Banquet revenue ends up off-platform on a Word template.
11EP-008 ↔ EP-014 (notifications) ↔ EP-012A (analytics KPI)Feedback survey via CRM/notification; P&L roll-up to property dashboard. Both unwired today.

The two BF-010 D-012 / D-013 cross-EPIC gaps (F&B handoff + invoice handoff) are the most material findings of this flow doc — neither appears in the EP-007 RTM, the EP-005B RTM, the EP-012C RTM, or the EP-008 RTM in isolation, because each RTM looks only at stories its EPIC owns. The cross-EPIC gap is precisely what the business-flow doc is designed to surface, per the playbook.

The P0 cluster of D-005 (GST split) + D-006 (milestones) + D-009 (multi-venue) + D-013 (invoice handoff) is the launch-blocker set for any property whose revenue mix is wedding-heavy. Without all four, the platform is unusable for the 30-40 % revenue slice that drives Indian banquet operators to buy a hotel PMS in the first place.