subject: platform

predicate: is-architected-as

object: multi-tenant marketplace platform powering unlimited marketplaces from one codebase, driven entirely by backend bootstrap configuration

status: active

kind: decision

confidence: high


subject: frontend

predicate: must-not

object: contain marketplace-specific code, hardcoded marketplace data, or environment-flag-driven UI

kind: constraint


subject: bootstrap

predicate: must-only-contain

object: data needed before app start (branding, languages, homepage layout, navigation, enabled widgets, footer pages) and must never contain products, orders, cart, or users


subject: translatable-fields

predicate: must-be-modeled-as

object: generic translations.{lang} map so adding/removing a language automatically exposes/removes translation fields across all translatable objects


subject: admin-app

predicate: is-isolated-from

object: marketplace storefront bundle: admin code never ships to storefront and vice versa, though they may share a domain


subject: widgets

predicate: must-not-own

object: page spacing or page width; the renderer owns sections, spacing, and page width, widgets own only their internal layout


subject: auth-and-payment-client-logic

predicate: is-decided-to-extract-into

object: standalone versioned npm packages @marketplaces/auth and @marketplaces/payment, installed as dependencies rather than edited in-repo


subject: partner-merchant-provisioning

predicate: is-decided-to-build-as

object: one generic inbound API where all partner-specific behaviour is a PartnerProfile config row (required levels, level aliases, routing field names, rate tier); no partner name appears in any entity, field, endpoint or status value


subject: partner-hierarchy-levels

predicate: map-onto

object: company and project are new thin entities above Marketplace; store IS Marketplace (Phase 9); payment_point is new and equals one payment method accepted at one marketplace (qr, card)


subject: Seller

predicate: is-excluded-from

object: the partner provisioning hierarchy; a payment routes to exactly one payment point, is reconciled there, and only then splits across sellers in Phase 7 settlement


subject: RoutingContext

predicate: is-required-on

object: CheckoutSession, PaymentIntent, Payment, Refund and ReconciliationRecord; frozen at checkout-session creation and immutable thereafter, so a payment is always attributable to exactly one payment point


subject: partner-api-credentials

predicate: are-scoped-by

object: a single node whose subtree defines authority; we hold only the partner-generated public key, rotation runs on a bounded overlap window and revocation is immediate and irreversible


subject: checkout-payment-methods

predicate: already-support

object: both qr and card end to end in src/app/pages/cart/cart.component.ts (separate create paths and separate status pollers); card is not an outstanding gap

kind: implemented


subject: tenant-api-routing

predicate: is-decided-to-use

object: one same-origin {origin}/backend gateway for bootstrap, auth, legacy endpoints, and versioned /api endpoints; nginx strips /backend and preserves the original Host for server-side tenant resolution