Nation-op proposals (P4a, #16): protocol types, pendingNationOps state, engine propose/resolve (stage 1)
- shared/protocol.ts: RenameOp/SplitOp/MergeOp + NationOp union; TurnResult.nationOps (required); ConfirmNationOp/RejectNationOp request+response types - shared/types.ts: GameState.pendingNationOps (type-only import of NationOp — no runtime cycle) - server/engine.ts: validateNationOps parser wired into validateTurnResult; isMeaningful counts proposals; applyTurnResult appends to the surviving pending list (never applies); runTurn fallback literal; system prompt gains the nationOps JSON field + rename proposal rule (both modes); new resolveNationRef/applyNationOp/confirmNationOp/rejectNationOp (id-first then unique case-insensitive name; rename changes Nation.name only; split/merge no-op until P4b; index validation returns null for 400) - server/db.ts: legacy rows load with pendingNationOps defaulted to [] - server/index.ts: fresh games start with pendingNationOps: [] - server/stub.ts: deterministicTurn returns nationOps: [] (the stub never proposes — unit-only coverage, matching P3) - tests: fixture updates (engine/db/map/regions) + new suites for resolveNationRef, validateNationOps, proposal lifecycle, confirm/reject (151 tests total)
This commit is contained in:
@@ -43,6 +43,9 @@ export function openDb(filePath: string): Db {
|
||||
// (v0.22, #16 P3) Rows saved before `GameState.unowned` existed load
|
||||
// with it defaulted: a legacy game has no no-man's-land regions.
|
||||
if (state.unowned === undefined) state.unowned = [];
|
||||
// (v0.23, #16 P4a) Same for pending nation-op proposals: a legacy game
|
||||
// has none awaiting confirm/reject.
|
||||
if (state.pendingNationOps === undefined) state.pendingNationOps = [];
|
||||
return state;
|
||||
} catch {
|
||||
return null;
|
||||
|
||||
Reference in New Issue
Block a user