Skip to main content

Epic Catalog — [SME-PROPOSED] Status Corrections

Sidecar to: ../01-epic-catalog.md Authored: 2026-05-24 by RTM pilot (BF-001 Tenant + Property Onboarding) Scope: EP-001 + EP-002 only. Other EPICs unchanged from the live catalog. Workflow: Operator reviews this sidecar, accepts/rejects per row, merges accepted changes into the live catalog, deletes this sidecar.

New status vocabulary​

The live catalog uses 3 statuses (Built / Partial / Not Started). Partial is overloaded — it covers "some criteria met", "code exists but no tests", and "code is a stub". This sidecar introduces 5 statuses:

StatusMeaning
BuiltCode exists + tests exist + tests pass
Built-UntestedCode exists, no automated test coverage
PartialCode exists for some acceptance criteria, gaps for others
StubCode is a placeholder / TODO / mock
Not StartedNo code

The expanded vocabulary lets reviewers tell apart three real-world conditions the live catalog conflates today:

  • A story whose code is fully shipped but lacks tests (high-confidence implementation, low-confidence regression safety) — Built-Untested.
  • A story whose code is a placeholder that returns mock data — Stub.
  • A story whose code covers some acceptance criteria but not others — Partial.

Each conveys a different remediation cost; merging them into Partial hides the cost.


EP-001 (onboarding subset, 7 stories)​

Only the 7 EP-001 stories that participate in BF-001 (Tenant + Property Onboarding) are reconciled in this sidecar. The remaining 9 EP-001 stories are out of scope for the pilot and remain at their live-catalog statuses.

StoryLive status[SME-PROPOSED] statusReason
US-001-001BuiltBuilt(matches) — login + tests + flow coverage all green
US-001-004BuiltPartialMFA backend Built, frontend Partial; operationally OFF in all 4 envs via MFA_ENFORCE_ADMIN=false kill-switch (EP-001 D-003). Story body claims mandatory enforcement that does not exist today.
US-001-005BuiltBuilt(matches) — two-step tempToken flow + /auth/mfa/validate shipped; stale FAIL 2/10 review file flagged (EP-001 D-006)
US-001-006BuiltPartialRBAC backend Built, frontend Partial (sidebar/permission-gate wiring incomplete per review 7/9). Catalog also says "9 Roles" but code has 11 (EP-001 D-008) — title should be "RBAC (11 Roles)".
US-001-007BuiltBuilt(matches) — password reset + email + 30-min TTL + anti-enumeration generic 200 all shipped
US-001-010BuiltPartialThreshold mismatch — catalog/original review says "5-attempt", code + flow test use 20 (EP-001 D-010). Also: brute-force flow test is MODE=compose only, no live-env coverage (EP-001 D-011).
US-001-011PartialBuiltQA-PMS-6 invitation-token flow shipped (setup-password link 72-h TTL via shared password-reset:<token> Redis key). Catalog Partial is stale. Adjust the EP-001 catalog subtotal from "10 Built, 4 Partial, 2 Not Started" → "11 Built (less the 3 statuses now demoted to Partial above)".

Net change for the EP-001 onboarding subset: 3 demoted (US-001-004, US-001-006, US-001-010 from Built → Partial), 1 promoted (US-001-011 from Partial → Built), 3 unchanged.


EP-002 (all 14 stories)​

StoryLive status[SME-PROPOSED] statusReason
US-002-001BuiltBuilt(matches) — Property CRUD + GSTIN/PAN regex + lat/lng + business-date all shipped + 25 service tests
US-002-002BuiltBuilt(matches) — Room type CRUD + duplicate + 43 tests across service/controller/DTO. Amenity-taxonomy gap (EP-002 D-004) is a story-incomplete drift, not a status drift.
US-002-003BuiltBuilt(matches) — Rooms CRUD + bulk + 32 tests. Bed-map endpoints orphaned (EP-002 D-005) is a story-incomplete drift, not a status drift.
US-002-004BuiltBuilt(matches) — PATCH /rooms/:id/status + RoomStatusLog + cascade from 3 services. Missing central state-machine guard (EP-002 D-006) is a deferred hardening, not a status drift.
US-002-005BuiltBuilt(matches) — Rate plan CRUD + 14 controller tests + tenant-guard spec. GST-inclusive vs exclusive gap (EP-002 D-008) is story-incomplete, not status drift.
US-002-006BuiltBuilt(matches) — Cancellation policies + Zod v4 typed rules validator + 14 tests. Refund SLA gap (EP-002 D-010) is story-incomplete, not status drift.
US-002-007PartialPartial(matches) — Seasons CRUD shipped (review-file "NOT_IMPLEMENTED" is stale per EP-002 D-011); full dynamic-pricing loop still incomplete; forecast-sidecar + revenue-strategy boundary undocumented (EP-002 D-013)
US-002-008PartialPartial(matches) — 3 importers shipped (eZee/Hotelogix/Opera); IDS Next missing; chunked upload + BullMQ + WebSocket progress deferred; no flow test
US-002-009PartialPartial(matches) — Saga shipped (auth-service orchestrator + property-service seed); frontend 4-step vs spec 7-step; seed-defaults wiring incomplete
US-002-010BuiltBuilt-UntestedCode exists (isSmoking + features[] fields on DTOs) but no dedicated assertions — covered only implicitly via rooms.service.spec.ts 18-test suite. "Connecting" has no connectingRoomId linkage; "Accessible" is a single boolean rather than RPwD-aligned taxonomy.
US-002-011BuiltStubRe-uses PATCH /rooms/:id/status; no dedicated RoomBlock entity, no expected-return-date, no work-order linkage to hmp-asset-service, no auto-clear, no actor-role restriction (EP-002 D-014). Calling this "Built" misleads operators planning a maintenance project.
US-002-012Not StartedNot Started(matches) — no code, no tests, no UI; story-vs-reality matches honestly
US-002-013PartialPartial(matches) — Room.building free-text field + filter only; no dedicated Building entity with address/GPS/floor-count
US-002-014BuiltBuilt(matches) — assets.controller upload-URL + register-image + 9 service specs + 13 widget specs; ordering persistence is a story-incomplete drift, not status drift

