Skip to content

Features

Canonical system design intent for the Metrognome codebase. Each feature is a folder containing the spec plus implementation plans, ralph prompts, research notes, and post-mortems. See ADR-016 for the source-of-truth chain (business > spec > code) and the spec/code coexistence rule. Spec/plan/prompt conventions: aaron-hogan/ralph.

When a spec disagrees with code, fix one of them — they never coexist contradicted. Authority chain: business > spec > code.

Layout per feature

features/<name>/
  spec.md          canonical design intent
  plan.md          implementation plan with **Status:** + checkboxes (ralph)
  prompt.md        ralph protocol for this divergence
  progress.txt     cross-iteration learnings (auto-grown)
  research.md      background, when needed
  runbook.md       ops procedure when applicable (e.g., burst-runbook for incidents)
  retro.md         post-mortem when applicable
  deploy-checklist.md   one-time deploy artifacts

Strict folder-always — every feature is a folder, even single-file ones.

Index

Feature Code Purpose Status
promo-credits-location-borne apps/api/src/services/scheduling/ReservationCreationService.ts, apps/api/src/services/payment/ReserveService.ts Promo-origin credit redemptions pay locations $0; purchased keeps ~90c; reserve + audits purchased-only (ADR-026, reaffirmed + extended by ADR-028 after a same-day reversal cycle) spec — impl PR #917 reopened
consolidate-lockout-side-effects apps/api/src/services/payment/{FulfillmentService,StripeWebhookService,SubscriptionCreateHandler}.ts, apps/api/src/services/scheduling/ReservationSideEffectService.ts One idempotent finalizeLockout(reservationId) reconciler for all lockout signup side effects — per-effect preconditions + claim ledger, sweep cron repairs dropped work spec · plan
stripe-webhook-ingress apps/api/src/app/api/stripe/webhooks/route.ts, apps/api/src/services/shared/WebhookEventService.ts Ingress/transport: signature verification, durable persistence, idempotency, claim/lease/retry, reconciliation initial (done) · hardening (done)
refactor-scheduler apps/web/src/components/organisms/scheduling/, apps/web/src/components/organisms/booking/, apps/web/src/hooks/scheduling/ cal.com-style slot picker + on-page /book surface replacing the accordion scheduler and booking modals spec · plan (in-progress)
posthog apps/web/src/lib/tracking.ts, apps/api/src/lib/analytics/, apps/web/src/app/providers.tsx Replace Umami with PostHog Cloud — funnels, session replay, identification in-progress
privacy-compliance apps/web/src/app/(marketing)/privacy/page.tsx, apps/web/src/lib/tracking.ts, apps/api/src/lib/meta/, apps/web/src/app/layout.tsx US-only privacy floor: accurate policy, opt-out propagated to Pixel + CAPI + Google Ads, GPC honoring, DSAR intake in-progress
bookkeeping analytics/scripts/*bookkeeping*, apps/api/prisma/migrations/*bookkeeping* Per-location LLC bookkeeping with penny-perfect Stripe reconciliation. Multi-layer pipeline feeding a 4-tab Metabase dashboard (Revenue, Money Movements, Transactions, Receivables), used directly by staff and CB Solutions (main accounting firm, all locations). A location-scoped parity variant (dashboard 34, MG4/5/6/8/9) serves COR Accounting, the smaller firm on that subset. shipped (dashboard.md)
service-period-recognition apps/api/prisma/migrations/*bookkeeping* (planned), analytics/scripts/*bookkeeping* ADR-027 accrual lens for the bookkeeping pipeline: three dates per ledger row, deposits/credits as deferred revenue recognizing at redemption or 12mo/18mo expiry breakage, execution-dated settlements tab, no retroactive mutation. Recognition mapping awaits accountant sign-off. spec · plan — ready to build; CB Solutions reviewing
payment-record-architecture apps/api/src/services/**/*Payment*.ts ADR-008 unified Payment model. Eliminates Stripe metadata dependencies, creates records at checkout not in webhooks. shipped (see deploy-checklist.md)
permission-redesign apps/api/src/utils/auth/role-check.ts ADR-006 permission redesign — role checks replace the permission grammar shipped (Mar 2026, #494/#497/#498)
token-exchange apps/api/src/app/api/auth/token-exchange/ (planned) Service-principal on-behalf-of token exchange — a confidential service acts as a staff user via a short-lived opaque delegated token. Foundation for the staff MCP. spec
sms (not started) SMS via Twilio for member notifications research
account-dedup-merge (not started) Verified-phone person-key: dedup at signup (Twilio Verify OTP) + staff account-merge tool. Fixes Apple-relay duplicate accounts. spec · research
stripe-data-pipeline (foundational for bookkeeping) ADR-007 Stripe data sync pipeline planning
studio-reference apps/web/src/app/(staff)/studios/ Staff studio reference page planning
staff-ui-redesign apps/web/src/app/(app)/staff/, apps/web/src/components/molecules/detail/, apps/web/src/components/organisms/{modals,sheets}/ Stripe-style read-only detail pages for the three highest-traffic staff entities (User, Resource, Reservation); edits via CrudModal, multi-pane/preview flows via TakeoverSheet; canonical Activity (audit-log) section, entity-bound row actions. Permanent coexistence with unmigrated pages. Engineering pattern in architecture/frontend/detail-pages.md. spec · design · planv1 shipped (#783/#788/#789); Resource + tour create flows outstanding
unified-cherry-city-lp apps/web/src/app/(landing)/lp/cherry-city/, apps/web/src/lib/tracking.ts, apps/api/src/lib/meta/ Replace dual /cherry-city/{tour,hourly} LPs with a unified /lp/cherry-city; pain-led hero, monthly/hourly fork, new LandingFunnelChoice Pixel + CAPI event for unified Meta optimization spec · done
cherry-city-ppc-prospecting (Meta Ads Manager — no code) Phase 1 Meta paid prospecting campaign driving the unified LP — Traffic objective, LPV optimization, awareness + retargeting-pool building. Companion to unified-cherry-city-lp. spec
market-landing-pages apps/web/src/app/(landing)/lp/[marketSlug]/, apps/web/src/components/organisms/marketing/, apps/api/prisma/schema.prisma (LocationGroup) Tour-driven /lp/[marketSlug] template (Salem first, Portland for free). Replaces /lp/cherry-city. Hero tour-form → direct TourSchedulerModal hand-off (no auth), locations-near-you (IP geo), 3-fork to /monthly /hourly /groups. spec · done
marketing-scorecard-attribution analytics.* (view + ad-spend/leads sync), apps/api/src/services/scheduling/ReservationCreationService.ts, apps/api/src/services/payment/{FulfillmentService,PaymentIntentHandler}.ts Make the cold-start scorecard one queryable analytics object and complete channel attribution lead→tour→move-in. Ad-data ETL + scorecard view + coarse CM tour lead-source/auto-match (the lever) + move-in coverage audit. Builds on #727. spec
lead-market-attribution apps/api/src/app/api/contact/route.ts, apps/api/src/services/contact/InquiryService.ts Resolve an inquiry's market to location_id from the already-collected city when it maps to exactly one active location (Salem and single-building metros), so front-of-funnel leads grid on the per-location scorecard. Page/explicit context only, no geo-IP. spec
align-waitlist-checkout apps/web/src/app/waitlist/invite/[id]/, apps/web/src/features/checkout/, apps/api/src/app/api/checkout/waitlist-invitation/[id]/route.ts Route the no-auth waitlist deposit (/waitlist/invite/[id]) through the shared CheckoutExperience; auth-aware saved payment methods (member case) via server-minted customer session; retire the dead /checkout/waitlist authed flow. plan
ai-workspace (Claude Cowork plugin library — separate mg-plugins repo, no code in this monorepo) Private library of Claude Cowork plugins shaped by the Metrognome org model — Platform services + Pillars + Universal layer. Plugins encode procedure (SOPs); Drive remains the human artifact surface. spec
make-music-salem-comp apps/api/src/services/scheduling/mms-comp.ts, apps/api/src/app/api/mms-comp/ Original MMS 2026 free rehearsal comp — hardcoded MMS_COMP.resourceIds allowlist + /api/mms-comp/* endpoint pair. One-off pattern; subsumed by comp-reservations primitive. Resources provisioned in prod via clone-from-source script. spec · shipped
comp-reservations apps/api/src/app/api/comp/reservations/, apps/api/src/app/api/comp/resources/, apps/web/src/app/(landing)/lp/[marketSlug]/ (comp hero), /lp/mms2026 (embedded modal) Offer-row-driven free-booking primitive. POST /api/comp/reservations + GET /api/comp/resources. Active offers: MMS_SALEM_2026 (Free Practice Week) + CHERRY_CITY_FIRST_PRACTICE (first 4 hours free, Salem). spec
free-first-practice apps/web/src/components/molecules/navigation/PromoButton.tsx, apps/api/src/app/api/promo/eligibility/[offerId]/, apps/api/src/app/api/offers/dashboard/, apps/web/src/app/(landing)/lp/[marketSlug]/ Replace the 50-free-credits trial promo with the CHERRY_CITY_FIRST_PRACTICE comp offer on all promo surfaces (header button, dashboard callout, /promo/free-credits 301), pointing at /lp/salem/free-first-practice. Market-LP hero integration shelved pending scheduler refactor. MG10 only. spec
guest-phone-verification apps/api/src/services/verification/PhoneVerificationService.ts, apps/api/src/app/api/phone-verification/, apps/web/src/components/molecules/booking/CompDetailsForm.tsx Prove an unauthenticated visitor controls a phone number (Twilio Verify OTP, transaction-scoped proof — not identity, see ADR-024) for requiresVerifiedPhone offers; drives the cross-identity PromoRedemption.phone redemption cap and post-possession account-exists routing to phone-OTP sign-in. First consumer: comp bookings. spec · planshipped, gate live (#882, #883; CHERRY_CITY_FIRST_PRACTICE)
refactor-mms-pages apps/web/src/app/(landing)/lp/mms2026/, apps/api/src/app/api/leads/green-room-registration/, apps/api/src/app/api/leads/giveaway-entry/, apps/api/src/templates/emails/GreenRoomConfirmationEmail.tsx MMS 2026 Artist HQ — LP restructured around Green Room + FPW pillars, Green Room registration endpoint + immediate email, Vedder giveaway kiosk endpoint (R-02 gated), 10 MMS source codes in ConversionAttribution. spec · kickoff
staff-mcp apps/staff-mcp/ (planned) Staff-ops MCP server — thin proxy over @mg/api; LLM-driven member operations on behalf of the signed-in staffer via token-exchange OBO. FastMCP-TS, homelab Docker + Cloudflare tunnel. spec
reservation-health apps/api/src/services/health/ (planned), apps/api/src/app/api/cron/reservation-health-*/ (planned) Continuous reservation-invariant engine — data complete, sub linked + healthy, billing/transfers correct, payments linked. Consolidates ~15 one-off audit scripts (reservation-validate-lockout is the prototype) into one engine run nightly across the fleet, alerting on violations. spec · plan
api-include-parent-mgids-in-response apps/api/src/app/api/reservations/, apps/api/src/app/api/payments/, apps/api/src/services/health/ API convention: any response exposing a flat entity's mgId (reservation, payment, etc.) also exposes its parent chain's mgIds, so consumers can render a locatable ref like MG11-SMO33 RSV592. Display layer joins; data layer supplies the parts. spec · plan
staff-invitations apps/web/src/components/organisms/{InvitationsTable.tsx,sheets/CreateLockoutSheet.tsx,sheets/CreateWaitlistSheet.tsx}, apps/api/src/app/api/checkout/session/ Unified staff invitations surface (lockout + waitlist over CheckoutInvitation) + the daily-use create flows as TakeoverSheet sheets; honest pending-payment status; waitlist data hygiene. Companion arc to staff-ui-redesign. planPhases 1–5 shipped (#807/#808/#814); Resource + tour create outstanding
waitlist-status-model apps/api/prisma/schema.prisma (WaitlistStatus), apps/web/src/app/(app)/staff/waitlist/ Replace conflated waitlist PENDING with honest INVITED/ACTIVE statuses + single-table staff UI; PROCESSING payment status. Builds on staff-invitations. planshipped (#810/#811/#814)
reservation-invited-status apps/api/prisma/schema.prisma (ReservationStatus), apps/web/src/app/(app)/staff/reservations/ Reservations gain INVITED — a lockout invitation creates a real reservation that holds the studio and expires in 7 days (staff notified). Reservation analogue of the waitlist status model. planPhases 1–3 shipped (#815, expiry notice #834); backlog open
sent-email-log apps/api/src/services/email/EmailService.ts, apps/api/src/app/api/emails/, apps/web/src/app/(app)/staff/ (detail-page email tables) EmailService.dispatch logs every sent/failed email; read-only staff email log surfaced on detail pages (GET /api/emails). Shipped as a staff-ui-redesign adjunct. specv1 shipped (#789/#798); webhooks/retention (phase 4) deferred
account-activity-timeline (planned) apps/api/src/app/api/users/[id]/activity/ Unify the User detail page's Payments + Transactions tables into one server-paginated "Account activity" feed. Carried-forward deferral from the staff-ui-redesign User page. spec — deferred / not built
public-lockout-checkout apps/web/src/app/checkout/lockout-invitation/[id]/ Public no-login lockout checkout (on-demand sub) + routing-by-account-state (stub → public page, set-up user → authed /checkout/reservation). specshipped (#822)
unified-checkout apps/web/src/features/checkout/ ADR-020 unified auth-optional checkout surface — one CheckoutExperience for authed and public flows. planshipped (#829)