docs: consolidate scattered docs into canonical set
Replace ~35 organically-grown docs (docs/platform/*, docs/backend-platform/*, one-off sprint reports, Search.md, Diagnostics.md, Content-Management.md, Backend-Handoff-Sprint16.md, docs/superpowers/*, docs/Project-Editor.md, untracked docs/total.md) with the six canonical docs declared in .claude/CLAUDE.md: PROJECT.md, ARCHITECTURE.md, BACKEND.md, FRONTEND.md, BOOTSTRAP.md, EDITOR.md, plus a new PROJECT-STRUCTURE.md. - BACKEND.md is a punch list per domain (auth, bootstrap draft/publish, static pages, categories, products, orders, dashboard metrics, activity, translations, search, product engagement) plus a Known reliability issues section on the prod 502/504 root cause. - ARCHITECTURE.md links to (does not duplicate) the enforced docs/architecture/foundation/** ADRs and standards docs. - docs/ADMIN.md and docs/architecture/foundation/** and docs/context/** are left untouched per instructions. - Updated the one dangling docs/Project-Editor.md reference in admin-auth.service.ts to point at docs/BACKEND.md. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -1,175 +0,0 @@
|
||||
# Sprint 16 — Marketplace Project Editor MVP
|
||||
|
||||
Status: approved for planning
|
||||
Date: 2026-07-13
|
||||
Related: [ADR-0001](../../context/adrs/ADR-0001-marketplace-platform-vision.md), [Project-Editor.md](../../Project-Editor.md)
|
||||
|
||||
## Goal
|
||||
|
||||
A client can open the editor for their marketplace, edit settings, save a
|
||||
draft, preview, and publish — without touching JSON by hand. The editor edits
|
||||
the same `BootstrapConfig` the storefront consumes. No parallel/duplicate
|
||||
configuration model is introduced anywhere in this work.
|
||||
|
||||
## Current state (as of this sprint)
|
||||
|
||||
A working editor already exists at `/builder`
|
||||
(`src/app/features/project-editor/`): `ProjectEditorPageComponent` + signal-based
|
||||
`ProjectEditorFacade` (no NgRx), sections for general, branding, theme, header,
|
||||
footer, homepage (already has drag-and-drop reordering), widgets,
|
||||
static-pages (via `StaticPagesEditorComponent`), features, preview. Static
|
||||
page HTML is edited via a plain `<textarea>`. There is no Languages tab, no
|
||||
Navigation tab, no Draft/Publish distinction, and no `ProjectValidator`. There
|
||||
is no separate admin app — admin-ish features are ordinary lazy routes in the
|
||||
same Angular build as the storefront. There is no `projectId` / multi-project
|
||||
concept: each domain (tenant) resolves to its own bootstrap via the existing
|
||||
tenant-resolution mechanism, so "a project" is implicitly the current domain's
|
||||
tenant.
|
||||
|
||||
This sprint extends the existing editor rather than rebuilding it.
|
||||
|
||||
## Routing
|
||||
|
||||
Single Angular build (no separate admin app this sprint — deferred, see
|
||||
Out of scope). Flat, non-parameterized routes, since there is no project id:
|
||||
|
||||
```
|
||||
/edit → redirect to /edit/general
|
||||
/edit/general
|
||||
/edit/branding
|
||||
/edit/theme (existing, kept)
|
||||
/edit/languages (new)
|
||||
/edit/navigation (new)
|
||||
/edit/header (existing, kept)
|
||||
/edit/homepage
|
||||
/edit/footer
|
||||
/edit/static-pages
|
||||
/edit/widgets (existing, kept)
|
||||
/edit/features (existing, kept)
|
||||
/edit/preview
|
||||
```
|
||||
|
||||
`/builder` and `/builder/*` redirect to the equivalent `/edit/*` route for
|
||||
backward compatibility. Actual subdomain hosting (`admin.marketplace.com`)
|
||||
and a physically separate Angular deployment are a future ADR/sprint — this
|
||||
sprint only makes the route shape subdomain-ready (flat, no id segment).
|
||||
|
||||
Tabs become real child routes (deep-linkable, back-button works) instead of
|
||||
today's in-component signal switch. `ProjectEditorFacade` is unchanged by
|
||||
this — it already loads/holds bootstrap independent of which tab is active.
|
||||
|
||||
## Languages tab (new)
|
||||
|
||||
New `LocaleSyncService` (in `features/project-editor/services/`). It knows
|
||||
both translation shapes already used in the codebase:
|
||||
- index-signature maps: `{ [locale: string]: string }`
|
||||
(`LocalizedTextContent`/`LocalizedHtmlContent`)
|
||||
- keyed translation records: `Record<string, { title?, html?, seo? }>`
|
||||
(e.g. `StaticPageTranslationConfig`)
|
||||
|
||||
`addLocale(code)` / `removeLocale(code)` walk the known translatable slices of
|
||||
the in-memory bootstrap draft (static pages, footer nav labels, homepage
|
||||
widget text props) and add/remove that locale's key generically — not one
|
||||
`if` per field. `setDefaultLocale(code)` updates
|
||||
`localization.defaultLocale` (already exists). The tab lists supported
|
||||
locales, lets you add/remove, and pick the default; removing the current
|
||||
default is blocked by `ProjectValidator` (see below).
|
||||
|
||||
## Navigation tab (new)
|
||||
|
||||
Visual nested list over header + footer navigation
|
||||
(`src/app/shared/models/config/navigation.model.ts`). Add link, remove link,
|
||||
reorder (buttons, matching the homepage tab's existing pattern — no new
|
||||
drag-and-drop library), edit label (multilingual, via the same translation
|
||||
shape as everywhere else), edit URL, "open in new tab" toggle, visibility
|
||||
toggle, and nested children. Backed by new facade actions on
|
||||
`ProjectEditorFacade` (`addNavLink`, `removeNavLink`, `reorderNavLink`,
|
||||
`updateNavLink`) — no new store, same facade.
|
||||
|
||||
## Rich HTML editor (new)
|
||||
|
||||
New `MarketplaceHtmlEditorComponent`
|
||||
(`features/project-editor/components/html-editor/`): native
|
||||
`contentEditable` + a toolbar (bold, italic, underline, bullet/numbered
|
||||
lists, link, image, table, headings, code view, preview). No new npm
|
||||
dependency (no Quill/TipTap). Emits raw HTML on change; does not sanitize —
|
||||
sanitization remains a storefront-render concern, unchanged. Replaces the
|
||||
`<textarea>` currently in `static-pages-editor.component.html`, and is reused
|
||||
anywhere else HTML is edited going forward (e.g. footer custom content).
|
||||
|
||||
## Draft / Publish
|
||||
|
||||
No backend draft/publish API exists yet — confirmed against
|
||||
`docs/Project-Editor.md`, which only lists *recommended future* endpoints
|
||||
(`PUT /builder/bootstrap`, `POST /builder/bootstrap/{preview,validate,import}`,
|
||||
`GET /builder/bootstrap/export`), none of which distinguish draft from
|
||||
published. This sprint models it client-side only:
|
||||
|
||||
- `ProjectDraft` (new, in `models/`): `{ bootstrap: BootstrapConfig, status:
|
||||
'draft' | 'published', dirty: boolean, lastSavedAt?: string }`.
|
||||
- **Save** persists the draft using the same local mechanism the editor
|
||||
already uses for export/import (no new backend call this sprint) and
|
||||
clears `dirty`.
|
||||
- **Publish** runs `ProjectValidator` (must pass), then calls
|
||||
`ConfigService.applyBootstrapOverride()` (the mechanism already used for
|
||||
live preview) and sets `status = 'published'`.
|
||||
- **Documented gap for backend**: real draft/publish persistence needs
|
||||
`PUT /builder/bootstrap/draft` and `POST /builder/bootstrap/publish`
|
||||
endpoints. Not implemented this sprint; called out explicitly so backend
|
||||
work can be scheduled.
|
||||
|
||||
## Validation (new)
|
||||
|
||||
New `ProjectValidator` (in `services/`), pure functions run against the
|
||||
current draft. Checks: missing logo, no languages configured, invalid
|
||||
marketplace URL, duplicate static-page slugs, empty homepage (no sections),
|
||||
homepage section referencing a missing/unregistered widget, duplicate
|
||||
navigation links (same URL+label pair), invalid color values (theme tab).
|
||||
Runs on every Save (surfaces warnings, does not block) and on Publish
|
||||
(blocks with a clear list of failures). Errors surface inline in the
|
||||
relevant tab plus a summary list.
|
||||
|
||||
## Dirty-state
|
||||
|
||||
`ProjectEditorFacade` tracks `dirty` via a diff against the last-saved
|
||||
snapshot. A `CanDeactivate` route guard plus a `beforeunload` listener warn
|
||||
before navigating away or closing the tab with unsaved changes.
|
||||
|
||||
## UI
|
||||
|
||||
Card-based layout per tab, sticky Save/Publish bar (shows dirty state and
|
||||
validation summary), responsive down to tablet width — matching the
|
||||
existing editor's current visual style, no new design system.
|
||||
|
||||
## Architecture summary
|
||||
|
||||
Reused as-is: `ProjectEditorFacade`, `ProjectEditorIoService`,
|
||||
`ProjectEditorPreviewService`, existing section components.
|
||||
|
||||
New: `LocaleSyncService`, `ProjectValidator`, `MarketplaceHtmlEditorComponent`,
|
||||
`ProjectDraft` model, Navigation tab section + facade actions, Languages tab
|
||||
section + facade actions, `CanDeactivate` dirty-guard.
|
||||
|
||||
No `ProjectEditorStore`/`ProjectSerializer` as separate classes — the
|
||||
existing facade + `ProjectEditorIoService` already cover that responsibility
|
||||
(store = facade signals; serializer = IO service); introducing parallel
|
||||
classes would duplicate what's there, which the platform's own coding rules
|
||||
forbid.
|
||||
|
||||
## Out of scope (this sprint)
|
||||
|
||||
- Separate Angular app / actual subdomain deployment for admin.
|
||||
- Real backend draft/publish persistence (documented as a gap above).
|
||||
- Drag-and-drop for the new Navigation tab (buttons only, like homepage's
|
||||
existing pattern predates this — homepage itself already has drag-and-drop
|
||||
from a prior sprint and is left as-is).
|
||||
- Products, Orders, Users, Dashboards, Analytics (future sprints per the
|
||||
platform roadmap).
|
||||
|
||||
## Documentation
|
||||
|
||||
This spec plus updates to `docs/Project-Editor.md` (new tabs, draft/publish
|
||||
model, new services) and a fact-pack update under
|
||||
`docs/context/features/project-editor/FACTS.jsonl` are part of the
|
||||
deliverable, per the platform's documentation rule ("every new feature must
|
||||
include documentation").
|
||||
Reference in New Issue
Block a user