docs(project-editor): document Sprint 16 tabs, draft/publish gap, and validation rules

This commit is contained in:
sdarbinyan
2026-07-13 15:29:21 +04:00
parent 26c07fb3e6
commit a8b2b4bf0b
2 changed files with 42 additions and 8 deletions

View File

@@ -88,6 +88,14 @@ Future backend integration:
- export JSON - export JSON
- import JSON - import JSON
- runtime preview without full browser refresh - runtime preview without full browser refresh
- Languages (Sprint 16)
- add/remove supported locale
- set default locale
- generically syncs translation keys across static pages and navigation labels (`LocaleSyncService`)
- Navigation (Sprint 16)
- header navigation: add/remove/reorder/edit label/URL/visibility
- flat footer navigation: same actions
- grouped footer navigation (column-based) is read-only in this tab for now
## Preview Strategy ## Preview Strategy
@@ -120,15 +128,36 @@ Current widget editor supports explicit fields for:
Other widgets use JSON props fallback until dedicated editors are added. Other widgets use JSON props fallback until dedicated editors are added.
## Future Backend Endpoints ## Draft / Publish (Sprint 16)
Recommended future builder endpoints: There is still no backend draft/publish API. This sprint models it client-side
- `GET /builder/bootstrap` in `ProjectEditorFacade`:
- `PUT /builder/bootstrap` - `status: 'draft' | 'published'` and `dirty` (diffed against the
- `POST /builder/bootstrap/preview` last-saved snapshot) live in facade state.
- `POST /builder/bootstrap/validate` - `save()` snapshots the current in-memory bootstrap as "last saved" (no
- `POST /builder/bootstrap/import` network call yet).
- `GET /builder/bootstrap/export` - `publish()` runs `ProjectValidator`, and if there are no issues, applies
the bootstrap via `PlatformRuntimeService.reloadFromBootstrap` and marks
status `published`.
**Backend gap, not yet implemented:** real persistence needs
`PUT /builder/bootstrap/draft` and `POST /builder/bootstrap/publish`
endpoints so drafts/publishes survive a reload and are shared across editors.
## Validation
`ProjectValidator` (`services/project-validator.service.ts`) runs on every
render of the save bar: missing logo, no languages, invalid marketplace URL,
duplicate static-page slugs, empty homepage, a homepage widget with no
`type`, duplicate header navigation links, invalid theme colors. Publish is
blocked while any issue is present; Save is not.
## Rich HTML editing
Static page HTML is edited via `MarketplaceHtmlEditorComponent`
(`components/html-editor/`), a `contentEditable` + toolbar component with no
external dependency. It emits raw HTML on every change and never sanitizes —
sanitization remains a storefront-render concern.
## Constraints ## Constraints

View File

@@ -0,0 +1,5 @@
{"id":"PE-20260713T010000Z-0001","subject":"project-editor-routing","predicate":"is","object":"flat routes under /edit/:section (no projectId — a project is the domain-resolved tenant); /builder and /project-editor redirect to /edit/general","src":["docs/superpowers/specs/2026-07-13-marketplace-project-editor-sprint16-design.md","src/app/app.routes.ts"],"status":"active","kind":"decision","updated_at":"2026-07-13T01:00:00Z","confidence":"high","tags":["project-editor","routing"]}
{"id":"PE-20260713T010000Z-0002","subject":"locale-sync","predicate":"is-implemented-by","object":"LocaleSyncService, which generically adds/removes a locale key across static page translations and navigation labels without per-field hardcoding","src":["src/app/features/project-editor/services/locale-sync.service.ts"],"status":"active","kind":"implemented","confidence":"high","updated_at":"2026-07-13T01:00:00Z","tags":["project-editor","i18n"]}
{"id":"PE-20260713T010000Z-0003","subject":"draft-publish-flow","predicate":"is","object":"client-side only (ProjectEditorFacade.status/dirty/save/publish) because no backend draft/publish endpoint exists yet; PUT /builder/bootstrap/draft and POST /builder/bootstrap/publish are the documented backend gap","src":["docs/Project-Editor.md","src/app/features/project-editor/facade/project-editor.facade.ts"],"status":"active","kind":"constraint","confidence":"high","updated_at":"2026-07-13T01:00:00Z","tags":["project-editor","backend-gap"]}
{"id":"PE-20260713T010000Z-0004","subject":"html-editing","predicate":"uses","object":"MarketplaceHtmlEditorComponent, a contentEditable + toolbar component with no external rich-text dependency; emits raw HTML, never sanitizes during editing","src":["src/app/features/project-editor/components/html-editor/marketplace-html-editor.component.ts"],"status":"active","kind":"decision","confidence":"high","updated_at":"2026-07-13T01:00:00Z","tags":["project-editor","html-editor"]}
{"id":"PE-20260713T010000Z-0005","subject":"navigation-tab","predicate":"supports","object":"header navigation and flat-list footer navigation (add/remove/reorder/edit); grouped-column footer navigation is read-only until a future sprint","src":["src/app/features/project-editor/sections/navigation-section.component.ts"],"status":"active","kind":"constraint","confidence":"high","updated_at":"2026-07-13T01:00:00Z","tags":["project-editor","navigation"]}