diff --git a/BACKEND-API-REFERENCE.md b/BACKEND-API-REFERENCE.md index 9a74ccf..7bfda30 100644 --- a/BACKEND-API-REFERENCE.md +++ b/BACKEND-API-REFERENCE.md @@ -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. +**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: | Tag | Meaning | diff --git a/docs/PRODUCT-PLAN-v3.1-DELIVERY-PLAN.md b/docs/PRODUCT-PLAN-v3.1-DELIVERY-PLAN.md index 4a9000b..56d9b95 100644 --- a/docs/PRODUCT-PLAN-v3.1-DELIVERY-PLAN.md +++ b/docs/PRODUCT-PLAN-v3.1-DELIVERY-PLAN.md @@ -1,6 +1,6 @@ # 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**. diff --git a/docs/backend/README.md b/docs/backend/README.md new file mode 100644 index 0000000..1c61aa0 --- /dev/null +++ b/docs/backend/README.md @@ -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. diff --git a/docs/backend/TRACK-A-ANALYTICS-CONTRACT.md b/docs/backend/TRACK-A-ANALYTICS-CONTRACT.md new file mode 100644 index 0000000..d269442 --- /dev/null +++ b/docs/backend/TRACK-A-ANALYTICS-CONTRACT.md @@ -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; + 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. diff --git a/docs/backend/TRACK-S-SECURITY-RBAC-CONTRACT.md b/docs/backend/TRACK-S-SECURITY-RBAC-CONTRACT.md new file mode 100644 index 0000000..6220343 --- /dev/null +++ b/docs/backend/TRACK-S-SECURITY-RBAC-CONTRACT.md @@ -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.