215 lines
10 KiB
Markdown
215 lines
10 KiB
Markdown
|
|
# Seller Management — Capability Documentation
|
||
|
|
|
||
|
|
Status legend used throughout this document:
|
||
|
|
|
||
|
|
- **Implemented** — exists in source on `feature/seller-management-foundation` today, verified (`tsc`, `arch:check`, or live browser test).
|
||
|
|
- **Planned** — has a typed contract or explicit ADR decision, but no code reads/writes it yet.
|
||
|
|
- **Future** — a concept named in this document for roadmap completeness only. No shape, contract, or decision exists yet. Do not build against this section without a new ADR.
|
||
|
|
|
||
|
|
This document is the entry point. Detail lives in its companion docs:
|
||
|
|
[ADR-011](adr/ADR-011-optional-seller-management-module.md) (decision),
|
||
|
|
[Seller-Management-Diagrams.md](Seller-Management-Diagrams.md) (hierarchy/bootstrap-gate diagrams),
|
||
|
|
[Seller-Management-Domain-Models.md](Seller-Management-Domain-Models.md) (every type, field by field),
|
||
|
|
[Seller-Management-UX-Review.md](Seller-Management-UX-Review.md) (Phase 1 UI review).
|
||
|
|
|
||
|
|
## 1. Overview
|
||
|
|
|
||
|
|
Seller Management is an **optional platform capability** that would let one
|
||
|
|
marketplace host multiple independent sellers, each with their own
|
||
|
|
inventory/orders/branding, under one centralized administration. It is not
|
||
|
|
another tenant — a seller is a child scope beneath exactly one marketplace
|
||
|
|
(ADR-011).
|
||
|
|
|
||
|
|
**Implemented today:** typed contracts for the whole hierarchy, a disabled-
|
||
|
|
by-default feature flag, one Backoffice page that explains the capability
|
||
|
|
and collects interest ("Request Access" / "Learn More"). **Nothing else** —
|
||
|
|
no CRUD, no backend, no seller-facing UI, no checkout/order behavior change.
|
||
|
|
|
||
|
|
## 2. Architecture & Hierarchy — Implemented (types only)
|
||
|
|
|
||
|
|
```
|
||
|
|
Platform
|
||
|
|
└── Marketplace (tenant) — always present, backend-resolved (ADR-001)
|
||
|
|
└── Seller (optional) — 0..N per marketplace, backend-resolved (ADR-011)
|
||
|
|
```
|
||
|
|
|
||
|
|
Full diagram set: [Seller-Management-Diagrams.md](Seller-Management-Diagrams.md).
|
||
|
|
|
||
|
|
Rules (ADR-011, enforced by review, not yet by any lint rule):
|
||
|
|
Marketplace is the sole primary tenant. Seller is a child scope, never a
|
||
|
|
sibling tier. The frontend never resolves seller identity itself — same
|
||
|
|
rule as tenant resolution. All seller-aware behavior must check one
|
||
|
|
capability flag, never scattered marketplace/seller conditionals.
|
||
|
|
|
||
|
|
## 3. Marketplace — Implemented (existing, unchanged)
|
||
|
|
|
||
|
|
The marketplace is the existing `TenantConfig`
|
||
|
|
(`shared/models/config/tenant.model.ts`) — resolved by the backend from
|
||
|
|
request Host, exactly as before this work started. Seller Management adds a
|
||
|
|
new `MarketplaceRef` (`core/sellers/models/marketplace-ref.model.ts`): a
|
||
|
|
minimal `{id, slug, name}` view of a marketplace *as seen from a seller
|
||
|
|
record*, not a replacement for `TenantConfig`.
|
||
|
|
|
||
|
|
## 4. Seller — Implemented (types only)
|
||
|
|
|
||
|
|
`Seller` (`core/sellers/models/seller.model.ts`): `id`, `marketplace:
|
||
|
|
MarketplaceRef`, `name`, `slug`, `status: SellerStatus`, optional `branding:
|
||
|
|
SellerBranding`, `createdAt`/`updatedAt`. No repository, gateway, facade, or
|
||
|
|
UI reads or writes this type yet — it exists so future CRUD work has a
|
||
|
|
settled shape instead of inventing one ad hoc.
|
||
|
|
|
||
|
|
**Planned:** a `SellerRepository`/`SellerGateway` pair following the same
|
||
|
|
mock↔API DI-token pattern every other admin domain already uses
|
||
|
|
(`BACKEND.md` §8). **Future:** the actual CRUD screens, list/detail pages,
|
||
|
|
onboarding flow.
|
||
|
|
|
||
|
|
## 5. Roles & Permissions — Implemented (types only)
|
||
|
|
|
||
|
|
`SellerPermissionRole` (`core/sellers/models/seller-permissions.model.ts`):
|
||
|
|
four values — `marketplaceOwner`, `seller`, `sellerStaff`, `platformAdmin`.
|
||
|
|
This is a **separate vocabulary** from the existing `AdminRole` (Owner/
|
||
|
|
Manager/Support/ReadOnly, `core/auth/models/permission.model.ts`) — not
|
||
|
|
merged, not wired into any guard. **No authentication or authorization
|
||
|
|
change exists anywhere in this work.**
|
||
|
|
|
||
|
|
**Planned:** once a real permission model is designed, these roles gate
|
||
|
|
seller-scoped routes/actions the same way `AdminRole` gates admin routes
|
||
|
|
today (ADR-009 capability-guard pattern). **Future:** the actual
|
||
|
|
permission-to-action mapping, custom/finer-grained roles per marketplace.
|
||
|
|
|
||
|
|
## 6. Future Roadmap
|
||
|
|
|
||
|
|
### Feature Flags — Implemented (contract), Planned (real use)
|
||
|
|
|
||
|
|
`BootstrapConfig.modules.sellerManagement.enabled`
|
||
|
|
(`shared/models/config/platform-modules.model.ts`), default `false`
|
||
|
|
(`DEFAULT_PLATFORM_MODULES_CONFIG`). Implemented as a typed contract read by
|
||
|
|
the Phase 1 page (`admin-seller-management-page.component.ts`); no backend
|
||
|
|
sets it to `true` anywhere today, so it is always `false` in practice.
|
||
|
|
|
||
|
|
### Bootstrap — Implemented (contract), Planned (real data)
|
||
|
|
|
||
|
|
`BootstrapConfig.modules?` and `BootstrapConfig.seller?` (`SellerConfig`,
|
||
|
|
`shared/models/config/seller.model.ts`) — both optional, both absent in
|
||
|
|
every real bootstrap response today. When a backend eventually resolves a
|
||
|
|
seller scope, it populates `seller`; until then this field simply doesn't
|
||
|
|
exist on the wire.
|
||
|
|
|
||
|
|
### Future API — Future
|
||
|
|
|
||
|
|
No endpoint exists. When built, it should follow `BACKEND.md`'s existing
|
||
|
|
mock↔API-gateway pattern (§8) rather than a new convention — this is a
|
||
|
|
statement of intent, not a designed contract. No URL, DTO, or status-code
|
||
|
|
behavior is decided.
|
||
|
|
|
||
|
|
### Seller Storefronts — Future
|
||
|
|
|
||
|
|
Concept: a seller-branded storefront view within a marketplace (e.g. a
|
||
|
|
seller's own product listing page reachable from the marketplace). **Not
|
||
|
|
designed.** No route, component, or URL scheme exists or is decided.
|
||
|
|
|
||
|
|
### Seller Branding — Implemented (types only), Future (usage)
|
||
|
|
|
||
|
|
`SellerBranding` (`core/sellers/models/seller-branding.model.ts`): logo,
|
||
|
|
banner, description, contacts, address, theme overrides — every field
|
||
|
|
optional. **Implemented as a type only.** Nothing renders it, nothing falls
|
||
|
|
back from it to marketplace branding — that precedence logic is **Future**
|
||
|
|
work, not yet designed.
|
||
|
|
|
||
|
|
### Seller Ownership — Implemented (schema only), Future (logic)
|
||
|
|
|
||
|
|
`sellerId?: string` added to `Item` (storefront), `AdminProduct`, and
|
||
|
|
`AdminOrder` — optional, absent means marketplace-owned (every existing
|
||
|
|
product/order today). **No code reads or writes this field anywhere.**
|
||
|
|
Ownership rules, transfer, and enforcement are **Future** work.
|
||
|
|
|
||
|
|
### Checkout Modes — Future
|
||
|
|
|
||
|
|
Concept: how checkout behaves when a cart contains items from multiple
|
||
|
|
sellers (e.g. single combined checkout vs. per-seller checkout flows).
|
||
|
|
**Not designed.** No decision exists on this; today every product is
|
||
|
|
marketplace-owned and checkout has exactly one flow, unchanged by this work.
|
||
|
|
|
||
|
|
### Unified Orders / Split Orders — Future
|
||
|
|
|
||
|
|
Concept: whether one customer purchase spanning multiple sellers becomes
|
||
|
|
one order record or splits into one order per seller. **Not designed.**
|
||
|
|
This is a real business decision (payments, refunds, and reporting all
|
||
|
|
depend on the answer) with no default assumed — explicitly listed as an
|
||
|
|
open question for whenever Seller Management moves past preparation.
|
||
|
|
|
||
|
|
## 7. Migration & Compatibility
|
||
|
|
|
||
|
|
### Why existing marketplaces remain unchanged
|
||
|
|
|
||
|
|
- `modules.sellerManagement.enabled` defaults to `false` and no backend
|
||
|
|
sets it — every marketplace today gets identical behavior whether the
|
||
|
|
field is present-and-false or entirely absent from its bootstrap
|
||
|
|
response.
|
||
|
|
- `BootstrapConfig.modules` and `BootstrapConfig.seller` are optional
|
||
|
|
fields; no existing field's type changed.
|
||
|
|
- `sellerId?` on `Item`/`AdminProduct`/`AdminOrder` is optional; no
|
||
|
|
consumer of any of these three types needed updating, verified by
|
||
|
|
`tsc --noEmit` staying clean after each change.
|
||
|
|
- Zero components, facades, services, or routes branch on marketplace or
|
||
|
|
seller identity anywhere in this work (ADR-011 compliance requirement) —
|
||
|
|
there is no conditional to accidentally trigger.
|
||
|
|
- Every commit in this line of work was verified with `tsc --noEmit`,
|
||
|
|
`arch:check` (import boundaries + circular deps), and — for the UI
|
||
|
|
commits — a live browser pass, specifically to confirm no regression to
|
||
|
|
existing pages.
|
||
|
|
|
||
|
|
## 8. Developer Notes
|
||
|
|
|
||
|
|
- All seller domain types live in `core/sellers/models/` (mirrors
|
||
|
|
`core/products/models`, `core/auth/models`). Extend there, not ad hoc in
|
||
|
|
feature folders.
|
||
|
|
- When real seller-aware behavior is eventually built, gate it behind
|
||
|
|
`modules.sellerManagement.enabled` in one place (a capability guard,
|
||
|
|
ADR-009's pattern) — never scattered `if` checks on tenant/seller identity.
|
||
|
|
- The Phase 1 page (`features/admin/seller-management/`) is disposable —
|
||
|
|
it exists to communicate the capability to merchants, not as a
|
||
|
|
foundation to extend. Real seller CRUD UI should be planned fresh once
|
||
|
|
the backend contract exists, not bolted onto this page.
|
||
|
|
|
||
|
|
## 9. Builder Notes
|
||
|
|
|
||
|
|
The Project Editor / Marketplace Builder has **zero seller-awareness**
|
||
|
|
today. Its draft/publish model (`localStorage`-only, no backend write path
|
||
|
|
per `BACKEND.md` §1.10) is entirely marketplace-scoped. If/when a seller
|
||
|
|
needs their own builder-like surface (branding, storefront layout), it must
|
||
|
|
be designed as its own ADR — do not assume the existing builder can be
|
||
|
|
reused as-is for a seller scope without that review, since its facades and
|
||
|
|
schema (ADR-005, ADR-007) were built assuming exactly one config document
|
||
|
|
per marketplace.
|
||
|
|
|
||
|
|
## 10. Backend Notes
|
||
|
|
|
||
|
|
No backend implementation exists for any part of Seller Management. When
|
||
|
|
work begins, follow `BACKEND.md`'s established pattern exactly: a
|
||
|
|
`SellerRepository`/`SellerGateway` behind a DI token, `MockSellerGateway`
|
||
|
|
first, `ApiSellerGateway` swapped in later, same convention every other
|
||
|
|
admin domain in this codebase already uses (`BACKEND.md` §8). The typed
|
||
|
|
models in `core/sellers/models/` are the DTO shapes to implement against —
|
||
|
|
treat them as the contract, not a suggestion to redesign.
|
||
|
|
|
||
|
|
## Diagrams
|
||
|
|
|
||
|
|
```mermaid
|
||
|
|
graph LR
|
||
|
|
A["Types & feature flag<br/>(this + prior 3 commits)"] -->|Implemented| B["Phase 1 UI<br/>(Partners > Seller Management page)"]
|
||
|
|
B -->|Implemented| C["Backend contract decisions<br/>(BACKEND.md gaps, own ADR)"]
|
||
|
|
C -->|Future| D["Seller CRUD + real gateway"]
|
||
|
|
D -->|Future| E["Seller Branding rendering<br/>+ Storefronts"]
|
||
|
|
E -->|Future| F["Checkout Modes +<br/>Unified/Split Orders"]
|
||
|
|
|
||
|
|
classDef done fill:#2e7d3222,stroke:#2e7d32,color:inherit;
|
||
|
|
classDef future fill:#6b728022,stroke:#6b7280,color:inherit;
|
||
|
|
class A,B done;
|
||
|
|
class C,D,E,F future;
|
||
|
|
```
|
||
|
|
|
||
|
|
Rollout is strictly left-to-right — no stage after "Phase 1 UI" has started.
|
||
|
|
See [Seller-Management-Diagrams.md](Seller-Management-Diagrams.md) for the
|
||
|
|
hierarchy and bootstrap-gate diagrams (unchanged, still accurate).
|