docs(backend): add Seller Management section to BACKEND.md

docs/BACKEND_API.md no longer exists as a live file (merged into
BACKEND.md in an earlier consolidation pass, per that doc's own intro
- only docs/archive/BACKEND_API.md remains, historical only). This
mission's "update BACKEND_API.md" instruction is fulfilled by
extending the doc that actually supersedes it: new §11 "Seller
Management (Optional Capability)", added to the top-of-file table of
contents, no existing section renumbered or altered.

Every subsection explicitly tagged Implemented / Planned / Future,
matching the same legend used in docs/architecture/foundation/
Seller-Management.md (the frontend-side capability doc this section
is the backend counterpart to):

- 11.2 Future entities: Marketplace (Implemented, existing
  TenantConfig unchanged), Seller/SellerBranding (Planned - frontend
  types exist, no backend schema), SellerUser/SellerSettings/
  SellerInvitation (Future - no type, no concept, named for roadmap
  completeness only).
- 11.3 Future endpoints: Seller CRUD/Activation/Invitations/Branding/
  Analytics/Dashboard - all Future, none designed, each noted as
  following the existing mock-to-API-gateway pattern (SS8) once built.
- 11.4 Authentication: SellerPermissionRole (4 roles) explicitly
  flagged as a separate vocabulary from the existing, live AdminRole -
  not merged, no guard wired, zero auth change.
- 11.5 Domain resolution: market.com -> Marketplace is Implemented
  today (ADR-001, backend-Host-resolved); nike.market.com -> Marketplace
  -> Seller is Future, no backend resolves it - and per the storefront
  audit, needs no frontend routing change once it does.
- 11.6 Bootstrap additions: modules/modules.sellerManagement documented
  as Implemented-as-contract (typed, always false/absent today);
  sellerScope/sellerBranding as Planned with an explicitly flagged open
  question (SellerConfig vs SellerBranding nesting not reconciled);
  permissions noted as existing/unrelated today.
- 11.7 Checkout modes: Unified Order vs Split Orders - Future, not
  designed, flagged as the single most consequential undecided item
  for backend design given payments/refunds/reporting all depend on it.
- 11.8 Product ownership: sellerId? on Item/AdminProduct/AdminOrder -
  Implemented as schema only (optional, absent = marketplace-owned,
  verified backward-compatible via tsc staying clean). Existing
  products remain valid with no migration required - NULL/absent
  ownership documented as a permanent state, not transitional.

No backend implemented. No frontend code touched. Documentation only.
This commit is contained in:
sdarbinyan
2026-07-26 22:41:57 +04:00
parent f4b92c7909
commit fa6e5cd68b

View File

