spec(§2): solution proposal — carry forward prototype shape, invert seed/gate, defer GraphQL+OAuth

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-06-10 07:03:57 -07:00
parent a68f59ac85
commit 7147e740a1
@@ -237,7 +237,61 @@ Scenario: BUC-5a — Bring-up is rehearsable
## 2. Solution Proposal
<!-- §2 pending -->
**Build the first vertical slice of the ecomm web application** — a
multi-tenant modular monolith that carries forward the prototype's *proven*
shape and inverts its *disqualifying* assumption:
- **Carry forward** (validated by R01R07 of the prototype): a four-layer
Python backend (`entrypoint → api → domains → platform`) with the layer
contract mechanically enforced; SQLite (WAL) with forward-only numbered
migrations and no ORM; a React/Vite SPA admin talking to a screen-shaped
REST BFF; scenario-bound end-to-end tests (one test per BDD scenario ID);
OHM concepts cited inline next to the rules they ground.
- **Invert** (the prototype's bootstrap was the wrong way round for a real
product): **no seeded tenant and no admission gate.** The prototype was born
with one hard-coded store and one invited owner; ecomm is born *empty*.
Identity is open sign-up via **email + one-time code** (passwordless;
corpus 14.01.00030004), the storefront is created *through the product* by
its merchant, and an empty database is a first-class, fully working state —
which is precisely what makes BUC-5's bootstrap story true by construction
rather than by tooling.
- **Defer** (YAGNI for four screens): the prototype's second API surface
(GraphQL) is not built in this MVP; the layering keeps the seam so it can be
added later as a projection over the same domain core. Google/Apple OAuth
and sign-in-by-emailed-link (corpus 14.01.00050007) are deferred the same
way — the email-canonical identity rule (14.01.0010) keeps them addable
without account migration.
**Why this approach** over the alternatives:
- *Do nothing / concierge* (hand-create merchants on request): fails BUC-5
outright (every merchant is hand-seeded state) and validates nothing — the
prototype already validated the need; the open question is productionizing.
- *Re-architect on a heavier stack* (Postgres, separate services, SSR
framework): buys scale and rendering properties the MVP measurably does not
need, at the cost of slower iteration and a bigger bootstrap surface —
directly against the "launching anywhere is routine" outcome (§1.6). The
single-VM flotilla deployment standard (handbook §8) favors the lighter
stack; revisit at real scale (§6.7, §7.4).
- *Resume the prototype codebase*: it bakes in the seeded-tenant and
invite-gate assumptions at the foundation, and the rebuild exists precisely
to lay clean foundations. Its *patterns* are kept; its code is reference
only.
**Solution-specific scope:** the landing page, sign-up/log-in (email +
one-time code), create-storefront (both entry points: post-sign-up and
returning-without-storefront), the empty admin shell, sign-out, and the
bring-up story for localhost/PPE/Prod including real email delivery in
deployed environments.
**Solution-specific non-goals (this release):** GraphQL surface; OAuth
providers and magic-link completion; the onboarding questionnaire and POS
opt-in from the corpus first-run flow (14.01.00170024) — the merchant lands
directly on their admin; storefront rename/settings (14.01.0025 makes naming
optional at creation; *changing* it later is the Settings Feature's job);
account-lifecycle polish beyond what passwordless entry gives for free
(password reset does not exist because passwords do not exist; the one-time
code *is* email verification; account deletion is deferred and logged in §9).
---