docs(editor): mark editor publish as backend-blocked local-only (FH-E.5)

Audited all 21 localStorage users against the "localStorage as source of
truth" objection. It was already false almost everywhere:

- Every admin facade (products, categories, orders, moderation,
  dashboard) uses localStorage only for view preferences - viewMode,
  density, visibleColumns, expandedIds, sort. Entity CRUD goes through
  the API gateways.
- currency-rates.service already removed its localStorage-typed rates.
- language, location region, search history, the anonymous session id,
  admin preferences - all legitimate cache/preference.
- The editor already shows an "unsaved local draft restored" banner
  (draftRestored -> save bar), which is the recovery-cache indicator this
  item called for.

One real gap remains and it is backend-blocked: project-editor
publish() applies config to the in-memory runtime and saves the draft to
localStorage, then declares itself published - no server round-trip,
because the PHASE-9 §5 revision API does not exist yet. Marked precisely
in publish() with the required behaviour (await the server, only then
mark published) and cross-referenced to the contract.

Nothing to rip out: the codebase was already at the target state
everywhere the backend exists to support it.

262 tests pass. Boundaries green.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
sdarbinyan
2026-08-21 22:41:14 +04:00
parent 1c87a53f02
commit b4772d10c7
2 changed files with 20 additions and 6 deletions

View File

@@ -508,6 +508,15 @@ export class ProjectEditorFacade {
if (!current || this.hasBlockingIssues()) {
return false;
}
// FH-E.5 / PHASE-9 §5. This is a LOCAL preview publish: it applies the
// config to the in-memory runtime and saves the draft to localStorage.
// localStorage is a recovery cache here (see draftRestored), never the
// published source of truth. Real publish must round-trip through the
// revision API - POST .../revisions/{id}/publish - which creates an
// immutable server-side revision and flips the published pointer in one
// transaction. Until that endpoint exists this stays local-only and must
// not be treated as authoritative; when it ships, this method awaits the
// server response and only then marks status 'published'.
this.runtime.reloadFromBootstrap(current);
const savedAt = this.draftStorage.save(current);
this.state.update(state => ({