@@ -59,6 +59,7 @@ background reading.
8. [Real Backend Implementation Guide](#8-real-backend-implementation-guide)
9. [Backend Checklist](#9-backend-checklist)
10. [Maintenance Mode](#10-maintenance-mode)
11. [Seller Management (Optional Capability)](#11-seller-management-optional-capability)
---
## 1. Bootstrap
@@ -4975,6 +4976,218 @@ Each has a **Recommended default** — apply it unless flagged otherwise.
---
## 11. Seller Management (Optional Capability)
Status legend for this section only (matches
`docs/architecture/foundation/Seller-Management.md`, the frontend-side
capability doc this section is the backend counterpart to):
- **Implemented** — exists in frontend source today, verified.
- **Planned** — a typed contract or explicit ADR decision exists; no backend
or runtime behavior exists yet.
- **Future** — named for roadmap completeness only. No shape, contract, or
decision exists. Do not build against a Future item without a new ADR.
**Nothing in this section is implemented on the backend, because no backend
exists yet for anything in this document.** Frontend-side preparation
(typed models, a disabled-by-default feature flag, one Backoffice
placeholder page) is real and is marked Implemented per item below; backend
work is entirely Planned or Future. This section documents the frontend's
existing preparation and the shape a backend should target — it does not
invent new frontend behavior, and per this section's mission, it must not
be read as backend implementation guidance beyond documentation.
### 11.1 Overview
Seller Management is an optional platform capability: a marketplace
(tenant) may host zero or more independent sellers, each scoped beneath it.
It is not a second tenancy tier — see §11.5 Domain Resolution. Full
frontend-side detail: `docs/architecture/foundation/Seller-Management.md`
and its companion ADR-011.
### 11.2 Future entities
None of these have a backend schema, migration, or storage decision yet.
Frontend typed equivalents (where they exist) are cited per entity.
- **Marketplace** — **Implemented** (existing `TenantConfig`, unchanged by
this work). The plus a new **Planned** frontend-only reference type,
`MarketplaceRef` (`core/sellers/models/marketplace-ref.model.ts`):
`{id, slug, name}`, the minimal view of a marketplace as seen from a
seller record. Not a backend entity of its own — it's a projection of
the existing Marketplace/tenant entity.
- **Seller** — **Planned** (frontend type exists: `Seller`,
`core/sellers/models/seller.model.ts` — `id`, `marketplace: MarketplaceRef`,
`name`, `slug`, `status: SellerStatus`, optional `branding: SellerBranding`,
`createdAt`/`updatedAt`). No backend table, migration, or endpoint exists.
- **SellerUser** — **Future**. No frontend type exists for a user record
scoped to a specific seller (distinct from the existing marketplace-level
`AdminUser`, `features/admin/users/models/admin-user.model.ts`). Named
here for roadmap completeness only — shape not decided.
- **SellerBranding** — **Planned** (frontend type exists: `SellerBranding`,
`core/sellers/models/seller-branding.model.ts` — logo, banner,
description, contacts, address, theme overrides, every field optional).
No backend storage or rendering/precedence logic exists (frontend side of
precedence — falling back to marketplace branding — is also undecided,
per `Seller-Management.md` §6).
- **SellerSettings** — **Future**. No frontend type, no backend concept.
Distinct from `SellerBranding` (visual) — would cover operational
settings (e.g. notification preferences, payout details) if this
capability is ever built out. Not designed.
- **SellerInvitation** — **Future**. No frontend type, no backend concept.
The onboarding mechanism implied by the existing Phase 1 UI's "Request
Access" form (`features/admin/seller-management/pages/
admin-seller-management-page.component.ts`) is a **mocked, client-side-only
submission today** — no email is sent, no invitation record is created,
nothing persists past the browser session. A real invitation flow
(backend-issued invitation token, acceptance, seller-account creation) is
entirely Future.
### 11.3 Future endpoints
No endpoint below exists. Each would follow this codebase's established
mock↔API-gateway pattern (§8) once built — that pattern is a statement of
intent here, not a designed URL/DTO contract.
- **Seller CRUD** — **Future**. No `SellerRepository`/`SellerGateway`
interface exists yet (unlike e.g. Categories, §3.2, which already has
this seam). Would need `list/get/create/update/delete` following the
conventions in §2 (pagination, filtering, error envelope) once designed.
- **Seller Activation** — **Future**. Ties to `SellerStatus`
(`'pending' | 'active' | 'suspended' | 'disabled'`, frontend type only,
no transition logic anywhere) and to SellerInvitation above. No
state-machine, no endpoint, no decision on who can activate/suspend a
seller.
- **Seller Invitations** — **Future**. See SellerInvitation above — this
would be the endpoint surface for that entity, once it exists.
- **Seller Branding** — **Future** (endpoint). The `SellerBranding` type is
Planned (§11.2) but no read/write endpoint exists to serve or persist it.
- **Seller Analytics** — **Future**. The existing `AdminAnalyticsFacade`
(§3.20) already has no real aggregation endpoint for the marketplace as a
whole — per-seller analytics is a further layer on top of a gap that
isn't solved yet even without sellers. Not designed.
- **Seller Dashboard** — **Future**. Same reasoning as Seller Analytics;
the existing `AdminDashboardMetricsGateway.loadMetrics()` (§3, Dashboard)
is a bare no-arg call with no parameter to scope by seller even
syntactically — a seller dashboard is new surface, not an extension.
### 11.4 Authentication
**No authentication change of any kind exists in this work.** The four
roles below are a **Planned** vocabulary only
(`SellerPermissionRole`, `core/sellers/models/seller-permissions.model.ts`):
`marketplaceOwner`, `seller`, `sellerStaff`, `platformAdmin`. This is
**explicitly a separate vocabulary from the existing, live `AdminRole`**
(Owner/Manager/Support/ReadOnly, `core/auth/models/permission.model.ts`,
§4) — not merged, not wired into any guard, no route currently checks it.
Closest existing hook (per
`Seller-Management-Backoffice-Readiness-Audit.md`): `AdminUser` already
carries an `AdminUserScope` field (`'marketplace' | 'office'` in seed
data) and a permission-array shape on `AdminRole` — the natural future home
for these four roles, but today it's used for display labels only, nothing
gates on it. **Future:** deciding whether `SellerPermissionRole` extends,
replaces, or sits alongside `AdminRole`; wiring any guard/interceptor to
check it; deciding how a Seller/Seller Staff session authenticates at all
(same Telegram/Ed25519 mechanisms as today, §4, or something new — not
decided).
### 11.5 Domain resolution
```
market.com → Marketplace (Implemented — ADR-001, live today)
nike.market.com → Marketplace → Seller (Future — no backend resolves this yet)
```
**Implemented today:** tenant (Marketplace) resolution is entirely
backend-side by request Host (ADR-001, §1.9). The frontend never resolves
tenant identity itself — it calls `GET /bootstrap` and renders whatever
comes back for whatever hostname it's running on.
**Future:** a second-level Host pattern (`{seller}.{marketplace-domain}`)
resolving to a seller scope beneath that marketplace. No backend logic for
this exists. Per the frontend-side storefront audit
(`Seller-Management-Storefront-Audit.md`), the frontend's existing
discipline — nothing hardcodes hostname, canonical URLs already derive
from `location.origin` dynamically — means this pattern needs **no
frontend routing change** once a backend resolves it; the open work is
entirely backend resolution logic plus which bootstrap fields carry the
resolved seller data (see §11.6).
### 11.6 Bootstrap additions
All **Implemented as typed contracts, always absent/false in every real
bootstrap response today** — no backend populates any of these fields
anywhere:
- **`modules`** — `BootstrapConfig.modules?: PlatformModulesConfig`
(`shared/models/config/platform-modules.model.ts`). Optional; absent
means every module is disabled.
- **`modules.sellerManagement`** — `{enabled: boolean}`, defaults to
`false` (`DEFAULT_PLATFORM_MODULES_CONFIG`). Read by the Phase 1 page
today; no backend ever sets it `true`.
- **`sellerScope`** — **Planned**. The frontend has a domain-level
`SellerScope` type (`core/sellers/models/seller-scope.model.ts`:
`{sellerId, marketplaceId}`) and a bootstrap-wire counterpart,
`BootstrapConfig.seller?: SellerConfig`
(`shared/models/config/seller.model.ts`) — present only when the backend
has resolved a seller-level request scope (§11.5). No backend does this
yet; the field is optional and always absent today.
- **`sellerBranding`** — **Planned**. Carried as `SellerConfig`'s branding
shape would need to be, or as `BootstrapConfig.seller?.branding` — the
exact nesting isn't finalized, since `SellerConfig` (bootstrap wire
shape) and `SellerBranding` (domain type) are currently separate types
that haven't been reconciled (see `Seller-Management-Domain-Models.md`).
Flagged as an open question here rather than guessed at.
- **`permissions`** — **Implemented** (existing, unchanged) —
`BootstrapConfig.permissions: PermissionsConfig` already exists and is
unrelated to Seller Management's future permission model; the two are
not connected today. **Future:** whether/how `SellerPermissionRole`
(§11.4) ever surfaces through this existing field or a new one — not
decided.
### 11.7 Checkout modes
**Future — not designed.** Two named concepts, no decision between them:
- **Unified Order** — one customer purchase, regardless of how many
sellers' items are in the cart, produces one order record.
- **Split Orders** — one customer purchase spanning multiple sellers
produces one order record per seller.
**Current, unrelated to sellers:** checkout today is a single inline
popup flow (`pages/cart/cart.component.ts`) producing exactly one order via
one `POST /orders`-equivalent call — there is no multi-seller cart concept
of any kind to split or unify, because every product is marketplace-owned.
This decision has real consequences (payments, refunds, reporting) that
depend on it — explicitly listed as open in
`Seller-Management.md` §6 and repeated here because it's the single most
consequential undecided item for backend design once this capability moves
past preparation.
### 11.8 Product ownership
**Implemented (schema only), Future (logic).** `sellerId?: string` was
added as an **optional** field to three existing frontend types: `Item`
(storefront product, `models/item.model.ts`), `AdminProduct`
(`features/admin/products/models/admin-product.model.ts`), and `AdminOrder`
(`features/admin/orders/models/admin-order.model.ts`). In every case,
absent means marketplace-owned — exactly what every existing product and
order is today. **No frontend code reads or writes this field anywhere.**
No backend column, migration, or filter exists for it either.
**Compatibility guarantee, verified not assumed:** adding this optional
field required zero changes to any consumer of these three types —
confirmed by `tsc --noEmit` staying clean after the change
(`Seller-Management-Domain-Models.md`). The same guarantee applies to any
future backend schema change: a nullable `seller_id` column (or
equivalent) that defaults to `NULL`/absent preserves every existing
product/order exactly as-is. **Existing products remain valid** with no
migration required to backfill a value — `NULL`/absent seller ownership is
a first-class, permanent state, not a transitional one.
---
## Appendix: `docs/TODO.md` items merged into this document (2026-07-26)
Final Project Closeout moved every backend-shaped item out of `docs/TODO.md` into this