docs(backend): harvest platform mechanisms into the contracts (Wave 2, FH-E.1-E.4)
Writes the 14 harvested mechanisms from FORK-ANALYSIS-2026-08-21.md into
the backend contracts. Each section is dated 2026-08-21 and tagged FH-*
so any wording traces back to why it is worded that way.
The through-line: several contracts stated correctness as behaviour
("the webhook must be idempotent"). Behaviour written as an if-statement
gets deleted by a refactor and the failure mode is a double charge. These
sections restate it as schema and mechanism.
PHASE-3 3.1 conditional-write reservation, 409 on zero rows, cart-wide
rollback, 15 min TTL
3.2 InventoryMovement append-only journal with resultingAvailable
6 bulk import idempotent by SKU, rollback while unsold
6a digital code pools, revealed only when paid
PHASE-7 5 unique constraints for payment idempotency and webhook
replay, insert-first handling, signature over raw body,
24h poll as reconciliation not primary
TRACK-S 2.1 session model - 32 bytes stored as SHA-256 only, HttpOnly,
one cookie per contour, Argon2id params, mandatory TOTP
2.2 origin allowlist ahead of routing on every cookie mutation
4.2 AES-256-GCM envelope for stored secrets, HMAC fingerprints
8a order manager as a separate contour, scoped by membership
rows rather than by configuration
PHASE-9 5.1 revision immutability, version = max+1, pointer flipped
in-transaction, operational state does not travel
5.2 clone carry / no-carry list, inventory to zero
5.3 signed read-only preview, non-GET 404s while previewing
6 host normalization, verifiedAt required, cache invalidation
PHASE-10 3a server re-runs the editor's validation, clamp-and-fallback
PHASE-2 3.1 order publicToken, snapshot completeness, never updated
FH-2.12 rejected on the merits: our marketplace lifecycle state machine
is richer than theirs, adopting it would be a downgrade. Recorded in the
TODO so it is not raised again.
Also adds BACKEND-HANDOFF.md sections 0 and 0a - nine falsifiable
invariants as a release gate, each cross-referenced to the contract that
specifies it, plus PR and release discipline. And ADR-0006 recording what
we take, what we reject, what we keep because ours is better, and the
organizational question it deliberately does not settle.
No implementation changes.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -2,10 +2,38 @@
|
||||
|
||||
Single entry point for a backend developer picking this up cold. Written 2026-08-18.
|
||||
|
||||
## 0. Invariants — the acceptance gate
|
||||
|
||||
Added 2026-08-21 (FH-E.1). Nine statements. Each is falsifiable, each has a test, and a release that violates any of them does not ship regardless of what else is finished. They come before the contracts because a contract can be read selectively and these cannot.
|
||||
|
||||
1. The public tenant is determined by verified `Host` alone. No public endpoint accepts a `marketplaceId` from the browser.
|
||||
2. The price of an order is computed by the backend. A price arriving in a request is ignored, never validated-and-used.
|
||||
3. Stock and reservation change atomically. Two buyers racing for the last unit produce one payable order.
|
||||
4. Payment creation and webhook receipt are idempotent, enforced by unique constraints rather than by handler logic.
|
||||
5. Provider credentials never leave the backend — not in a response, not in a bundle, not in a log.
|
||||
6. A published revision is immutable. Rollback creates a new revision; history is never rewritten.
|
||||
7. Rolling back design does not roll back live inventory, orders, or payments.
|
||||
8. No user reads a marketplace they are not assigned to — through the UI or through a direct API call.
|
||||
9. Every administrative mutation leaves an audit record naming actor, action, before and after.
|
||||
|
||||
Where each is specified: 1 and 6–7 in [Phase 9](PHASE-9-TENANT-REGISTRY-DOMAINS-CONTRACT.md) §5–6; 2 in [Phase 1](PHASE-1-MONEY-FX-PAYMENTS-CONTRACT.md) §5; 3 in [Phase 3](PHASE-3-CATALOG-OFFER-FULFILLMENT-CONTRACT.md) §3.1; 4 in [Phase 7](PHASE-7-PAYMENTS-RECONCILIATION-CONTRACT.md) §5; 5, 8 and 9 in [Track S](TRACK-S-SECURITY-RBAC-CONTRACT.md) §2, §3, §4.2.
|
||||
|
||||
## 0a. How work lands
|
||||
|
||||
Added 2026-08-21 (FH-E.2, FH-E.3).
|
||||
|
||||
**One functional area per pull request.** A PR carries: what it does, screenshots where there is UI, API changes, migrations, test evidence, security impact, and a rollback plan. Never change a payment, inventory, or order state machine in the same PR as a redesign — those two things fail differently and must be revertable separately.
|
||||
|
||||
**Migrations are expand/contract.** A migration and the frontend change that depends on it belong to one release train, but they may be separate PRs, and the expand step must be deployable on its own.
|
||||
|
||||
**A release is not "the build passed."** Each one records: version, migrations applied, healthcheck result, post-deploy smoke result, production dependency audit, and the rollback path actually available. A local build succeeding and a UI existing are not evidence of production readiness — the deploy and the smoke check are.
|
||||
|
||||
## 1. What this is
|
||||
|
||||
`marketplaces` is a multi-tenant marketplace platform frontend (Angular 22). The frontend is built and waiting; **there is no backend yet**. Every wire contract the backend needs to implement is already written and sitting in this directory — see [README.md](README.md) for the full index and build order.
|
||||
|
||||
Contract sections dated 2026-08-21 and tagged `FH-*` come from [FORK-ANALYSIS-2026-08-21.md](../FORK-ANALYSIS-2026-08-21.md) — a review of a parallel platform implementation that has a working backend. They are mechanisms that implementation already proved, harvested deliberately; the tag is there so you can trace any one of them back to why it is worded the way it is.
|
||||
|
||||
## 1a. Multi-tenancy — the thing that shapes every endpoint
|
||||
|
||||
The final executable infrastructure/backend contract is
|
||||
|
||||
Reference in New Issue
Block a user