Net change for EP-002: 2 status changes (US-002-010 Built → Built-Untested; US-002-011 Built → Stub). 12 unchanged.

Catalog subtotal impact: live row "9 Built, 4 Partial, 1 Not Started" → proposed "7 Built, 1 Built-Untested, 4 Partial, 1 Stub, 1 Not Started".


Proposed new stories (from drift findings)​

These 5 stories close gaps surfaced in BF-001 reconciliation: code exists in production, but no US-NNN-NNN row in the catalog. Each is paired with a NEW use-case sidecar in ./use-case-proposals/ (Task 7).

Proposed IDTitleReasonDrift link
US-001-017Tenant Self-Service SignupAdmin-portal signup flow exists (AP-T01-004 — admin-portal POST /tenants/signup + admin pre-verified row), but no US-001-NEW-SIGNUP row in catalog. BF-001 Step 1 / Step 2 gap. Closes via NEW UC: uc-tenant-signup-SME-PROPOSED.yaml.BF-001 Step 1/2 catalog gap
US-001-018Email Verification Landing PageAP-T01-003 (W3.E.7) shipped 2026-05-08 — /auth/verify-email?token=… landing page + auth-service POST /auth/verify-email endpoint, but no story row. Without a story, future regressions to the landing-page UX have no test contract to break.BF-001 Step 2 catalog gap → uc-email-verification-landing-SME-PROPOSED.yaml
US-002-015GST/Tax ConfigurationAP-T02-005 shipped — TaxConfiguration entity + CGST/SGST/IGST split + per-state slab table + inclusive/exclusive flag + dashboard /settings/taxes page, but no US-002-NNN row. This is the most error-prone pricing surface in Indian hospitality (EP-002 D-008 references it).BF-001 D-005 → uc-gst-tax-configuration-SME-PROPOSED.yaml
US-002-016Booking Engine Branding (suggest move to EP-011)PATCH /properties/:id/theme shipped (KeyNova 9-preset theme system + per-host-mapping override), but no story. Branding is fundamentally a booking-engine concern — recommend authoring under EP-011 (Booking Engine) not EP-002. The PATCH endpoint stays on property-service as the persistence layer.BF-001 D-005 → uc-booking-engine-branding-SME-PROPOSED.yaml
US-002-017Onboarding Wizard State API4-step dashboard wizard UI exists (setup-wizard/page.tsx), but the per-tenant wizard-state persistence is undocumented in catalog. Auth-service saga + property-service PATCH /:id/onboarding exists, but the contract between dashboard step-progress and backend state is not represented as a story. Without it, the 4-step vs spec-7-step compression (EP-002 D referenced in US-002-009 ACs) has no migration story.BF-001 Step 14 catalog gap → uc-onboarding-wizard-state-SME-PROPOSED.yaml

Note on naming: the proposed IDs US-001-017, US-001-018, US-002-015, US-002-016, US-002-017 continue the live catalog sequences. The live EP-001 ends at US-001-016 and EP-002 ends at US-002-014. If the operator merges US-002-016 into EP-011 instead, renumber to the next free US-011-017 (live EP-011 ends at US-011-016) and update the use-case sidecar's story_id accordingly.


Acceptance flow for the operator​

  1. Read this sidecar end-to-end.
  2. For each row in the EP-001 + EP-002 tables: accept, reject, or amend. Annotate decisions in this file inline before merge.
  3. For each proposed new story: accept, reject, or move to a different EPIC. If accepted, the matching ./use-case-proposals/uc-*-SME-PROPOSED.yaml file must be promoted in lockstep (Task 7).
  4. Merge accepted changes into ../01-epic-catalog.md — update the per-EPIC tables, the subtotal rows, and the Grand Summary Stories Built / Partial / Not Started counts.
  5. Add the 2 new status values (Built-Untested, Stub) to the legend at the top of ../01-epic-catalog.md.
  6. Delete this sidecar.