docs: add platform vision ADR and Sprint 16 project editor design spec
Records the multi-tenant marketplace platform architecture as ADR-0001 (bootstrap-driven, config-only frontend) with a source-backed fact pack, and writes the approved Sprint 16 design for extending the existing project editor with Languages/Navigation tabs, an HTML editor, and a client-side draft/publish flow.
This commit is contained in:
67
docs/context/adrs/ADR-0001-marketplace-platform-vision.md
Normal file
67
docs/context/adrs/ADR-0001-marketplace-platform-vision.md
Normal file
@@ -0,0 +1,67 @@
|
||||
---
|
||||
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.
|
||||
6
docs/context/features/platform-vision/FACTS.jsonl
Normal file
6
docs/context/features/platform-vision/FACTS.jsonl
Normal file
@@ -0,0 +1,6 @@
|
||||
{"id":"PV-20260713T000000Z-0001","subject":"platform","predicate":"is-architected-as","object":"multi-tenant marketplace platform powering unlimited marketplaces from one codebase, driven entirely by backend bootstrap configuration","src":["docs/context/adrs/ADR-0001-marketplace-platform-vision.md"],"status":"active","kind":"decision","updated_at":"2026-07-13T00:00:00Z","confidence":"high","tags":["architecture","multi-tenant"]}
|
||||
{"id":"PV-20260713T000000Z-0002","subject":"frontend","predicate":"must-not","object":"contain marketplace-specific code, hardcoded marketplace data, or environment-flag-driven UI","src":["docs/context/adrs/ADR-0001-marketplace-platform-vision.md"],"status":"active","kind":"constraint","updated_at":"2026-07-13T00:00:00Z","confidence":"high","tags":["frontend","constraint"]}
|
||||
{"id":"PV-20260713T000000Z-0003","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","src":["docs/context/adrs/ADR-0001-marketplace-platform-vision.md"],"status":"active","kind":"constraint","updated_at":"2026-07-13T00:00:00Z","confidence":"high","tags":["bootstrap","constraint"]}
|
||||
{"id":"PV-20260713T000000Z-0004","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","src":["docs/context/adrs/ADR-0001-marketplace-platform-vision.md"],"status":"active","kind":"constraint","updated_at":"2026-07-13T00:00:00Z","confidence":"high","tags":["i18n","constraint"]}
|
||||
{"id":"PV-20260713T000000Z-0005","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","src":["docs/context/adrs/ADR-0001-marketplace-platform-vision.md"],"status":"active","kind":"constraint","updated_at":"2026-07-13T00:00:00Z","confidence":"high","tags":["admin","security"]}
|
||||
{"id":"PV-20260713T000000Z-0006","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","src":["docs/context/adrs/ADR-0001-marketplace-platform-vision.md"],"status":"active","kind":"constraint","updated_at":"2026-07-13T00:00:00Z","confidence":"high","tags":["widgets","layout"]}
|
||||
Reference in New Issue
Block a user