ui: plan 01-27 done #1
+19
@@ -99,6 +99,25 @@ The intended v1 architecture is:
|
||||
format-compatible with GitHub Actions). Linux runners cover Tier 1
|
||||
tests; a macOS runner is provisioned only when Tier 2 iOS smoke is
|
||||
needed.
|
||||
- **Synthetic-report parser parity is a global rule.** A DEV-only
|
||||
loader on the lobby (`import.meta.env.DEV`) lets the developer feed
|
||||
the UI a JSON file that mimics a server `Report`, so the map and
|
||||
inspectors can be exercised against rich game states without playing
|
||||
many turns end-to-end. The JSON is produced by the Go CLI in
|
||||
`tools/local-dev/legacy-report/`, which converts legacy text
|
||||
reports under `tools/local-dev/reports/` into the shape of
|
||||
`pkg/model/report.Report` (whatever subset the UI currently
|
||||
decodes). Every phase that **extends the server→UI report contract**
|
||||
— adding decoding for a new `Report` field in
|
||||
`ui/frontend/src/api/game-state.ts` — must, in the same PR, extend
|
||||
the legacy parser to populate that field, **or** explicitly note in
|
||||
the parser's `README.md` that the field cannot be derived from the
|
||||
legacy text format and is left empty in synthetic JSON. The point
|
||||
is to keep `tools/local-dev/legacy-report/` a faithful (and
|
||||
type-checked, via `pkg/model/report` import) generator of test
|
||||
inputs as the UI grows; otherwise synthetic data silently lags
|
||||
behind the contract and visual tests stop covering the new
|
||||
behaviour.
|
||||
|
||||
## Information Architecture and Navigation
|
||||
|
||||
|
||||
@@ -109,6 +109,56 @@ mode off, troubleshooting common boot issues).
|
||||
The local-dev stack is independent from the local-ci stack below;
|
||||
they bind different ports and can run side by side.
|
||||
|
||||
## Synthetic reports for visual testing (DEV)
|
||||
|
||||
For visual checks of the map, inspectors and order-overlay against
|
||||
rich game states, the lobby exposes a DEV-only "Load synthetic
|
||||
report" affordance (`import.meta.env.DEV`). The flow is:
|
||||
|
||||
1. Convert a legacy text report (`tools/local-dev/reports/{dg,gplus}/`)
|
||||
to JSON with the Go CLI:
|
||||
|
||||
```sh
|
||||
go run ./tools/local-dev/legacy-report/cmd/legacy-report-to-json \
|
||||
--in tools/local-dev/reports/dg/KNNTS039.REP \
|
||||
--out /tmp/dg39.json
|
||||
```
|
||||
|
||||
See [`../../tools/local-dev/legacy-report/README.md`](../../tools/local-dev/legacy-report/README.md)
|
||||
for what the parser populates today and how to extend it when a
|
||||
new UI phase decodes a new `Report` field.
|
||||
|
||||
2. Run the UI dev server (`pnpm -C ui/frontend dev`), open the lobby,
|
||||
and use the "Load JSON…" file picker in the **Synthetic test
|
||||
reports (DEV)** section. The page navigates to
|
||||
`/games/synthetic-<uuid>/map` with the report wired into the
|
||||
in-game shell.
|
||||
|
||||
In synthetic mode:
|
||||
|
||||
- The map view, inspectors and races view render against the loaded
|
||||
report exactly as they would for a real game.
|
||||
- Composing orders works locally (overlay applies through
|
||||
`applyOrderOverlay` as usual), but **nothing is sent to the
|
||||
gateway** — `OrderDraftStore.scheduleSync` short-circuits because
|
||||
the synthetic id is not a UUID and the layout deliberately does
|
||||
not bind a `GalaxyClient` for this game.
|
||||
- The order draft is persisted into the platform `Cache` under the
|
||||
same `order-drafts` namespace as real games, keyed by the
|
||||
synthetic id, so navigating back into the same synthetic session
|
||||
restores the draft. The cache is cleared with
|
||||
`__galaxyDebug.clearOrderDraft(gameId)` (DEV debug surface).
|
||||
- A page reload loses the in-memory report registry; opening the
|
||||
same synthetic id afterwards redirects to /lobby. Re-load the JSON
|
||||
to reseed.
|
||||
|
||||
The synthetic-report parity rule (see [`../PLAN.md`](../PLAN.md) §
|
||||
Assumptions and Defaults) requires every UI phase that extends
|
||||
`decodeReport` to also extend the legacy parser in lockstep, or to
|
||||
record in the parser's `README.md` that the new field cannot be
|
||||
derived from legacy text. This keeps the synthetic-mode coverage in
|
||||
step with the contract as the UI grows.
|
||||
|
||||
## Local CI verification
|
||||
|
||||
`tools/local-ci/` ships a self-contained Gitea + Actions runner via
|
||||
|
||||
Reference in New Issue
Block a user