ui/phase-14: rename planet end-to-end + order read-back

Wires the first end-to-end command through the full pipeline:
inspector rename action → local order draft → user.games.order
submit → optimistic overlay on map / inspector → server hydration
on cache miss via the new user.games.order.get message type.

Backend: GET /api/v1/user/games/{id}/orders forwards to engine
GET /api/v1/order. Gateway parses the engine PUT response into the
extended UserGamesOrderResponse FBS envelope and adds
executeUserGamesOrderGet for the read-back path. Frontend ports
ValidateTypeName to TS, lands the inline rename editor + Submit
button, and exposes a renderedReport context so consumers see the
overlay-applied snapshot.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Ilia Denisov
2026-05-09 11:50:09 +02:00
parent 381e41b325
commit f80c623a74
86 changed files with 7505 additions and 138 deletions
@@ -0,0 +1,52 @@
// Provides a derived view of the server `GameReport` overlaid with
// the player's local order draft. Every consumer that needs to
// render the player's current intent (inspector, map, mobile sheet)
// subscribes through this context instead of reading `gameState.report`
// directly.
//
// Lifetime matches the in-game shell layout: one source per game,
// rebuilt on layout remount. The source itself is a thin reactive
// wrapper — the actual overlay computation lives in
// `applyOrderOverlay` (api/game-state.ts) and runs lazily on every
// access through the `report` getter.
import {
applyOrderOverlay,
type GameReport,
} from "../api/game-state";
import type { GameStateStore } from "./game-state.svelte";
import type { OrderDraftStore } from "../sync/order-draft.svelte";
/**
* RENDERED_REPORT_CONTEXT_KEY is the Svelte context key the in-game
* shell layout uses to expose a `RenderedReportSource` instance to
* descendants. Consumers read the latest overlay through `source.report`
* (a reactive getter) and re-render when the underlying stores
* change.
*/
export const RENDERED_REPORT_CONTEXT_KEY = Symbol("rendered-report");
export interface RenderedReportSource {
readonly report: GameReport | null;
}
/**
* createRenderedReportSource binds the live `GameStateStore` and
* `OrderDraftStore` to a getter that returns the overlay-applied
* report on every read. The getter is reactive: Svelte tracks the
* underlying `$state` accesses inside `applyOrderOverlay`, so any
* change to the report or the draft re-runs every dependent
* `$derived` block.
*/
export function createRenderedReportSource(
gameState: GameStateStore,
orderDraft: OrderDraftStore,
): RenderedReportSource {
return {
get report(): GameReport | null {
const raw = gameState.report;
if (raw === null) return null;
return applyOrderOverlay(raw, orderDraft.commands, orderDraft.statuses);
},
};
}