docs: replace 62 scattered/stale markdown files with two living references
Some checks failed
Architecture Governance / architecture (push) Has been cancelled
Some checks failed
Architecture Governance / architecture (push) Has been cancelled
Removes all tracked repo documentation (root status docs, docs/,
docs/architecture/foundation/**, docs/archive/**, docs/context/BACKEND-AUDIT.md
+ adrs, src/assets/mock/README.md) and replaces it with:
- GAPS-AND-IMPROVEMENTS.md — role-based findings (user, PO, QA, backend,
accessibility, engineering) plus automated code-review passes over the
storefront and backoffice, each with file:line references. Findings only,
no fixes applied.
- BACKEND-API-REFERENCE.md — single consolidated backend contract: auth
(both mechanisms), bootstrap, pagination/sorting/filtering conventions,
error model, every live/mock-only endpoint with JSON examples, and the
admin-domain DI-token seam gaps.
Open items and unresolved decisions from the deleted docs (KNOWN-ISSUES,
PRODUCT_BACKLOG, SPRINT-PLAN-NEXT, Seller-Management audits, etc.) were
harvested into the two new files before deletion, not lost.
CLAUDE.md/AGENTS.md/GEMINI.md/.claude/ and docs/context/{INDEX,LOG,
MAINTENANCE,README}.md are untouched — confirmed gitignored, never part of
git history, outside this cleanup's scope.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,67 +0,0 @@
|
||||
---
|
||||
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.
|
||||
@@ -1,53 +0,0 @@
|
||||
---
|
||||
id: ADR-0002
|
||||
title: Media Manager backend contract and mock storage adapter
|
||||
status: active
|
||||
date: 2026-07-15
|
||||
tags: ["architecture", "media", "backend-gap", "repository-pattern"]
|
||||
---
|
||||
|
||||
## Context
|
||||
|
||||
Sprint 4 (Media Manager) needs a media library: upload, browse, delete, and pick
|
||||
images/files for use across Product Editor, Static Pages (CMS), and Branding.
|
||||
No media backend exists yet — `/media` currently routes to a "coming soon"
|
||||
placeholder (`BackofficeComingSoonPageComponent`), and `docs/BACKEND.md` does
|
||||
not document any upload/storage endpoint. This mirrors the already-documented
|
||||
draft-publish-flow gap in the Project Editor (see `PE-20260713T010000Z-0003`):
|
||||
build the real contract, then implement a client-side mock adapter behind the
|
||||
same interface so the UI never needs to change when the backend ships.
|
||||
|
||||
## Decision
|
||||
|
||||
- **Domain model** `MediaAsset`: `{ id, url, thumbnailUrl?, filename, mimeType,
|
||||
size, width?, height?, altText?: Record<locale, string>, tags?: string[],
|
||||
createdAt }`. `altText` follows the platform's `translations.{lang}` rule
|
||||
(ADR-0001) — never a flat string.
|
||||
- **Repository contract** (future backend, to be implemented server-side):
|
||||
- `GET /media?page=&pageSize=&search=` → paginated `MediaAsset[]`
|
||||
- `POST /media/upload` (multipart) → `MediaAsset`
|
||||
- `DELETE /media/:id` → 204
|
||||
- `PATCH /media/:id` (altText/tags only) → `MediaAsset`
|
||||
- **Frontend abstraction**: a `MediaRepository` interface (Repository pattern,
|
||||
per `docs/context/features/*` conventions) with two implementations selected
|
||||
via DI token:
|
||||
- `MockMediaRepository` — stores assets in IndexedDB (not localStorage: binary
|
||||
blobs need it) as an interim store until the backend exists. Data URLs are
|
||||
generated for rendering; the shape returned matches `MediaAsset` exactly.
|
||||
- `HttpMediaRepository` — thin wrapper over the endpoints above, added when
|
||||
the backend ships. Swapping providers is the only change required.
|
||||
- **Media never enters the Bootstrap model.** Like products/orders/users, media
|
||||
assets are runtime admin data, not tenant configuration — consistent with
|
||||
ADR-0001's rule that Bootstrap contains only what's needed before the app
|
||||
starts.
|
||||
- **Media Picker** is a standalone, reusable dialog (built on the existing
|
||||
`app-dialog` Design System primitive) so Product Editor and CMS editors
|
||||
consume the same selection UI instead of each building their own.
|
||||
|
||||
## Consequences
|
||||
|
||||
- Any feature needing to reference an image (product gallery, static page
|
||||
hero, branding logo) does so via `MediaAsset.url`/`id`, obtained through the
|
||||
shared Media Picker — never a raw file input duplicated per feature.
|
||||
- When the backend ships, only `MediaRepository`'s DI provider changes; no
|
||||
component or facade code should need to change.
|
||||
@@ -1,42 +0,0 @@
|
||||
---
|
||||
id: ADR-0002
|
||||
title: Project Editor field-schema registry, centralized validation, and metadata-augmented form engine
|
||||
status: active
|
||||
date: 2026-07-16
|
||||
tags: ["project-editor", "schema", "validation", "undo-redo"]
|
||||
---
|
||||
|
||||
## Context
|
||||
|
||||
The Project Editor (`src/app/features/project-editor/`) edits the tenant `BootstrapConfig` across 11 hand-authored section templates, all built on the `shared/ui` field primitives (ADR established post-Sprint 30 redesign; see `docs/EDITOR.md`). Field labels/hints/defaults lived inline per template, `ProjectValidator` issues were not addressable to a field, there was no undo/redo, and no per-field modified/error state. Sprint X+1 ("Configuration Engine & Dynamic Form Foundation") required: a field-schema registry, centralized validation (JSON/CSS/URL/color/locale/duplicate-route/widget-config), live inline validation with publish-gating, pre-publish preview, dirty/modified-field tracking with a leave-warning, and session undo/redo — without duplicating form logic or validators, and without breaking draft/publish/import/export.
|
||||
|
||||
## Decision
|
||||
|
||||
**Metadata-augmented, not fully schema-driven.** A field-schema registry (`schema/field-schema.model.ts`, `schema/editor-schema.ts`, `schema/editor-schema.service.ts`) declares every editable field (dot-path key, section, type, label/hint keys, default, required, validator refs) as the single source of truth for field identity and validator wiring — but section templates stay hand-authored. The schema drives validation and metadata; it does not render fields. This was chosen over a fully schema-driven renderer because 11 mature templates already exist on top of the `shared/ui` kit, and a renderer rewrite carried materially higher regression risk against "preserve all existing functionality" for no UX gain.
|
||||
|
||||
**Validators are pure, composed, and tagged.** `schema/validators/primitives.ts` holds one pure function per concern (hex color, HTTP URL, email, JSON, CSS brace-balance, style-block extraction, route normalization). `ProjectValidator` composes them and attaches `section`, `fieldKey`, and `severity` (`error` | `warning`) to every issue, so the same validator is never re-implemented per field or per section.
|
||||
|
||||
**Severity splits blocking from advisory.** `publish()` now gates on `hasBlockingIssues()` (`severity === 'error'`) instead of "any issue exists." All 9 pre-existing checks stayed `error` (no behavior change); the new duplicate-routes and invalid-CSS checks are `warning` — informative, non-blocking, by design.
|
||||
|
||||
**Undo/redo is a pure reducer wrapped in debounced facade state.** `schema/history.util.ts` is a framework-free `{past, future}` snapshot reducer (commit/undo/redo, depth-capped). The facade debounces commits (~300ms) so a typing burst collapses into one undo step, and routes undo/redo through the same `localStorage` draft-save path as every other mutation so the autosave never desyncs from the undo stack.
|
||||
|
||||
**Modified-field tracking is a schema diff, not a form-state library.** `modifiedFields` walks every schema field and compares current vs. `originalBootstrap` by dot-path — no new dependency, reuses `EditorSchemaService.getByPath`.
|
||||
|
||||
## Consequences
|
||||
|
||||
Positive:
|
||||
- One registry answers "what fields exist, what validates them, what do they mean" — new fields register once and get validation + inline-error wiring for free.
|
||||
- No validator is duplicated: JSON/CSS/color/URL/email logic lives in exactly one place each.
|
||||
- Zero changes to `ProjectEditorIoService`, `ProjectEditorDraftStorageService`, or the draft/publish/reset flow — full backward compatibility.
|
||||
- Undo/redo and modified-field tracking added without a state-management library.
|
||||
|
||||
Negative / accepted debt:
|
||||
- Inline `[error]` binding is wired on a subset of fields (theme palette, general name/domain, branding logo) — not yet every schema-backed field across all 11 sections. Section-level visibility (nav badges, save-bar issue list) covers the rest today.
|
||||
- The field-schema registry is not yet consumed by templates for label/hint rendering (still inline i18n keys in each template) — only for validation, diffing, and change-summary labels. A future pass could fully drive labels from the schema.
|
||||
- CSS/JSON validators have a thin binding surface today (CSS only via static-page `<style>` blocks; JSON only via import) since no dedicated `customCss`/raw-JSON field exists yet in `BootstrapConfig`.
|
||||
|
||||
## Compliance Requirements
|
||||
|
||||
- New editable `BootstrapConfig` fields should get a `FieldSchema` entry in `editor-schema.ts` alongside their template addition.
|
||||
- New validation rules must be added as a pure function in `schema/validators/primitives.ts` and composed into `ProjectValidator` — never inlined ad hoc in a section component.
|
||||
- `severity: 'error'` is reserved for checks that must block Publish; anything advisory is `'warning'`.
|
||||
Reference in New Issue
Block a user