Files
galaxy-game/ui/README.md
T
Ilia Denisov e31fb2c17a
Tests · UI / test (push) Failing after 9m28s
docs(ui): sync docs to the app-shell; fix stale nav comments
Rewrite ui/docs (navigation, order-composer, auth-flow, pwa-strategy,
game-state + secondary topic docs) and ui/README for the single-URL
app-shell (in-memory screens/views, Back→lobby via shallow routing,
sessionStorage restore + validation, return-to-lobby). ui/PLAN.md gets a
Phase-10 supersede note (implemented; standalone-compatible). Fix stale
code comments (session-store auth gate, report-sections spec contract).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-23 21:04:11 +02:00

192 lines
9.7 KiB
Markdown

# ui — Galaxy Cross-Platform Client
`ui/` hosts the new cross-platform Galaxy client. A single
TypeScript + Svelte source tree builds to five targets: web,
web-mobile, standalone PC (mac/win/linux), iOS, and Android. A
shared Go module (`ui/core`) carries envelope cryptography, the
FlatBuffers codec, keypair management, and a thin bridge over
`pkg/calc/` for UI-side game math; it is compiled to WASM for the
web targets, gomobile native libraries for mobile, and embedded
directly in Wails on desktop. All network I/O lives on the
TypeScript side via ConnectRPC, so the Go module is a pure compute
boundary on every platform.
The web target is a finalized, installable PWA: a shared design-token
system with light/dark themes, WCAG 2.2 AA accessibility, en/ru
localisation with a persisted choice, a central error surface, and
offline tolerance — see the topic docs below.
The legacy Fyne client under `client/` is reference-only.
Nothing in `ui/` imports from it.
The strategic rationale (why Svelte, why PixiJS, why Go-as-WASM, why
Wails+Capacitor) lives outside the repo at
`~/.claude/plans/buzzing-questing-fountain.md`. This README is a
quick orientation; deeper design notes live under `ui/docs/`.
## Targets
| Target | Wrapper | Toolchain | Status |
| --------------- | ---------------- | ----------------------- | ------------------------------ |
| web | browser tab | Vite + WASM | implemented |
| web-mobile | mobile browser | Vite + WASM | implemented |
| desktop (mac) | Wails v2 | Go + Wails CLI | planned (see ROADMAP.md) |
| desktop (win) | Wails v2 | Go + Wails CLI | planned (see ROADMAP.md) |
| desktop (linux) | Wails v2 | Go + Wails CLI | planned (see ROADMAP.md) |
| iOS | Capacitor | gomobile + Xcode | planned (see ROADMAP.md) |
| Android | Capacitor | gomobile + Gradle | planned (see ROADMAP.md) |
## Layered architecture
- **TypeScript + Svelte 5 frontend**, shared across all five targets,
scaffolded with SvelteKit + Vite.
- **PixiJS v8** with dual WebGPU/WebGL backend for the world map
renderer.
- **Go module `ui/core/`** as a compute-only library (canonical bytes,
Ed25519 sign/verify, FlatBuffers codec, keypair, thin bridge to
`pkg/calc/`) compiled to WASM, gomobile, and Wails-embedded native.
- **TypeScript-side `Core` interface** with three adapters
(`WasmCore`, `WailsCore`, `CapacitorCore`) selected at build time.
- **`GalaxyClient`** on top of `Core` performs all network I/O via
ConnectRPC (`@connectrpc/connect-web`) on every platform.
- **Per-platform storage:** WebCrypto + IndexedDB on web, OS keychain
+ SQLite on desktop, iOS Keychain / Android Keystore + SQLite on
mobile, all behind a single `KeyStore` and `Cache` TypeScript
interface.
- **Single-URL app-shell navigation:** the game UI is one route served
at `/game/`; the screen (login / lobby / game) and the in-game view
are in-memory state (`lib/app-nav.svelte.ts`), not URLs, so the
address bar never changes. Browser Back/Forward move between screens
via shallow routing without touching the URL — a model that also
suits the bundled standalone targets (Wails / Capacitor) that have no
URLs. One active view occupies the main area at a time; the sidebar
holds a single tool (calculator, inspector, or order) with persistent
state on switch. See [`docs/navigation.md`](docs/navigation.md).
## Repository layout
```text
ui/
├── PLAN.md staged implementation plan
├── ROADMAP.md planned desktop / mobile / multi-turn features
├── PLAN-finalize.md PWA, accessibility, localisation, error UX
├── Makefile wasm / ts-protos / web / mobile / desktop targets
├── README.md this file
├── buf.gen.yaml local-plugin TS Protobuf-ES generator
├── docs/ topic-based design notes
│ ├── auth-flow.md email-code login, session store, revocation
│ ├── i18n.md translation primitive, native-name picker, extensibility
│ ├── order-composer.md order draft model, persistence, history-mode wiring
│ ├── storage.md web KeyStore/Cache, IDB schema, baseline
│ ├── testing.md per-PR / release test tiers
│ └── wasm-toolchain.md TinyGo build, JSDOM loading, bundle budget
├── core/ ui/core Go module (canonical bytes, keypair)
├── wasm/ TinyGo entry point exposing Core to JS
├── mobile-bridge/ gomobile bindings (planned — see ROADMAP.md)
├── desktop/ Wails project (planned — see ROADMAP.md)
├── mobile/ Capacitor project (planned — see ROADMAP.md)
└── frontend/ SvelteKit / Vite source
├── src/api/ GalaxyClient + typed Connect client + auth + session
├── src/lib/ app-shell nav + screens + game shell, env config, session store, stores
├── src/platform/core/ Core interface + WasmCore adapter
├── src/platform/store/ KeyStore/Cache interfaces + web adapter
├── src/proto/ generated Protobuf-ES + Connect descriptors + FlatBuffers TS bindings
├── src/routes/ single-URL app-shell: `/game/` dispatcher (+page.svelte) + `/__debug/*`
└── static/ core.wasm + wasm_exec.js (built by `make wasm` / CI; gitignored)
```
Linked topic docs:
- [`docs/navigation.md`](docs/navigation.md) — single-URL app-shell,
screens and views as in-memory state, screen history, sidebar tools.
- [`docs/auth-flow.md`](docs/auth-flow.md) — email-code login,
session store state machine, revocation watcher.
- [`docs/lobby.md`](docs/lobby.md) — lobby UI sections, application
/ invite lifecycle, create-game form defaults.
- [`docs/i18n.md`](docs/i18n.md) — translation primitive, native-name
language picker, recipe for adding a new locale.
- [`docs/storage.md`](docs/storage.md) — web KeyStore/Cache,
IndexedDB schema, browser baseline.
- [`docs/order-composer.md`](docs/order-composer.md) — local
order draft store, persistence, history-mode wiring.
- [`docs/wasm-toolchain.md`](docs/wasm-toolchain.md) — TinyGo build,
loading recipe, bundle size budget.
- [`docs/design-system.md`](docs/design-system.md) — design tokens,
light/dark theming, component conventions.
- [`docs/a11y.md`](docs/a11y.md) — WCAG 2.2 AA approach, axe + keyboard
gates, shared a11y primitives.
- [`docs/error-state-ux.md`](docs/error-state-ux.md) — central error
surface, shared loading/empty/error states, selection marker, sheet
dismissal.
- [`docs/pwa-strategy.md`](docs/pwa-strategy.md) — installable, offline
PWA: service worker, manifest, icons.
- [`docs/testing.md`](docs/testing.md) — Tier 1 per-PR + Tier 2
release test tiers.
## Build pipeline
Every cross-target build flows through `make` at this level.
Native targets are placeholders until their platform work lands;
running `make` with no arguments prints the current placeholder map.
```text
make web Vite production build
make wasm TinyGo → core.wasm
make ts-protos Connect-ES + Protobuf-ES gen
make fbs-ts FlatBuffers TS bindings via flatc
make gomobile gomobile bind → ios + android (planned — see ROADMAP.md)
make desktop-mac Wails build for darwin (planned — see ROADMAP.md)
make desktop-win Wails build for windows (planned — see ROADMAP.md)
make desktop-linux Wails build for linux (planned — see ROADMAP.md)
make ios Capacitor + xcodebuild (planned — see ROADMAP.md)
make android Capacitor + gradle (planned — see ROADMAP.md)
make all every target above
```
## Local development
For UI work against a real stack, the `tools/local-dev/` docker
compose brings up postgres + redis + mailpit + backend + gateway in
one command, and `ui/frontend/.env.development` is already wired to
talk to it:
```sh
make -C tools/local-dev up # build + start, wait for healthy
pnpm -C ui/frontend dev # Vite on the host
# UI: http://localhost:5173
# Mailpit: http://localhost:8025
```
The stack accepts a fixed dev code (`123456`) in addition to the
real Mailpit-delivered one. Full runbook in
[`../tools/local-dev/README.md`](../tools/local-dev/README.md).
For testing the production-shaped surface — Caddy in front of the
gateway, statically served UI bundle, real `https://*.galaxy.lan`
hostnames — use the long-lived dev environment at
[`../tools/dev-deploy/`](../tools/dev-deploy/README.md). It is
redeployed by Gitea Actions on every merge into `development`.
## Topic docs
Topic docs live under `ui/docs/` (testing tiers, WASM toolchain,
navigation shell, renderer internals, sync protocol, auth flow, and
so on).
## Cross-references
- [`PLAN.md`](./PLAN.md) — staged implementation plan (historical
record of completed work).
- [`ROADMAP.md`](./ROADMAP.md) — planned desktop / mobile / multi-turn
projection features.
- [`PLAN-finalize.md`](./PLAN-finalize.md) — PWA, accessibility,
localisation, error UX finalization work.
- [`../docs/ARCHITECTURE.md`](../docs/ARCHITECTURE.md) — platform
architecture and the transport security model (§15) the client
envelope contract derives from.
- [`../docs/FUNCTIONAL.md`](../docs/FUNCTIONAL.md) — per-domain user
stories that drive the UI flows.
- [`../docs/TESTING.md`](../docs/TESTING.md) — project-wide testing
layers; UI-specific test tiers (Vitest, Playwright) live in
`ui/docs/testing.md`.