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:
70
docs/EDITOR.md
Normal file
70
docs/EDITOR.md
Normal file
@@ -0,0 +1,70 @@
|
||||
# EDITOR (Project Editor)
|
||||
|
||||
Replaces the old `docs/Project-Editor.md` (content merged in below and extended with the Sprint 19 field-description/dropdown work).
|
||||
|
||||
The Project Editor (`src/app/features/project-editor/`) edits the tenant's `BootstrapConfig` (`docs/BOOTSTRAP.md`) directly — no parallel model. It is out of scope for products, categories, orders, or analytics management (those live under `features/admin/*`/`features/backoffice/*`, see `docs/ADMIN.md`).
|
||||
|
||||
```
|
||||
src/app/features/project-editor/
|
||||
pages/ route container
|
||||
sections/ one component per editor tab (see below)
|
||||
components/ shared editor UI (save bar, HTML editor)
|
||||
models/ ProjectEditorState, EDITOR_SECTION_BOOTSTRAP_KEYS
|
||||
services/ ProjectValidator, ProjectEditorDraftStorageService, LocaleSyncService
|
||||
facade/ ProjectEditorFacade
|
||||
```
|
||||
|
||||
Route: `/edit/:section` or `/{lang}/edit/:section`.
|
||||
|
||||
## Facade
|
||||
|
||||
`ProjectEditorFacade` exposes: `loadBootstrap()`, `updateBootstrap(updater)`, `exportBootstrap()`, `importBootstrap()`, `preview()`, `save()`, `publish()`, plus signals `bootstrap`, `status` (`draft|published`), `dirty`, `lastSavedAt`, `lastPublishedAt`, `validationIssues`, `homepageWidgets`, `homepagePage`. Components in `sections/*` inject this facade directly (an accepted exception to the presentational-component rule, per ADR-006 — these are container/section components, not shared UI).
|
||||
|
||||
## Sections
|
||||
|
||||
| Section | Component | Covers |
|
||||
|---|---|---|
|
||||
| General | `general-section` | marketplace name, domain, description, default/supported languages |
|
||||
| Branding | `branding-section` | logo, small logo, favicon, marketplace title |
|
||||
| Theme | `theme-section` | palette colors, theme mode, site layout mode |
|
||||
| Header | `header-section` | logo/search/categories/languages/cart/profile/wishlist/compare/region toggles |
|
||||
| Footer | `footer-section` | company info, address, phone, email, copyright, payment icons, social links, static pages list |
|
||||
| Homepage | `homepage-section` | homepage section list: visibility, order (drag-and-drop), layout strategy, columns |
|
||||
| Widgets | `widgets-section` | homepage widget configuration — typed editors for hero/categories/product-collection, JSON fallback for everything else |
|
||||
| Marketplace Features | `features-section` | feature flags, catalog navigation mode, search suggestions/history, recently viewed, reviews/questions/recommendations |
|
||||
| Languages | `languages-section` | add/remove supported locale, set default locale; syncs translation keys across static pages and nav labels via `LocaleSyncService` |
|
||||
| Navigation | `navigation-section` | header nav: add/remove/reorder/edit label/URL/visibility. Flat footer nav: same. Grouped (column-based) footer nav is read-only here — edit via Footer tab. |
|
||||
| Preview | `preview-section` | export/import JSON, in-memory runtime preview without full reload |
|
||||
|
||||
## Save / publish / draft / reset model
|
||||
|
||||
- **Save**: `save()` snapshots the current in-memory bootstrap as "last saved" (`lastSavedAt`). `ProjectEditorDraftStorageService` persists the full draft to `localStorage` (`projectEditor.draftBootstrap.v1`, scoped by `tenant.id`) on every `updateBootstrap()`, `save()`, and `publish()` call.
|
||||
- **Publish**: runs `ProjectValidator`; if clean, calls `PlatformRuntimeService.reloadFromBootstrap()`, sets `status = 'published'`, sets `lastPublishedAt`, and becomes the new `originalBootstrap` baseline used by reset.
|
||||
- **Draft restore**: on `loadBootstrap()`, if a stored draft exists for the same tenant it loads instead of the fresh fetch, and `draftRestored` is set (shown as a dismissible banner in the save bar).
|
||||
- **Reset section**: reverts one section's bootstrap keys (per `EDITOR_SECTION_BOOTSTRAP_KEYS` in `models/project-editor.model.ts`) to `originalBootstrap`. Confirmation required.
|
||||
- **Reset draft**: reverts the entire bootstrap to `originalBootstrap` and clears the persisted local draft. Confirmation required.
|
||||
- **Per-field reset is not implemented** — no per-field default registry exists; only section- and project-level reset.
|
||||
- **No backend persistence exists for any of this today** — see `docs/BACKEND.md` item 2 for the endpoints needed.
|
||||
|
||||
## Validation
|
||||
|
||||
`ProjectValidator` (`services/project-validator.service.ts`) runs on every save-bar render and blocks Publish (not Save) on: missing `branding.logoUrl`, no supported locales, invalid `tenant.websiteBaseUrl`, duplicate static-page slugs (falls back to `route`), empty homepage, a homepage widget with no `type`, duplicate header nav links, invalid theme colors, missing translations for a supported locale, and layout/section-layout values outside the known enums (`PlatformLayoutType`, `SectionLayoutStrategy`).
|
||||
|
||||
## Admin Authentication (QR reuse)
|
||||
|
||||
Admin login shares the exact same Telegram QR/session backend and `TelegramLoginComponent` as customer login (`mode: 'admin'` vs `'customer'`) — only the cookie name/`SameSite` policy, token storage keys, and guard differ. **Backend gap:** because both flows hit the same session endpoint, the backend cannot distinguish an admin scan from a customer scan today — real admin authorization must be enforced server-side. Full detail: `docs/BACKEND.md` item 1.
|
||||
|
||||
## Field-description / dropdown UX (Sprint 19+)
|
||||
|
||||
Every field across the 10 editor section templates now carries a one-line, i18n'd description under its label explaining what it does in plain language (all new copy routed through `TranslateService`/`TranslatePipe`, added to `Translations` + `en.ts`/`ru.ts`/`hy.ts` following the existing `builder.*` key pattern — see `src/app/i18n/translations.ts`).
|
||||
|
||||
**Converted from free-text `<input>` to `<select>`** (backed by a closed TypeScript union), each option carrying a human label and a short description (via `title` attribute) instead of the raw enum value:
|
||||
|
||||
- `section.layout.strategy` (Homepage section) — `SectionLayoutStrategy`: `stack | grid | hero | carousel | split`.
|
||||
- `theme.mode` (Theme section) — `light | dark | system`.
|
||||
- `layout.type` (Theme section, "Site Layout") — `PlatformLayoutType`: `default | sidebar-left | carousel-home | minimal`.
|
||||
- `catalog.navigationMode` (Marketplace Features section) — `CatalogNavigationModeConfig`: `default | left-category-navigation | mega-category-layout | top-category-carousel`.
|
||||
|
||||
Each of these components defines a local `readonly` options array of `{ value, labelKey, descriptionKey }` (per ADR-006, these are section/container components so this is allowed without a new shared UI library).
|
||||
|
||||
**Still plain text/checkbox, with a description added, and why:** marketplace name, domain, description, logo/favicon/small-logo URLs, palette colors (already `<input type="color">`, which is the correct native widget), company/address/phone/email, copyright, payment icons/social links (JSON-ish textarea), homepage section `columns` (a number, not an enum), widget-specific props (`hero`/`categories`/`product-collection` typed fields like layout/height/overlay/autoplay/cardsPerRow — these are widget `props` strings/booleans, not modeled as TypeScript unions anywhere, so they stay free text/checkbox with a description rather than a fabricated enum), navigation link label/URL, and the widget JSON fallback textarea for any widget type without a dedicated editor. These are genuinely open-ended or already have the correct native input type; converting them to `<select>` would either be wrong (URLs/colors/free text) or invent an enum that doesn't exist in the schema.
|
||||
Reference in New Issue
Block a user