# ARCHITECTURE ## Platform principles - One codebase, unlimited tenants. No tenant-specific implementation code in the frontend. - Tenant behavior is controlled entirely by configuration loaded at bootstrap (`GET /bootstrap`, tenant resolved server-side by domain). - Prefer configuration over conditionals, composition over inheritance. - Authentication, payment, and authorization contracts/behavior are frozen and must not be redesigned as part of platform work (`docs/architecture/foundation/adr/ADR-010-backward-compatibility-for-auth-payment-authorization.md`). - No circular dependencies; shared/UI layers are feature-agnostic. These rules are enforced, not aspirational — see `docs/architecture/foundation/README.md` and the ADR set below, plus `npm run arch:check` (import-boundary + circular-dependency checks). ## Architecture Decision Records (source of truth — read directly, do not treat this file as a paraphrase) All under `docs/architecture/foundation/adr/`: - **ADR-001** — platform model (multi-tenant, config-driven). - **ADR-002** — layered feature architecture. - **ADR-003** — import boundaries and dependency direction. - **ADR-004** — configuration bootstrap and provider abstraction. - **ADR-005** — dynamic page/section/widget rendering. - **ADR-006** — UI component purity and container/facade pattern. - **ADR-007** — state management and facade boundaries. - **ADR-008** — theme engine and design-token runtime. - **ADR-009** — feature flags and capability guards. - **ADR-010** — backward compatibility for auth/payment/authorization. Companion standards docs (also `docs/architecture/foundation/`, kept as-is, enforced): `Coding-Standards.md`, `Naming-Conventions.md`, `Dependency-Rules.md`, `Folder-Blueprint.md`, `Import-Boundary-Matrix.md`, `State-Management-Standards.md`, `Configuration-Standards.md`, `Component-Standards.md`, `Service-Standards.md`. ## Layered architecture ``` Component (container) --> Facade --> Domain Service --> Repository/Provider --> Mock | API ``` - **Container/page components** own routing, orchestration, and DI of a facade. They hold no business logic. - **Presentational components** are `@Input()`/`@Output()`-only: no `HttpClient`, no storage, no environment access, no facade injection (ADR-006). The Project Editor's *sections* (`features/project-editor/sections/*`) are an accepted exception — they are container/section components, not shared presentational UI, so they may inject the facade directly (see `docs/EDITOR.md`). - **Facades** (`facades/**`, or feature-local `facade/`) are the only thing components talk to. They expose signals/observables and imperative methods; they compose one or more domain services (ADR-007). - **Domain services** (`core//*.service.ts`) convert backend DTOs into domain models via a **mapper**, and expose domain-shaped methods. DTOs never leak past the mapper boundary. - **Repositories/providers** are swappable via injection tokens (e.g. `PRODUCT_DATA_PROVIDER`, `CATEGORY_REPOSITORY`, `BACKOFFICE_DATA_PROVIDER`, `ADMIN_DASHBOARD_METRICS_GATEWAY`) so mock and real-API implementations can be swapped without touching facades or components — the same pattern used throughout `core/`, `features/admin/*`, and `features/backoffice/*`. ## Bootstrap / configuration engine - `ConfigService` loads `BootstrapConfig` (see `docs/BACKEND.md#1-bootstrap`) once at startup; `PlatformRuntimeService` applies it (theme, branding, runtime state) and can `reloadFromBootstrap()` for in-memory preview without a full page reload. - The bootstrap is the single source of truth for pages, sections, widgets, theme, navigation, footer, static pages, and feature flags (ADR-004). - The Project Editor mutates an in-memory draft of the same `BootstrapConfig` — there is no parallel editor-only model. ## Dynamic page / section / widget rendering (ADR-005) Render pipeline: `page config -> section engine -> section renderer -> widget host -> registered widget component`. - **Section Engine** (`dynamic-renderer/section-engine/section-engine.service.ts`) builds an ordered page render model from `PageConfig.sections`, applying `order`, `layout` (`SectionLayoutConfig.strategy`: `stack | grid | hero | carousel | split`), and `visibility` (desktop/tablet/mobile). - **Page Renderer** (`dynamic-renderer/page-renderer/page-renderer.service.ts`) delegates to the Section Engine. - **Widget Host** (`dynamic-renderer/widget-host/widget-host.service.ts`) resolves each widget's component via the **Widget Manifest** (`widgets/registry/widget-manifest.service.ts`, `widgets/contracts/widget-manifest.contract.ts`) and its data via the **Data Source Resolver** (`widgets/resolvers/data-source-resolver.service.ts`), which delegates to `CategoryFacade`/`ProductFacade` — widgets never call APIs directly. - Widgets receive only `{ section config, resolved data }` as inputs; they render presentation only, never fetch or mutate. - Unknown/unregistered widget types render a safe fallback; this is also surfaced in `features/diagnostics` (dev-only, route `/__diagnostics`). - `dynamic-page-layout.component.ts` (`layouts/containers/`) is the top-level container that composes Section Engine output using `PlatformLayoutConfig.type` (`default | sidebar-left | carousel-home | minimal`). ## Theme engine (ADR-008) - `ThemeConfig` (`shared/models/config/theme.model.ts`): `themeId`, `mode` (`light | dark | system`), `palette` (12 semantic colors), `typography`, `spacing`, `borderRadiusScale`, `shadows`, `iconSet`. - Applied as CSS custom properties at runtime; components/widgets consume tokens, never hardcoded brand colors. - Three tenant theme stylesheets live under `src/styles/themes/*.theme.scss` — see `docs/FRONTEND.md` for the CSS custom property convention. ## Feature flags / capability guards (ADR-009) - `bootstrap.featureFlags` (typed) plus the broader `bootstrap.features` (`MarketplaceFeaturesConfig`) surface for UI-facing toggles (wishlist, compare, reviews, recommendations, search history, etc.). - Feature resolution falls back across older config surfaces to preserve behavior as the flag model evolved across sprints — see `docs/BACKEND.md#1-bootstrap` for the full field list. ## Diagnostics (dev-only) `features/diagnostics/` (route `/__diagnostics`, excluded from production) validates bootstrap structure (missing fields, unknown widget types, duplicate ids, unknown layout values, missing translations) and runtime health (widget render failures, missing datasources), scored 0-100. Useful when investigating a bootstrap authored by the Project Editor.