Files
galaxy-game/ui/ROADMAP.md
T
Ilia Denisov a89048f6c5 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>
2026-05-21 23:17:51 +02:00

7.7 KiB
Raw Blame History

UI Client — Post-MVP Roadmap

The MVP web client (Phases 130 of PLAN.md) is complete. The near-term web finalization pass — visual system, accessibility, localisation, error UX, PWA, docs — is tracked separately in PLAN-finalize.md.

This roadmap holds the work deliberately deferred until after the web client is finalized: the native platform wrappers, the realistic multi-turn projection (a feature, not polish), the cross-platform acceptance pass, and a set of non-blocking follow-ups. Items keep their original PLAN.md phase numbers for continuity; their full original specs live in the PLAN.md git history.


Phase 31 — Wails Desktop Wrapper

Goal: native desktop app (macOS, Windows, Linux) running the same frontend bundle, with ui/core embedded as Go instead of WASM.

Key artifacts: ui/desktop/ Wails entry + IPC bindings; per-OS secure storage (macOS Keychain, Windows DPAPI, Linux Secret Service with a 0600 file fallback); modernc.org/sqlite cache; WailsCore / WailsKeyStore / WailsCache adapters; OS icons; ui/Makefile desktop-* targets; ui/docs/desktop-secure-storage.md. Re-evaluate Wails v2 vs v3 at phase start.

Depends on: Phase 6 (KeyStore/Cache interfaces) and the web form of Phases 730. Acceptance: all three OS binaries launch, log in, and persist the keypair on a fresh profile from one codebase; Linux file fallback activates without libsecret and writes 0600.

Phase 32 — Capacitor Mobile Wrapper

Goal: native iOS and Android apps running the same frontend bundle, calling a gomobile-compiled ui/core.

Key artifacts: ui/mobile-bridge/bridge.go gomobile façade; ui/Makefile gomobile/ios/android targets; Capacitor project + custom galaxy-core plugin (Swift + Kotlin); CapacitorCore / CapacitorKeyStore / CapacitorCache adapters (secure-storage + sqlite community plugins); app icons + splash; ui/docs/mobile-bridge.md.

Depends on: Phase 6 and the web form of Phases 730. Acceptance: iOS Simulator and Android Emulator launch, log in, and persist the keypair across restarts (manual smoke); same Core/Storage TS interfaces as web/desktop. Full Appium automation lands in Phase 36.

Phase 34 — Multi-Turn Projection (realistic planet forecast)

Goal: a realistic multi-turn planet projection, surfaced in the planet inspector and the calculator's planet area. (Reach circles already shipped in Phase 30; this phase no longer owns them.)

The Phase 30 planet area is single-turn (MAT-only). This phase makes it realistic and multi-turn by extracting the planet economy into pkg/calc (single-sourced, engine delegates): PlanetProduction, ProducePopulation, UnpackColonists, UnpackCapital, reusing ProduceShipsInTurn; plus a ProjectPlanetBuild projector ("K ships in M turns" under guaranteed per-turn supply) mirroring MakeTurn steps 09/12/14/15. CAP and COL only affect future turns (post-production unpacking), so they become meaningful here and join MAT as supply inputs in the calculator's planet area.

Key artifacts: the pkg/calc economy extraction + bridges + Core typings; planet-inspector forecast section (next-turn population, industry, materials, progress); calculator planet area gains CAP/COL supply; ui/docs/multi-turn-projection.md.

Depends on: Phases 17, 18, 30. Acceptance: projector output byte- identical to running the engine's per-turn planet update over the same turns (Go parity); inspector + calculator readouts consistent with it.

Phase 36 — Acceptance Pass

Goal: reconcile implementation, documentation, and regression coverage before declaring the client ready for technical beta.

Key artifacts: final cross-platform regression run on a release candidate; ui/docs/release-checklist.md; visual-regression baselines; Appium harness (iOS Simulator + Android Emulator) covering login, push, and a full turn loop, wired into a macOS-runner CI job as a pre-release gate; a docs/README/ARCHITECTURE/FUNCTIONAL drift sweep.

Depends on: Phases 135 (incl. the finalization plan). Acceptance: implementation matches every documented contract; the cross-cutting regression scenarios below pass on web, desktop, and mobile; Appium smoke passes on iOS and Android in CI.

Cross-cutting regression scenarios

  • A fresh device generates a keypair, completes email-code login, and signs a follow-up authenticated request on every platform.
  • A returning device resumes its session without re-login, preserves queued orders, and keeps receiving push events without gaps.
  • Server-side session revocation tears down the push stream and forces re-login on every platform within one second.
  • Tampering with payload_bytes, payload_hash, request_id, message_type, or any signature byte is rejected by ui/core with a stable error code.
  • Requests outside the freshness window are rejected before network; a clock-skew warning surfaces when the local clock disagrees beyond it.
  • The map renderer holds 60 fps with a 1000-primitive fixture on web (Chrome, Edge, Safari, Firefox), desktop (Wails on mac/win/linux), and mobile (latest iPhone, mid-range Android).
  • The sidebar preserves tool state across tab switches; the active view preserves state across view switches.
  • Order draft survives reloads, view switches, network drops, and history-mode entry/exit.
  • Orders queued offline flush in order on reconnect; a turn-cutoff conflict surfaces as a failed-order banner without retrying forever.
  • History mode applies to every view; the order tab disappears in history mode and the prior draft is restored on return.
  • The calculator's math matches pkg/calc/ byte-for-byte; drift fails CI.
  • Linux desktop without Secret Service completes login via the 0600 file fallback.
  • The web service worker invalidates on app update and never serves stale code on the first load after deploy.
  • Push-event signature verification is mandatory; any failure tears down the stream and reconnects with backoff.
  • Locale switch persists across reloads and applies to every visible string on every platform.

Deferred follow-ups (non-blocking)

Explicit deferral decisions, to fold into the phase noted when it lands. (The "build core.wasm in CI / drop the committed artefact" follow-up moved to PLAN-finalize.md F6, since it is timely.)

  • Restore js.CopyBytesToGo when TinyGo fixes the instanceof Uint8Array check — the per-element loop in ui/wasm/main.go::copyBytesFromJS is a TinyGo 0.41 workaround. Track upstream and revert once a fixed release is pinned.
  • Migrate TS codegen to the Connect-ES v2 BSR plugin once published — ui/buf.gen.yaml runs protoc-gen-es v2 locally because buf.build/connectrpc/es still emits v1-incompatible imports.
  • Rename gateway/internal/grpcapi/connectapi/ — historical name; the package serves Connect/gRPC/gRPC-Web. Pure rename. (Fold into the next gateway change; not a UI task.)
  • Rename GATEWAY_AUTHENTICATED_GRPC_* env vars to drop the GRPC infix — they label the authenticated edge tier, not the wire protocol. (Coordinate with the rename above; not a UI task.)
  • Add a Docker-stack Connect end-to-end integration testintegration/connect_call_test.go exercising a unary + a server-streaming Connect call through testenv.Bootstrap.
  • Battle viewer — push event game.battle.new — emit a backend notification intent (idempotency battle-new:<game_id>:<turn>:<battle_id>) so the shell shows a toast deep-linking into the Battle Viewer. Needs an engine emit-side change.
  • Battle viewer — richer ship-class visuals — derive shape/scale from mass, armament, shields, and ship count instead of the MVP one-circle-plus-label per (race, className).