v1.0.0: players table + migration from singleton account (ISS-105) #151

Merged
kamilkrzywda merged 1 commits from feat/multiplayer-players-table into master 2026-09-24 16:41:52 +02:00
Owner

Multiplayer step 1/12 — pure schema change, no behavior change.

What changed

  • players table (id TEXT PK, provider, username, cash REAL, reputation REAL) in the raw DDL (lib/db/client.ts) and Drizzle schema (lib/db/schema.ts; AccountRow → PlayerRow). The singleton account table is gone from fresh DBs.
  • One-time migration in open(): if a legacy file still has account (sqlite_master guard, same style as the v0.12.0 contracts migration) and players is empty, its single row is copied into a seeded local player — id local, provider local, username kamilkrzywda (joinable to users later) with cash/reputation carried over — then DROP TABLE account. Idempotent; runs exactly once per legacy file.
  • Fresh worlds: first-run seed check flipped from COUNT(*) FROM account to players; seedEmpty() inserts the local player row directly (same starting values).
  • Temporary single-player helper (lib/db/localPlayer.ts): getLocalPlayer(inst) + updateLocalPlayerEconomy(inst, {cash?, reputation?}). Every economy read/write now routes through it — snapshot (state.ts), all five actions, engine delivery/top-up/spawn reads, and the three test hooks. Will be parameterized by playerId in a later step.
  • API unchanged: /api/state keeps its account: {cash, reputation} field name and values; OpenAPI untouched (17 paths).

Tests

  • Fresh DB asserts the seeded local player row AND no account table; new dedicated migration test builds a minimal legacy file with only an account table → copied, dropped, second open is a no-op.
  • All existing suites converted to the helper (actions, engine, client, buy/sell/abandon routes); admin rows CRUD's PK-less example moves account → sim_state; tables-list expectation swaps account → players.
  • No new e2e spec — behavior byte-identical; CI's existing suite covers UI paths and fresh-stack boot exercises the new seed.

Local: tsc --noEmit clean, vitest run 411/411 (38 files), playwright test --list 64 tests in 17 files.

Multiplayer step 1/12 — pure schema change, no behavior change. ## What changed - **`players` table** (`id TEXT PK`, `provider`, `username`, `cash REAL`, `reputation REAL`) in the raw DDL (`lib/db/client.ts`) and Drizzle schema (`lib/db/schema.ts`; `AccountRow` → `PlayerRow`). The singleton `account` table is gone from fresh DBs. - **One-time migration** in `open()`: if a legacy file still has `account` (sqlite_master guard, same style as the v0.12.0 contracts migration) and `players` is empty, its single row is copied into a seeded local player — id `local`, provider `local`, username `kamilkrzywda` (joinable to `users` later) with cash/reputation carried over — then `DROP TABLE account`. Idempotent; runs exactly once per legacy file. - **Fresh worlds**: first-run seed check flipped from `COUNT(*) FROM account` to `players`; `seedEmpty()` inserts the local player row directly (same starting values). - **Temporary single-player helper** (`lib/db/localPlayer.ts`): `getLocalPlayer(inst)` + `updateLocalPlayerEconomy(inst, {cash?, reputation?})`. Every economy read/write now routes through it — snapshot (`state.ts`), all five actions, engine delivery/top-up/spawn reads, and the three test hooks. Will be parameterized by playerId in a later step. - **API unchanged**: `/api/state` keeps its `account: {cash, reputation}` field name and values; OpenAPI untouched (17 paths). ## Tests - Fresh DB asserts the seeded local player row AND no `account` table; new dedicated migration test builds a minimal legacy file with only an `account` table → copied, dropped, second open is a no-op. - All existing suites converted to the helper (actions, engine, client, buy/sell/abandon routes); admin rows CRUD's PK-less example moves `account` → `sim_state`; tables-list expectation swaps `account` → `players`. - No new e2e spec — behavior byte-identical; CI's existing suite covers UI paths and fresh-stack boot exercises the new seed. Local: `tsc --noEmit` clean, `vitest run` 411/411 (38 files), `playwright test --list` 64 tests in 17 files.
kamilkrzywda added 1 commit 2026-09-24 16:27:23 +02:00
v1.0.0: players table + migration from singleton account (ISS-105)
CI / build + unit + e2e (pull_request) Successful in 14m25s
b2034ebc52
kamilkrzywda scheduled this pull request to auto merge when all checks succeed 2026-09-24 16:31:21 +02:00
kamilkrzywda merged commit 21dd37f88c into master 2026-09-24 16:41:52 +02:00
Sign in to join this conversation.