Files
marketplaces/docs/architecture/foundation/Seller-Management-Domain-Models.md
sdarbinyan 86091a4742 feat(sellers): typed domain models for future Seller Management - no logic, no API, no auth changes
Typed models only, per mission. Nothing outside the new files reads
or writes any of this yet.

New core/sellers/models/ (mirrors core/products/models,
core/auth/models convention):
- MarketplaceRef - minimal {id,slug,name} reference from a seller
  back to its marketplace, distinct from bootstrap's TenantConfig.
- SellerStatus - 'pending'|'active'|'suspended'|'disabled', no
  transition logic.
- SellerScope - {sellerId, marketplaceId}, domain-level counterpart
  to BootstrapConfig.seller (SellerConfig from the ADR-011 pass).
- SellerBranding (+SellerContact/SellerAddress/SellerThemeOverrides)
  - logo/banner/description/contacts/address/theme overrides, every
    field optional. Marketplace branding/theme remain default;
    nothing consumes this yet.
- SellerPermissionRole/SellerPermissions - marketplaceOwner/seller/
  sellerStaff/platformAdmin. Separate vocabulary from the existing
  AdminRole (core/auth/models/permission.model.ts) - not merged, not
  wired into any guard, zero auth behavior change.
- Seller - the eventual entity, composed from the above.

Changed (optional-only, verified backward compatible):
- Item (models/item.model.ts) gained sellerId?: string
- AdminProduct (features/admin/products/models/) gained
  sellerId?: string
- AdminOrder (features/admin/orders/models/) gained sellerId?: string

Absent means marketplace-owned in every case, exactly like every
existing product/order today. No consumer of any of these three
models needed updating. AdminOrderItem (per-line-item ownership) and
the existing PermissionsConfig/AdminRole system were deliberately not
touched - out of scope for this pass.

Added docs/architecture/foundation/Seller-Management-Domain-Models.md
documenting every new type, every changed field, and the explicit
non-goals list. Linked from the foundation README alongside ADR-011
and the diagrams doc.

tsc --noEmit clean, arch:check (boundaries + cycles) clean.
2026-07-26 21:55:11 +04:00

4.3 KiB

Seller Management — Domain Models (Preparation)

Companion to ADR-011 and Seller-Management-Diagrams.md. This document covers the second preparation pass: typed domain models for a future Seller entity, and optional seller-ownership fields on existing Product/Order models. Typed models only — no repository, gateway, facade, CRUD, API, or authentication/authorization change exists as a result of this work.

New: core/sellers/models/

A new domain model group, mirroring the existing core/products/models/, core/auth/models/ convention. Nothing outside this directory imports from it yet — these types exist for future work to build against.

Type File Purpose
MarketplaceRef marketplace-ref.model.ts Minimal {id, slug, name} reference from a seller record back to its owning marketplace. Not a replacement for TenantConfig (bootstrap's runtime tenant contract, ADR-001) — just enough to say which marketplace a seller belongs to.
SellerStatus seller-status.model.ts Lifecycle vocabulary: 'pending' | 'active' | 'suspended' | 'disabled'. No transition logic.
SellerScope seller-scope.model.ts {sellerId, marketplaceId} — the domain-level counterpart to BootstrapConfig.seller (SellerConfig). Backend-resolved only, same rule as tenant resolution (ADR-001, ADR-011).
SellerBranding (+ SellerContact, SellerAddress, SellerThemeOverrides) seller-branding.model.ts Logo, banner, description, contacts, address, theme overrides — all fields optional. Absent means marketplace branding/theme applies, unchanged (BrandingConfig/ThemeConfig). Nothing consumes this yet.
SellerPermissionRole, SellerPermissions seller-permissions.model.ts Four future roles: marketplaceOwner, seller, sellerStaff, platformAdmin. 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 auth behavior change.
Seller seller.model.ts The eventual entity: id, marketplace: MarketplaceRef, name, slug, status: SellerStatus, optional branding: SellerBranding, createdAt/updatedAt.

All exported via core/sellers/models/index.ts.

Changed: optional seller ownership on existing entities

Three existing entities gained one new optional field each. In every case: absent = marketplace-owned (today's only reality for every existing product/order), nothing reads the field yet, no consumer needed updating, tsc/arch:check both verified clean after the change.

Entity File Field added
Item (storefront product) models/item.model.ts sellerId?: string
AdminProduct (admin product editor) features/admin/products/models/admin-product.model.ts sellerId?: string
AdminOrder (admin order editor) features/admin/orders/models/admin-order.model.ts sellerId?: string

Deliberately not touched: AdminOrderItem (per-line-item seller ownership is a finer-grained decision than this preparation pass covers — order-level sellerId is enough for now), and both existing bootstrap PermissionsConfig/AdminRole (no authentication change, per mission).

Non-goals (explicitly out of scope)

  • No repository, gateway, facade, or API call reads or writes sellerId, Seller, or any type in this document.
  • No route, guard, or UI surfaces any of this.
  • No change to AdminRole, ROLE_PERMISSIONS, or any existing authentication/authorization code path.
  • No change to marketplace branding/theme defaults or precedence — a marketplace with no sellers, or a seller with no branding overrides, behaves exactly as today.

What this unblocks later

Once Seller Management is actually implemented (its own ADR/implementation pass, per ADR-011 §"Scope of this ADR"): a SellerRepository/SellerGateway can return Seller objects instead of inventing a shape; product/order CRUD can start populating sellerId without a breaking schema change; permission guards can consume SellerPermissionRole once a real role system decision is made; branding resolution can check Seller.branding before falling back to marketplace BrandingConfig/ThemeConfig.