docs(backend): consolidate all backend contracts into one file
Some checks failed
Architecture Governance / architecture (push) Has been cancelled

Collapses the entire docs/backend/ set - Phase 1-10, Track A/S, the
partner API, the two handoffs, the frontend surface inventory, and the
harvest requirements - into a single source of truth,
docs/backend/BACKEND-INTEGRATION.md.

Every contract's entities, endpoints, and invariants are preserved,
reorganised by domain rather than by sprint. The nine release
invariants, the FH-* harvest mechanisms, the RBAC/audit/secrets
cross-cutting rules, the tenant-routing infra contract, the 15
acceptance tests, build order, dev setup, and open decisions are all in
the one file, with a change log (§14) at the bottom.

The file opens with the maintenance rule: any new backend need, contract
change, or shipped item updates this file in the same change - the
affected section and the change log. No new backend .md files.

Inbound links from BACKEND-API-REFERENCE, the ADRs, the fork docs,
DEPLOYMENT, PACKAGES-USAGE, the delivery plan, and e2e/README are
repointed at the single doc (section anchors collapse to the file; the
prose section refs remain as context). Also recorded the rule in the
repo CLAUDE.md.

17 backend docs removed, 1 added. No implementation changes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
sdarbinyan
2026-08-22 16:15:58 +04:00
parent 52fb52888f
commit d44565fae9
29 changed files with 522 additions and 3146 deletions

View File

@@ -189,11 +189,11 @@ That list is our leverage. It is also a precise statement of which of our module
### P0 — take these regardless of how the org question resolves
1. **Conditional-UPDATE stock reservation.** Adopt the pattern verbatim in `docs/backend/PHASE-6-CART-CHECKOUT-CONTRACT.md`: reserve via `WHERE (onHand - reserved) >= qty RETURNING id`, empty result = 409. It removes a whole class of race conditions and it is one line of SQL.
2. **Idempotency as a unique constraint, not application logic.** `Payment.idempotencyKey UNIQUE`, `PaymentWebhookEvent @@unique([provider, eventKey])`, P2002 → `{duplicate: true}`. Push this into `PHASE-7-PAYMENTS-RECONCILIATION-CONTRACT.md` as a schema requirement, not a behavioural note.
1. **Conditional-UPDATE stock reservation.** Adopt the pattern verbatim in `backend/BACKEND-INTEGRATION.md`: reserve via `WHERE (onHand - reserved) >= qty RETURNING id`, empty result = 409. It removes a whole class of race conditions and it is one line of SQL.
2. **Idempotency as a unique constraint, not application logic.** `Payment.idempotencyKey UNIQUE`, `PaymentWebhookEvent @@unique([provider, eventKey])`, P2002 → `{duplicate: true}`. Push this into `backend/BACKEND-INTEGRATION.md` as a schema requirement, not a behavioural note.
3. **Move every credential out of the browser.** Their audit is right about `authorization-key` / `userid-value` / partner ID. Mirror `PaymentCredential.encryptedConfig` (AES-256-GCM, versioned `v1.iv.tag.ct`) in our contract and delete the client-side header path.
4. **HttpOnly server sessions, separate cookie per contour** (`bo_session`, `manager_session`, `marketplace_session`). Kill the JS-set cookie and the shared Telegram session for admin + customer. This is our single worst finding in their audit.
5. **Origin allowlist hook for all admin mutations.** Twelve lines in `main.ts`; kills CSRF for cookie-authenticated mutations. Mirror in `TRACK-S-SECURITY-RBAC-CONTRACT.md`.
5. **Origin allowlist hook for all admin mutations.** Twelve lines in `main.ts`; kills CSRF for cookie-authenticated mutations. Mirror in `backend/BACKEND-INTEGRATION.md`.
6. **Backend-side config validation.** Our validation engine is better than theirs, but it runs in the browser. The server must re-run it. Their clamp-and-fallback ergonomics are right: never reject a colour, clamp it; never accept a non-https URL, blank it.
### P1 — take into our own architecture
@@ -250,7 +250,7 @@ So there is nothing to copy from them here. But their **session-issuing half is
| [vk-id-gateway.token.ts](src/app/core/identity/services/vk-id-gateway.token.ts) | DI seam via `environment.useMockData` |
| [vk-id-login.component.ts](src/app/components/vk-id-login/vk-id-login.component.ts) | Button component |
| [customer-identity.model.ts](src/app/core/identity/models/customer-identity.model.ts) | `ExternalIdentityProvider = 'vk_id' \| 'telegram' \| 'max'` |
| [PHASE-8-IDENTITY-MESSAGING-CONTRACT.md](docs/backend/PHASE-8-IDENTITY-MESSAGING-CONTRACT.md) | §2 defines the VK ID contract |
| [backend/BACKEND-INTEGRATION.md](backend/BACKEND-INTEGRATION.md) | §2 defines the VK ID contract |
We have the scaffolding and the contract. Yandex is absent everywhere except one mention of *Yandex Market* as a possible marketplace connector in the gap analysis — a different thing entirely.