--- id: ADR-0001 title: Multi-tenant marketplace platform vision and config-driven architecture status: active date: 2026-07-13 tags: ["architecture", "philosophy", "multi-tenant", "bootstrap"] --- ## Context This is not a single marketplace — it is a multi-tenant platform powering unlimited marketplaces (e.g. electronics.example.com, books.example.com) from one codebase. Every marketplace is configured from the backend via a bootstrap configuration (`GET /bootstrap`). No marketplace-specific code may exist in the frontend. ## Decision - The frontend (Angular 20, standalone components, Signals, RxJS, SCSS) is a pure renderer. It owns render, navigation, interaction, validation, animations only. - The backend (ASP.NET Core REST API) owns branding, pages, layouts, languages, homepage, navigation, categories, products, footer, static pages, payment configuration, and enabled features. - Flow: Bootstrap → Runtime Provider → Configuration Store → Renderer → Widgets. Nothing depends on build-time environments; everything depends on runtime configuration. - Bootstrap contains only data needed before the app starts (name, logo, colors, languages, footer pages, homepage layout, navigation, enabled widgets). It must never contain products, orders, cart, or users. - Widgets never own page spacing — only their own internal layout. The renderer owns sections, spacing, and page width. - Homepage is composed from a configurable, ordered list of sections (Section Engine): Hero, Categories, Featured Products, Banner, Latest Products, Custom HTML, Newsletter, etc. - All layouts (homepage, PLP, etc.) must be backend-configurable without frontend changes. - All user-facing text is translatable via a `translations.{lang}` shape, not a flat `title` field. Adding/removing a supported language must automatically expose/remove translation fields across all translatable objects, generically — never per-field hardcoding. - Static pages (About Us, Privacy, Terms, Contacts, Return Policy, Delivery, custom pages) are backend-delivered HTML, multilingual, and drive the footer. - Admin and storefront share a domain but are fully separate applications: the marketplace bundle never ships admin code and vice versa. Bootstrap is public; Admin is protected by JWT + roles/permissions + tenant isolation (Super Admin, Marketplace Admin, Moderator, Editor, Support, Customer). ## Coding rules - Never hardcode marketplace data or introduce marketplace-specific conditionals. - Never use environment flags to drive UI — everything is config-driven. - Keep components small; prefer composition and reusable widgets; never duplicate layouts. - Business logic lives in services/facades, not components. - Prefer Signals and standalone components. - Every new feature ships with docs: frontend docs, backend contract, bootstrap updates, API examples, migration notes if needed. ## Guiding question Before implementing anything: "Will this still make sense after 50 marketplaces and 100 developers?" If not, redesign before coding. ## Consequences Any feature (including the Sprint 16 Project Editor) must edit the same Bootstrap model the storefront consumes — no parallel/duplicate configuration models are permitted anywhere in the platform.