docs: Track A/S contracts + backend index tying the full v3.1 contract set together
Some checks failed
Architecture Governance / architecture (push) Has been cancelled
Some checks failed
Architecture Governance / architecture (push) Has been cancelled
- Track A: analytics event pipeline (traffic/catalog/commerce/operational/ quality events), synthetic-traffic separation enforced server-side by environment/token, never a client-settable flag. - Track S: 17-role/3-scope RBAC enforcement, audit log, secrets, rate limiting, step-up auth - closes this session's most serious finding (admin role model is decorative today, any authenticated admin has full access regardless of assigned role). - docs/backend/README.md: index of all 12 contract docs (Phases 1-10 + 2 tracks) in build order, plus what's deliberately excluded (namespace migration, per-connector adapters, extra payment providers) and the one thing still genuinely open across all of them - backend ownership. - Cross-linked from BACKEND-API-REFERENCE.md and the delivery plan so the index is discoverable from either entry point. This closes out documentation for every phase/track in PRODUCT-PLAN-v3.1-DELIVERY-PLAN.md that doesn't require a further business decision. Nothing left undocumented on our side pending only implementation and backend-ownership assignment. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
One document, everyone reads it: product, backend, frontend, QA. It answers three questions for every domain — **what does the frontend already call**, **what shape does it send/expect**, and **is it real or mocked today**. Generated from the actual Angular frontend source (this repo has no backend code — it is a pure client consuming an external API), cross-checked against the frontend's own tolerant adapters, not aspirational.
|
One document, everyone reads it: product, backend, frontend, QA. It answers three questions for every domain — **what does the frontend already call**, **what shape does it send/expect**, and **is it real or mocked today**. Generated from the actual Angular frontend source (this repo has no backend code — it is a pure client consuming an external API), cross-checked against the frontend's own tolerant adapters, not aspirational.
|
||||||
|
|
||||||
|
**For what doesn't exist yet:** this doc describes the live surface only. The full set of forward-looking wire contracts for Product Plan v3.1 (money/FX, orders, catalog/offer split, connectors, seller portal, identity, tenant registry, RBAC, analytics — 10 phases + 2 tracks) lives in [docs/backend/](docs/backend/README.md).
|
||||||
|
|
||||||
Maturity tags used throughout:
|
Maturity tags used throughout:
|
||||||
|
|
||||||
| Tag | Meaning |
|
| Tag | Meaning |
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Product Plan v3.1 — Delivery Plan (Phases → Sprints → Todos)
|
# Product Plan v3.1 — Delivery Plan (Phases → Sprints → Todos)
|
||||||
|
|
||||||
Companion to [PRODUCT-PLAN-v3.1-GAP-ANALYSIS.md](PRODUCT-PLAN-v3.1-GAP-ANALYSIS.md). Every gap identified there is assigned here exactly once.
|
Companion to [PRODUCT-PLAN-v3.1-GAP-ANALYSIS.md](PRODUCT-PLAN-v3.1-GAP-ANALYSIS.md). Every gap identified there is assigned here exactly once. Wire contracts for every `[BE]`/`[BOTH]` phase and track below are written up in [docs/backend/](backend/README.md) — hand that directory to whoever builds the backend.
|
||||||
|
|
||||||
**No calendar dates.** The plan itself (§12) refuses invented dates and fixes *sequence + exit criteria* instead. This document does the same. Sprints are ordered units of work, not two-week promises. Sizes are relative: **S** / **M** / **L** / **XL**.
|
**No calendar dates.** The plan itself (§12) refuses invented dates and fixes *sequence + exit criteria* instead. This document does the same. Sprints are ordered units of work, not two-week promises. Sizes are relative: **S** / **M** / **L** / **XL**.
|
||||||
|
|
||||||
|
|||||||
42
docs/backend/README.md
Normal file
42
docs/backend/README.md
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
# Backend Contracts Index — Product Plan v3.1
|
||||||
|
|
||||||
|
This directory is the complete set of wire contracts for building the backend behind [Product Plan v3.1](../PRODUCT-PLAN-v3.1-GAP-ANALYSIS.md). Each doc specifies entities, endpoints, and invariants only — never DB schema or service boundaries, which stay backend's own call.
|
||||||
|
|
||||||
|
**Read order matches build order.** Every doc after Phase 1 depends on the ones before it (noted at the top of each). All Sprint 0.1 decisions referenced throughout were answered 2026-08-17 — see [PRODUCT-PLAN-v3.1-DELIVERY-PLAN.md](../PRODUCT-PLAN-v3.1-DELIVERY-PLAN.md) Sprint 0.1 for the full record.
|
||||||
|
|
||||||
|
## Launch-gate phases (P0 — required before production)
|
||||||
|
|
||||||
|
| Doc | Covers | Status |
|
||||||
|
|---|---|---|
|
||||||
|
| [PHASE-1-MONEY-FX-PAYMENTS-CONTRACT.md](PHASE-1-MONEY-FX-PAYMENTS-CONTRACT.md) | Money model, FX quote, price snapshot, server-authoritative checkout amount, payment state machine | Ready |
|
||||||
|
| [PHASE-2-ORDERS-NOTIFICATIONS-CONTRACT.md](PHASE-2-ORDERS-NOTIFICATIONS-CONTRACT.md) | Canonical Order/OrderLine/Fulfillment (unified multi-seller), event bus, Notification Center | Ready |
|
||||||
|
| [PHASE-3-CATALOG-OFFER-FULFILLMENT-CONTRACT.md](PHASE-3-CATALOG-OFFER-FULFILLMENT-CONTRACT.md) | Product/Offer split, inventory/reservations, publish-time executability | Ready |
|
||||||
|
| [PHASE-4-CONNECTOR-FRAMEWORK-CONTRACT.md](PHASE-4-CONNECTOR-FRAMEWORK-CONTRACT.md) | Generic external-order connector framework (no fixed marketplace list) | Ready |
|
||||||
|
|
||||||
|
## Post-launch-gate phases (P1/P2)
|
||||||
|
|
||||||
|
| Doc | Covers | Status |
|
||||||
|
|---|---|---|
|
||||||
|
| [PHASE-5-SELLER-PORTAL-CONTRACT.md](PHASE-5-SELLER-PORTAL-CONTRACT.md) | Seller org/user/membership, seller-scoped order/fulfillment views | Ready |
|
||||||
|
| [PHASE-6-CART-CHECKOUT-CONTRACT.md](PHASE-6-CART-CHECKOUT-CONTRACT.md) | Server-owned cart, checkout session | Ready |
|
||||||
|
| [PHASE-7-PAYMENTS-RECONCILIATION-CONTRACT.md](PHASE-7-PAYMENTS-RECONCILIATION-CONTRACT.md) | Refunds, reconciliation, settlements | Ready |
|
||||||
|
| [PHASE-8-IDENTITY-MESSAGING-CONTRACT.md](PHASE-8-IDENTITY-MESSAGING-CONTRACT.md) | Customer identity, VK ID (built first), OTP, MAX/Telegram bots, Notification Orchestrator | Ready |
|
||||||
|
| [PHASE-9-TENANT-REGISTRY-DOMAINS-CONTRACT.md](PHASE-9-TENANT-REGISTRY-DOMAINS-CONTRACT.md) | Marketplace registry, Hostinger DNS automation, publish/revision model | Ready |
|
||||||
|
| [PHASE-10-CONTENT-MODULES-CONTRACT.md](PHASE-10-CONTENT-MODULES-CONTRACT.md) | Gorbushka-class mall/directory content entities | Ready, lowest priority |
|
||||||
|
|
||||||
|
## Cross-cutting tracks
|
||||||
|
|
||||||
|
| Doc | Covers | Status |
|
||||||
|
|---|---|---|
|
||||||
|
| [TRACK-A-ANALYTICS-CONTRACT.md](TRACK-A-ANALYTICS-CONTRACT.md) | Event pipeline, funnel, operational/quality metrics, synthetic-traffic separation | Ready — start alongside Phase 1, longest lead time |
|
||||||
|
| [TRACK-S-SECURITY-RBAC-CONTRACT.md](TRACK-S-SECURITY-RBAC-CONTRACT.md) | 17 roles/3 scopes, enforcement, audit log, secrets, rate limiting, step-up auth | Ready — gates the launch |
|
||||||
|
|
||||||
|
## What is deliberately not in this directory
|
||||||
|
|
||||||
|
- **API namespace migration** — Sprint 0.1 decision: new endpoints only use `/api/v2/...` etc; legacy endpoints (`/cart`, `/orders`, `/items`) are not being migrated as part of this contract set. See `BACKEND-API-REFERENCE.md` for the current live surface.
|
||||||
|
- **Per-connector adapters** (Ozon, Wildberries, etc.) — Sprint 0.1 decision: no fixed list. [Phase 4](PHASE-4-CONNECTOR-FRAMEWORK-CONTRACT.md) §8 is the onboarding runbook; each partner's adapter is written when that partner is actually onboarded.
|
||||||
|
- **Additional payment providers** (wallets, BNPL) — open business decision, not yet made. [Phase 7](PHASE-7-PAYMENTS-RECONCILIATION-CONTRACT.md) §4.
|
||||||
|
|
||||||
|
## One open item across all of these
|
||||||
|
|
||||||
|
**Backend ownership is still unanswered** (Sprint 0.1). Every contract above is ready to hand to whoever builds it — that person/team just hasn't been named yet.
|
||||||
89
docs/backend/TRACK-A-ANALYTICS-CONTRACT.md
Normal file
89
docs/backend/TRACK-A-ANALYTICS-CONTRACT.md
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
# Track A Backend Contract — Analytics Event Pipeline
|
||||||
|
|
||||||
|
Companion to [PRODUCT-PLAN-v3.1-DELIVERY-PLAN.md](../PRODUCT-PLAN-v3.1-DELIVERY-PLAN.md) Track A. Covers plan §3.1, §6.3, §13.3.
|
||||||
|
|
||||||
|
**Status: ready to build. Start alongside Phase 1, not last** — longest lead time in the programme, and it's a P0 in the plan's own §3.1. No tracking infrastructure exists at all today; this is missing infrastructure, not a missing endpoint.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Event logging spine
|
||||||
|
|
||||||
|
```ts
|
||||||
|
interface AnalyticsEvent {
|
||||||
|
eventType: string; // see §2-4 for the fixed vocabulary
|
||||||
|
marketplaceId: string;
|
||||||
|
sessionId: string;
|
||||||
|
customerId?: string;
|
||||||
|
timestamp: string;
|
||||||
|
properties: Record<string, unknown>;
|
||||||
|
isSynthetic: boolean; // see §6 - mandatory, never inferred
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
POST /api/v2/storefront/analytics/events { eventType, properties } -- server-side batched ingest
|
||||||
|
```
|
||||||
|
|
||||||
|
Frontend fires events client-side; backend is the source of truth for `sessionId` and `isSynthetic` — never trust a client-asserted synthetic flag without a matching signed staging/test-environment token.
|
||||||
|
|
||||||
|
## 2. Traffic events
|
||||||
|
|
||||||
|
```
|
||||||
|
session_started, page_view, product_view (with source/utm/referrer), unique users/sessions rollups
|
||||||
|
```
|
||||||
|
|
||||||
|
## 3. Catalog events
|
||||||
|
|
||||||
|
```
|
||||||
|
search, category_view, product_view, seller_view
|
||||||
|
```
|
||||||
|
|
||||||
|
## 4. Commerce events
|
||||||
|
|
||||||
|
```
|
||||||
|
add_to_cart, cart_view, checkout_started, payment_started, payment_success, payment_failed, order_created
|
||||||
|
```
|
||||||
|
|
||||||
|
These map directly onto the Phase 1/2/6 contracts' own state transitions — emit them from the same backend code paths that already produce `PaymentEvent`/`OrderEvent`, not a separately-maintained tracking layer that can drift.
|
||||||
|
|
||||||
|
## 5. Operational + quality metrics
|
||||||
|
|
||||||
|
```ts
|
||||||
|
interface OperationalMetric {
|
||||||
|
name: 'order_paid_to_notification_latency' | 'fulfillment_time' | 'connector_lag' | 'payment_webhook_lag';
|
||||||
|
marketplaceId: string;
|
||||||
|
value: number;
|
||||||
|
unit: 'seconds' | 'minutes';
|
||||||
|
measuredAt: string;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Quality events: frontend/backend errors, checkout validation failures, FX stale-rate blocks (Phase 1 §3.2).
|
||||||
|
|
||||||
|
## 6. Synthetic traffic separation (hard requirement, plan §3.1/§6.3/§10.2)
|
||||||
|
|
||||||
|
Synthetic/load-test traffic is permitted in staging and demo environments **only**, and must be technically inseparable-by-accident from production data — i.e. `isSynthetic: true` set server-side based on environment/token, never a client-settable flag that a real visit could accidentally or deliberately carry. Business reports must filter it out by construction, not by a manual exclusion query someone has to remember to add.
|
||||||
|
|
||||||
|
## 7. Endpoints
|
||||||
|
|
||||||
|
```
|
||||||
|
GET /api/admin/v2/analytics/funnel?marketplaceId=&period=
|
||||||
|
GET /api/admin/v2/analytics/operational?marketplaceId=&metric=
|
||||||
|
GET /api/admin/v2/analytics/quality?marketplaceId=
|
||||||
|
GET /api/v2/storefront/search/trending?marketplaceId= -- top N queries over a recent window, closes the existing SearchTrendingService.loadTrending() stub (returns of(null) today)
|
||||||
|
```
|
||||||
|
|
||||||
|
## 8. Post-launch monitoring set (plan §13.3, reuses the same event stream)
|
||||||
|
|
||||||
|
```
|
||||||
|
checkout_conversion, payment_success_failure_rate, webhook_processing_lag,
|
||||||
|
order_notification_lag, external_connector_lag, fx_quote_age_errors,
|
||||||
|
unmatched_reconciliation_count, fulfillment_stuck_count
|
||||||
|
```
|
||||||
|
|
||||||
|
## 9. What the frontend will start doing once this ships
|
||||||
|
|
||||||
|
- Replace the fully mock-composed `AdminAnalyticsFacade` with real funnel data.
|
||||||
|
- Fire the event vocabulary above from the relevant storefront interaction points.
|
||||||
|
- Bridge or replace the currently-always-zero `AdminProduct.visits` column with real tracking (see `GAPS-AND-IMPROVEMENTS.md`'s admin-product-views item — already partially speced in this session's [admin product views design](../superpowers/plans/2026-08-15-admin-product-views-column.md)).
|
||||||
|
- Wire `SearchTrendingService.loadTrending()` to the real endpoint in §7.
|
||||||
83
docs/backend/TRACK-S-SECURITY-RBAC-CONTRACT.md
Normal file
83
docs/backend/TRACK-S-SECURITY-RBAC-CONTRACT.md
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
# Track S Backend Contract — RBAC, Audit, Secrets, Rate Limiting
|
||||||
|
|
||||||
|
Companion to [PRODUCT-PLAN-v3.1-DELIVERY-PLAN.md](../PRODUCT-PLAN-v3.1-DELIVERY-PLAN.md) Track S. Covers plan §4.4, §10.
|
||||||
|
|
||||||
|
**Status: ready to build. Gates the launch — this is the single most serious security gap identified in this session's audit.** Today the admin role model is decorative: `AdminRole` and permissions exist as types, but nothing gates any button, page, or action anywhere in the app. Any authenticated admin has full access.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Roles (17 total, 3 scopes, per plan §4.4)
|
||||||
|
|
||||||
|
```ts
|
||||||
|
type PlatformRole = 'PLATFORM_OWNER' | 'TECH_ADMIN' | 'SECURITY_ADMIN' | 'DOMAIN_MANAGER' | 'VIEWER';
|
||||||
|
|
||||||
|
type MarketplaceRole =
|
||||||
|
| 'MARKETPLACE_ADMIN' | 'CONTENT_MANAGER' | 'CATALOG_MANAGER' | 'ORDER_MANAGER'
|
||||||
|
| 'FINANCE_MANAGER' | 'SUPPORT_MANAGER' | 'VIEWER';
|
||||||
|
|
||||||
|
type SellerRole =
|
||||||
|
| 'SELLER_OWNER' | 'SELLER_CATALOG_MANAGER' | 'SELLER_ORDER_MANAGER'
|
||||||
|
| 'SELLER_FINANCE_VIEWER' | 'SELLER_VIEWER';
|
||||||
|
```
|
||||||
|
|
||||||
|
`SellerRole` is already specified in [Phase 5's contract](PHASE-5-SELLER-PORTAL-CONTRACT.md) §4 — this doc adds the platform and marketplace scopes around it.
|
||||||
|
|
||||||
|
## 2. Enforcement (backend-side, non-negotiable)
|
||||||
|
|
||||||
|
Every `/api/admin/v2/*` and `/api/platform/v1/*` endpoint must check `(role, tenantScope)` against the acting user's session — **before** touching data, not as a post-hoc filter. `tenant scope` here means: a `MARKETPLACE_ADMIN` for marketplace A must get a `403` (not an empty result) querying marketplace B's data, never a silently-scoped response that looks like "there's just nothing here."
|
||||||
|
|
||||||
|
```
|
||||||
|
GET /api/identity/v1/session/permissions -> { role, scopes: string[], marketplaceIds: string[] }
|
||||||
|
```
|
||||||
|
|
||||||
|
Frontend route/action guards derive from this endpoint's response — never hardcode role logic client-side beyond hiding UI affordances (which is convenience, not security).
|
||||||
|
|
||||||
|
## 3. Audit log
|
||||||
|
|
||||||
|
```ts
|
||||||
|
interface AuditEvent {
|
||||||
|
id: string;
|
||||||
|
actor: string;
|
||||||
|
action: string; // e.g. 'role.changed', 'offer.price_updated', 'refund.approved'
|
||||||
|
entityType: string;
|
||||||
|
entityId: string;
|
||||||
|
before?: unknown;
|
||||||
|
after?: unknown;
|
||||||
|
reason?: string;
|
||||||
|
occurredAt: string;
|
||||||
|
ip?: string;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Mandatory coverage (plan §10.1): permission changes, seller status changes, catalog moderation actions, price changes, payment/refund actions, manual order overrides, integration credential changes, production launch actions.
|
||||||
|
|
||||||
|
```
|
||||||
|
GET /api/admin/v2/audit?marketplaceId=&entityType=&actor=&from=&to=
|
||||||
|
```
|
||||||
|
|
||||||
|
## 4. Secrets
|
||||||
|
|
||||||
|
All provider/connector credentials (payment providers, external marketplace connectors, VK/MAX/Telegram bot tokens, FX source keys) live in dedicated secret storage, referenced by opaque `credentialRef` strings in every other contract in this series — never returned in any API response body, never logged in plaintext.
|
||||||
|
|
||||||
|
## 5. Rate limiting
|
||||||
|
|
||||||
|
```
|
||||||
|
429 response: { error: { code: 'RATE_LIMITED', retryAfterSeconds: number } }
|
||||||
|
```
|
||||||
|
|
||||||
|
Applies to storefront/auth/provider endpoints. Frontend currently has **zero** 429 handling anywhere — see [BACKEND-API-REFERENCE.md §5](../../BACKEND-API-REFERENCE.md) for the full error-envelope contract this should follow.
|
||||||
|
|
||||||
|
## 6. Step-up authentication
|
||||||
|
|
||||||
|
Required before: bank/payment detail changes (Phase 5 §5), production launch (Phase 9 §3 step 8), role grants at `PLATFORM_OWNER`/`MARKETPLACE_ADMIN` level, and any manual financial override (refund approval outside normal flow, price override on a live order).
|
||||||
|
|
||||||
|
## 7. PII minimization
|
||||||
|
|
||||||
|
Customer/seller PII is exposed only to roles that need it for their scope (e.g. `FINANCE_VIEWER` sees payout totals, not raw bank account numbers unless `FINANCE_MANAGER`+). Export endpoints (`GET .../export`) are themselves audit-logged actions per §3.
|
||||||
|
|
||||||
|
## 8. What the frontend will start doing once this ships
|
||||||
|
|
||||||
|
- Route guards and action-level permission checks across the entire backoffice — currently none exist.
|
||||||
|
- Backoffice **Audit & Security** section (missing from admin nav today): role changes, sensitive actions, login/security events, exports.
|
||||||
|
- Reconcile `AdminRole` (already de-duplicated to one canonical type this session) against the real 17-role table from §1.
|
||||||
|
- 429 interceptor + retry-after UI.
|
||||||
Reference in New Issue
Block a user