Skip to content

Decisions

Architectural Decision Records (ADRs). Append-only — decisions don't get rewritten when reversed; a new ADR supersedes an old one.

Format

Files are numbered: NNN-kebab-case-title.md. Each ADR captures: context, decision, consequences. See adr/SKILL for the template.

Index

Use file listing for the canonical index. Recent decisions:

  • 001-test-db-local-postgres-fallback.md — local Postgres for tests instead of Docker Supabase
  • 006-permission-system-redesign.md — see features/permission-redesign/plan.md
  • 008-payment-record-architecture.md — see features/payment-record-architecture/spec.md
  • 017-platform-v2-substrate-only.md — land deps + ESM, defer framework, cancel Phases 2–6
  • 018-own-subscription-default-payment-method.md — drop Stripe on_subscription writeback; set the sub default ourselves so the member's chosen PM is what charges
  • 019-api-pattern-alignment.md — pragmatic in-place API convergence; keep envelope, offset+totals, no URL versioning, problem+json deferred; forward-and-at-seams only, no bulk migration; supersedes 014
  • 020-unified-auth-optional-checkout.md — collapse the dual-URL lockout checkout (public no-login vs authed ?s=) into one auth-optional, auth-aware surface via progressive enhancement; auth is a runtime property, not a routing fork; supersedes the #822 split
  • 021-access-gate-hardware-consolidation.md — access gate / lock device / kit asset / assignment are mostly one door shown four ways; asset-first lifecycle (a lock enters as an ACCESS_GATE_KIT asset), deviceId sourced from the assigned kit instead of a free string, gate detail as the single home with single-row DetailTables for hardware + live status, no standalone Locks list (reconciliation job instead); entities stay separate, no table merge; direction accepted, implementation deferred
  • 022-phone-native-login-recovery.md — phone becomes a Supabase-native login + recovery factor (not a self-managed Twilio Verify attribute); GoTrue enforces phone uniqueness (drop the app-level index), linkIdentity() consolidates OAuth providers; recycling out of scope; supersedes account-dedup-merge spec Decisions 1 & 5
  • 023-checkout-intent-creation-timing.md — keep early server-side PaymentIntent minting for now, with its compensation tax (reuse guards, cancel-first ordering, abandoned-checkout sweep); the checkout rebuild MUST re-evaluate with deferred intent creation (create+confirm at pay-click) as the default candidate — it makes the stale-intent bug class unrepresentable
  • 024-guest-phone-possession-verification.md — possession proof for unauthenticated flows is API-owned (direct Twilio Verify, phone_verifications table, per-transaction consumption) and never touches ADR-022's identity storage; per-phone redemption uniqueness is the actual fraud control; account existence revealed only post-possession; paid guest flows get no OTP; see features/guest-phone-verification/spec.md
  • 025-platform-subledger.md — written money_events subledger at the movement chokepoint, reconciled against stripe.* mirrors; cash movements only (accrual is derived downstream); one shared classification vocabulary with the bookkeeping layer; build sequenced after the reserve-gate enforce flip and funding deployment; see features/platform-subledger/spec.md
  • 026-promo-credits-location-borne.md — promo-origin credit redemptions produce no location transfer (location-borne marketing, same economics as free-first-practice); purchased-origin keeps the ~90c/credit payout; origin per consumed balance via creditPackageId/subscription_deposit_amount; promo reserve leaves the platform's books; see features/promo-credits-location-borne/spec.md
  • 027-service-period-revenue-recognition.md — accountants close on service period; recognition is a derived bookkeeping lens (never stored postings, per 025): deposits and credit purchases defer at receipt and recognize at redemption or expiry breakage (12mo/18mo); reversals are dated contra events, closed periods never restate; revenue and settlement views split; see features/service-period-recognition/spec.md
  • 028-no-money-movement-free-hourly.md — final ruling after a same-day reversal cycle: NO money movement on any free hourly booking (comps, tours, dedicated); reaffirms 026 (promo-origin redemption steps pay $0, purchased keeps ~90c) and documents the withdrawn pay-at-redemption interlude; grandfathered payouts stay; no top-up cadence; impl = PR #917 (reopened); see features/promo-credits-location-borne/spec.md

(Add to the bottom when shipping a new ADR.)