# ADR-011: Optional Seller Management Module

Status: Accepted
Date: 2026-07-26

## Context

The platform today has a two-level hierarchy: Platform → Marketplace (tenant),
per ADR-001. Some marketplaces will eventually need a third, optional level:
individual Sellers operating storefronts within one marketplace (a
marketplace-of-marketplaces / multi-vendor model). Not every marketplace
needs this — most tenants today have none.

Seller Management must not become a second tenancy model. ADR-001 already
established that tenant identity is backend-resolved from request Host and
the frontend never passes or resolves tenant identity itself. Introducing
sellers must not weaken that discipline or introduce a second, parallel
resolution mechanism the frontend has to reason about.

## Decision

Seller Management is an **optional platform capability module**, not a new
tenancy tier equal to Marketplace:

```
Platform
  └── Marketplace (tenant)      — always present, resolved by backend (ADR-001)
        └── Seller (optional)   — 0..N per marketplace, resolved by backend
```

- **Marketplace remains the sole primary tenant.** A seller is a child scope
  of exactly one marketplace, never a sibling of Marketplace and never
  resolved independently of it.
- **The frontend never resolves seller identity itself** — same rule as
  tenant resolution (ADR-001). The backend decides whether the current
  request scope is marketplace-level or seller-level and reflects that
  decision in the bootstrap response.
- **The frontend consumes bootstrap only.** No new endpoint, header, or
  client-side resolution logic is introduced by this ADR. If a seller scope
  applies, `BootstrapConfig.seller` (see `SellerConfig`) is present; if not,
  it's absent. There is no other channel.
- **Gated by a module flag, not scattered conditionals.** The capability is
  controlled by one typed flag — `BootstrapConfig.modules.sellerManagement.
  enabled` (see `PlatformModulesConfig`) — checked in one place if/when
  seller-aware behavior is built, never as ad hoc `if (tenant.id === 'x')`
  or similar marketplace-specific conditionals anywhere in feature code.
  This follows the same capability-guard discipline ADR-009 already
  established for feature flags.

## Backward Compatibility (non-negotiable)

- `modules` and `seller` are both optional fields on `BootstrapConfig`.
  Existing marketplaces whose bootstrap response never includes them are
  unaffected — untyped-absent is not a special case to handle, it's the
  default.
- `DEFAULT_PLATFORM_MODULES_CONFIG` defaults `sellerManagement.enabled` to
  `false`. A marketplace that has never heard of this feature, and a
  marketplace where the backend explicitly disables it, behave identically:
  no new routes, no new menu entries, no new API calls, no visual change.
- No existing `BootstrapConfig` field, route, guard, or component changes as
  a result of this ADR. This ADR adds types; it changes nothing that already
  runs.

## Scope of this ADR

This ADR and its accompanying typed contracts (`PlatformModulesConfig`,
`SellerManagementModuleConfig`, `SellerConfig`) are **architecture only**:

- No UI is introduced — no seller-facing pages, no admin seller-management
  screens, no navigation entries.
- No backend is implemented — no endpoints, no seller data model, no
  resolution logic.
- No business logic is introduced — no seller CRUD, no seller-scoped
  permissions, no seller onboarding flow.

Those are all future work, gated behind `modules.sellerManagement.enabled`,
and each will need its own ADR/implementation pass once the module is
actually being built out (routing strategy under a seller scope, admin UI,
backend data model and resolution, permission model for seller-level roles).
This ADR exists so that future work has a typed foundation to build on
without retrofitting the platform/marketplace hierarchy after the fact.

## Consequences

Positive:

- Marketplaces that don't need multi-vendor support pay zero cost — no new
  code path executes, no new field is even present in their bootstrap
  response.
- Future Seller Management work has a settled hierarchy and typed contract
  to build against instead of ad hoc per-feature decisions about where
  "seller" fits.
- Consistent with the platform's existing capability-guard discipline
  (ADR-009) — one flag, checked in one place, not scattered conditionals.

Negative:

- Adds two optional fields to `BootstrapConfig` that most of the codebase
  will never populate — acceptable, matches the existing pattern of several
  other optional bootstrap fields (`header?`, `catalog?`, `layout?`, etc.).
- Defers real design decisions (seller-scoped routing, seller admin
  permissions, seller data ownership) to whenever the module is actually
  implemented — intentional; this ADR does not pre-invent that design.

## Compliance Requirements

- No component, facade, or service may branch on marketplace identity or
  seller identity directly. All seller-aware behavior, once built, must
  check `modules.sellerManagement.enabled` (or a capability-guard built on
  top of it) as the single gate.
- No frontend code may attempt to resolve which seller is active by itself
  (URL parsing, local storage, guessed convention, etc.) — that information
  only ever comes from `BootstrapConfig.seller`, backend-resolved, exactly
  like tenant resolution today.
- Any future work that adds seller-facing routes, UI, or backend calls must
  keep all of it inert and unreachable while `modules.sellerManagement.
  enabled` is `false`, with no exception.
