db+game: ship_systems table + starting ship seed (new game and v4 backfill step)

This commit is contained in:
2026-09-28 23:32:04 +00:00
parent c7580d92bd
commit 0910891995
5 changed files with 108 additions and 3 deletions
+9
View File
@@ -72,6 +72,15 @@ CREATE TABLE IF NOT EXISTS crew (
origin TEXT NOT NULL -- 'STARTING CREW' or '<planet>, <system>' for members found while exploring
);
CREATE TABLE IF NOT EXISTS ship_systems (
id INTEGER PRIMARY KEY AUTOINCREMENT,
save_id INTEGER NOT NULL REFERENCES saves(id),
type TEXT NOT NULL,
level INTEGER NOT NULL DEFAULT 0, -- 0 = not built yet ('built' is derived: level > 0)
capacity INTEGER NOT NULL DEFAULT 0,
UNIQUE (save_id, type)
);
CREATE TABLE IF NOT EXISTS events (
id INTEGER PRIMARY KEY AUTOINCREMENT,
save_id INTEGER NOT NULL REFERENCES saves(id),
+15 -1
View File
@@ -1,4 +1,4 @@
import { integer, primaryKey, real, sqliteTable, text } from 'drizzle-orm/sqlite-core'
import { integer, primaryKey, real, sqliteTable, text, uniqueIndex } from 'drizzle-orm/sqlite-core'
// Drizzle schema for game state. Single-player by design: exactly ONE save row ever exists
// (no auth/accounts), so every table hangs off saves.id but only one save is in play.
@@ -74,6 +74,20 @@ export const crew = sqliteTable('crew', {
origin: text('origin').notNull(),
})
// The ship's systems, one row per known type (see SHIP_TYPES in lib/game/ship-costs.ts).
// `built` is derived, not stored: level > 0 means built — unbuilt rows sit at level/capacity 0.
export const shipSystems = sqliteTable(
'ship_systems',
{
id: integer('id').primaryKey({ autoIncrement: true }),
saveId: integer('save_id').notNull().references(() => saves.id),
type: text('type').notNull(),
level: integer('level').notNull().default(0), // 0 = not built yet
capacity: integer('capacity').notNull().default(0),
},
(t) => [uniqueIndex('ship_systems_save_type_unique').on(t.saveId, t.type)],
)
// Append-only game log. Writers so far: new-game + jump events; later issues add more
// writers and a read endpoint.
export const events = sqliteTable('events', {