docs(ui): finalize MVP plan structure and de-archaeologize topic docs

MVP web client (Phases 1-30) is complete; reorganize planning + living docs around that.

- PLAN.md kept as the staged MVP record (1-30) with a status block + pointers; removed the 31-36 stages, regression scenarios, and deferred-TODO section (moved out); fixed a stale cross-machine plan path.

- ui/PLAN-finalize.md (new): active web-finalization plan in 8 stages (visual system, a11y, i18n, error UX, PWA, build hygiene, docs, owner manual-QA loop); absorbs former Phases 33 and 35.

- ui/ROADMAP.md (new): post-MVP (Wails, Capacitor, realistic projection, acceptance + regression scenarios) and triaged deferred follow-ups.

- ui/docs/README.md (new): grouped topic-doc index.

- De-archaeologized all 20 ui/docs topic docs + ui/README.md + ui/core/README.md: stripped Phase-N build history, rewritten as current-state; deferred work now points at ROADMAP.md / PLAN-finalize.md. Docs-only; no code change.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Ilia Denisov
2026-05-21 23:17:51 +02:00
parent 51865b8cf4
commit a89048f6c5
26 changed files with 836 additions and 929 deletions
+8 -8
View File
@@ -1,9 +1,9 @@
# In-game diplomatic mail UI
Phase 28 wires the in-game mail view that consumes the `diplomail`
subsystem in the backend. The route lives at `/games/:id/mail`
(registered in Phase 10) and replaces the active view when the user
opens the "diplomatic mail" entry in the header menu.
The in-game mail view consumes the `diplomail` subsystem in the
backend. The route lives at `/games/:id/mail` and replaces the
active view when the user opens the "diplomatic mail" entry in the
header menu.
## Wire surface
@@ -29,8 +29,8 @@ the gateway translation lives in
## Recipient by race name
The compose flow does **not** consult a memberships listing. The
recipient picker reads `gameState.report.races[].name` (the Phase 22
projection of `report.player[]`), and the send request carries the
recipient picker reads `gameState.report.races[].name` (projected
from `report.player[]`), and the send request carries the
chosen race name as `recipient_race_name`. The backend resolves it
against `Memberships.ListMembers(gameID, "active")` and rejects with
`forbidden` if the matching member is no longer active. This keeps
@@ -55,8 +55,8 @@ projects the union of inbox and sent into:
`read_at` and `deleted_at` are not surfaced to the user in any pane
— they only drive the badge counter and the optimistic mark-read
state. This is intentional (per Phase 28 decisions): the user-facing
spec for diplomatic mail does not promise read receipts.
state. This is intentional: the user-facing spec for diplomatic mail
does not promise read receipts.
## Translation toggle