v1.0.0: players table + migration from singleton account (ISS-105)
CI / build + unit + e2e (pull_request) Successful in 14m25s

This commit is contained in:
2026-09-24 14:26:34 +00:00
parent 837aa60a7d
commit b2034ebc52
21 changed files with 258 additions and 166 deletions
+9 -6
View File
@@ -2,6 +2,7 @@ import { loadAirportsGeoJson } from '@/lib/airports';
import { haversineKm, initialBearingDeg } from '@/lib/geo';
import { weatherFor } from '@/lib/weather';
import { getGameDb } from '@/lib/db/client';
import { getLocalPlayer } from '@/lib/db/localPlayer';
import * as schema from '@/lib/db/schema';
import { catalogEntries, FUEL_PRICE_PER_L, PLANE_TYPES, SELL_FRACTION, type CatalogEntry } from './catalog';
import { fuelAtWeighted, progressAt, positionAt, windBurnFactor } from '@/lib/sim/movement';
@@ -114,19 +115,21 @@ export function sseFrame(snapshot: StateSnapshot): StateSnapshot {
}
export async function getStateSnapshot(): Promise<StateSnapshot> {
const { db } = await getGameDb();
const inst = await getGameDb();
const { db } = inst;
// NOTE: use plain select(), not the relational db.query.* API — in drizzle-orm
// 0.45.x the sql-js driver drops the result mapper for relational queries and
// returns raw rows keyed by SQL column names (snake_case, no type decoding).
const [accountRows, simRows, planeRows, packageRows] = await Promise.all([
db.select().from(schema.account),
// v1.0.0 (ISS-105): the snapshot's `account` field is now the local player row — same shape,
// resolved through the temporary single-player helper until multiplayer lands.
const [player, simRows, planeRows, packageRows] = await Promise.all([
getLocalPlayer(inst),
db.select().from(schema.simState),
db.select().from(schema.planes),
db.select().from(schema.packages),
]);
const accountRow = accountRows[0];
const simRow = simRows[0];
if (!accountRow || !simRow) throw new Error('game state missing account/sim_state row');
if (!simRow) throw new Error('game state missing sim_state row');
const fc = await loadAirportsGeoJson();
const nameByIcao = new Map(fc.features.map((f) => [f.properties.icao, f.properties.name]));
@@ -169,7 +172,7 @@ export async function getStateSnapshot(): Promise<StateSnapshot> {
};
return {
account: { cash: accountRow.cash, reputation: accountRow.reputation },
account: { cash: player.cash, reputation: player.reputation },
simState: { clockMs: simRow.clockMs },
catalog: catalogEntries(),
fuelPricePerL: FUEL_PRICE_PER_L,