feat(game): tasks table + schema v7 backfill, admin registry (#44)

This commit is contained in:
2026-10-02 13:08:53 +00:00
parent f52a59c5fc
commit 6c51c3cec8
6 changed files with 78 additions and 1 deletions
+1
View File
@@ -18,6 +18,7 @@ export const ADMIN_TABLES = {
tech: schema.tech,
missions: schema.missions,
events: schema.events,
tasks: schema.tasks,
} as const satisfies Record<string, SQLiteTable>
const TABLE_NAMES: Set<string> = new Set(Object.values(ADMIN_TABLES).map((t) => getTableName(t)))
+13
View File
@@ -116,6 +116,19 @@ CREATE TABLE IF NOT EXISTS events (
message TEXT NOT NULL,
created_at TEXT NOT NULL
);
CREATE TABLE IF NOT EXISTS tasks (
id INTEGER PRIMARY KEY AUTOINCREMENT,
save_id INTEGER NOT NULL REFERENCES saves(id),
type TEXT NOT NULL, -- 'JUMP' | 'EXPLORE' | 'SHIP_UPGRADE' | 'SHIP_EXPAND' | 'SHIP_BUILD' | 'RESEARCH'
payload TEXT NOT NULL, -- JSON per type: JUMP {systemId, hops} · SHIP_UPGRADE/EXPAND {systemId} · SHIP_BUILD {type} · RESEARCH {techId} · EXPLORE {planetId}
lead_crew_id INTEGER NOT NULL REFERENCES crew(id),
helpers TEXT NOT NULL DEFAULT '[]', -- JSON array of crew ids
duration INTEGER NOT NULL,
remaining INTEGER NOT NULL,
status TEXT NOT NULL DEFAULT 'ACTIVE', -- 'ACTIVE' | 'PENDING' | 'DONE'
queued_at_turn INTEGER NOT NULL DEFAULT 0
);
`;
// SPACE_WANDERER_DB_PATH override exists so unit tests can point at a temp file instead
+17
View File
@@ -136,3 +136,20 @@ export const events = sqliteTable('events', {
message: text('message').notNull(),
createdAt: text('created_at').notNull(),
})
// Queued actions (PR A, spec §3): one row per task assigned to a team. `payload` is a JSON
// string whose shape depends on `type` (see the Task interface in lib/game/tasks.ts);
// `helpers` is a JSON array of crew ids. Upgraded saves start with an empty queue — the v7
// backfill stamps the version, the DDL in client.ts creates the table.
export const tasks = sqliteTable('tasks', {
id: integer('id').primaryKey({ autoIncrement: true }),
saveId: integer('save_id').notNull().references(() => saves.id),
type: text('type').notNull(), // TaskType
payload: text('payload').notNull(),
leadCrewId: integer('lead_crew_id').notNull().references(() => crew.id),
helpers: text('helpers').notNull().default('[]'), // JSON array of crew ids
duration: integer('duration').notNull(),
remaining: integer('remaining').notNull(),
status: text('status').notNull().default('ACTIVE'), // 'ACTIVE' | 'PENDING' | 'DONE'
queuedAtTurn: integer('queued_at_turn').notNull().default(0),
})