Files
marketplaces/docs/ARCHITECTURE.md
sdarbinyan 5374401257 docs: consolidate documentation and archive temporary reports
Step 1-2 (audit + plan): classified 35 project markdown files into
Core/Architecture/ADR/Temporary-audit/Sprint-report/Generated-review/
Duplicate/Obsolete/Historical. Agent-tooling files (.agents/skills/**,
.superpowers/**, docs/context/**, CLAUDE.md/GEMINI.md/AGENTS.md/
.github/copilot-instructions.md) explicitly out of scope — intentional
per-tool duplication, not documentation debt.

Step 3 (merge, no information lost):
- docs/PROJECT.md -> docs/PROJECT_INDEX.md, rewritten as the single
  entry point: system overview, living-doc index, archive pointer,
  current status, and a critical-finding callout up top.
- docs/backend/BACKEND-INTEGRATION.md -> docs/BACKEND_API.md,
  docs/backend/REMAINING-BACKEND-WORK.md ->
  docs/BACKEND_API_REMAINING_WORK.md (also folded in a legitimate
  uncommitted status update that had been sitting unstaged all
  session: categories marked DONE, order-creation endpoint noted done).
- RELEASE-NOTES.md merged into CHANGELOG.md (was a near-duplicate of
  the same release content in friendlier prose), then deleted.
- KNOWN-ISSUES.md: added item 13 (see below) and item 14 (missing
  canDeactivate on admin/products edit, from the archived PROJECT-STATE
  audit, re-verified still true); added a correction note to Fixed
  item 7.
- All cross-references to renamed/moved files fixed across every
  kept doc (grep+sed pass, then verified with a link-existence check
  across all 58 in-scope markdown files -> 0 broken links).

Step 4 (archive, nothing deleted without merging first): created
docs/archive/, moved 19 files there (3 root sprint reports, 1 platform
report, SPRINT-PLAN.md, and 14 one-off audit/review/report docs).
Added correction headers to the 3 archived docs whose conclusions were
affected by the finding below, rather than silently leaving them
misleading.

Step 5: docs/PROJECT_INDEX.md rewritten per the mission brief -
someone opening the repo should understand the whole system from it.

IMPORTANT FINDING (surfaced during this audit, not the mission's
primary goal but too significant to bury): pages/category/*,
pages/search/*, pages/item-detail/*, pages/info/**, pages/legal/**
(40+ files) are entirely unrouted dead code - app.routes.ts's
cmsContentRoutes is a literal empty array, and category/search/product
routes redirect to CatalogContainerComponent/
ProductDetailsContainerComponent, not these files. Confirmed against
app.routes.ts directly and cross-checked against FRONTEND.md's own
routing description. This means several fixes from earlier this cycle
(RC-Premium-01, RC STORE-01) and the dead-code cleanup sprint's
conclusion that these files were live were all wrong - documented as
KNOWN-ISSUES.md item 13, flagged at the top of PROJECT_INDEX.md, and
noted on the 3 archived docs whose conclusions it affects. No
application code was changed to fix this (out of scope per this
session's 'documentation only' constraint) - it needs a wire-it-up-or-
delete-it decision first.

Verification: tsc --noEmit clean, npm run build green, all markdown
links across 58 in-scope files resolve (checked programmatically).
No application/Angular/backend code modified.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-25 19:10:49 +04:00

6.5 KiB

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/<domain>/*.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_API.md#4-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_API.md#4-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.