fix(db): consistent starting xp in crew_skills seeder (#45)
This commit is contained in:
@@ -6,7 +6,7 @@ import { eq } from 'drizzle-orm'
|
||||
import { openGameDb, type GameDb } from '@/lib/db/client'
|
||||
import * as schema from '@/lib/db/schema'
|
||||
import { ROLES, generateStartingCrew, rollCrewMember, startingCrewRng } from './crew'
|
||||
import { STARTING_LEVELS, type SkillName } from './crew-costs'
|
||||
import { STARTING_LEVELS, XP_THRESHOLDS, type SkillName } from './crew-costs'
|
||||
import { MIN_AVAILABLE } from './missions'
|
||||
import { BASE_CAPACITY, BASE_LEVEL, SHIP_TYPES } from './ship-costs'
|
||||
import { TECHS } from './tech'
|
||||
@@ -745,7 +745,7 @@ describe('backfill (old saves)', () => {
|
||||
return Object.fromEntries(rows.map((r) => [r.skill, { level: r.level, xp: r.xp }]))
|
||||
}
|
||||
|
||||
it('v8: a v7-stamped save (crew present, no skills) seeds 4 role-based rows per member, xp 0, state untouched; idempotent across restart', async () => {
|
||||
it('v8: a v7-stamped save (crew present, no skills) seeds 4 role-based rows per member, xp consistent with level, state untouched; idempotent across restart', async () => {
|
||||
const { db, file } = await freshFile()
|
||||
await getWorldState(db) // fresh v8 save (crew_skills already seeded by createNewGame — JC-21)
|
||||
const save = (await db.db.select().from(schema.saves))[0]
|
||||
@@ -759,11 +759,11 @@ describe('backfill (old saves)', () => {
|
||||
const turnBefore = (await db.db.select().from(schema.saves))[0].turn
|
||||
await getWorldState(db) // ensureSave → backfill v7 → v8 → seedCrewSkills
|
||||
expect((await db.db.select().from(schema.saves))[0].schemaVersion).toBe(8)
|
||||
expect(await skillMap(db, pilot.id)).toEqual({ NAVIGATION: { level: 2, xp: 0 }, SCANNING: { level: 0, xp: 0 }, ENGINEERING: { level: 0, xp: 0 }, RESEARCH: { level: 0, xp: 0 } }) // PILOT
|
||||
expect(await skillMap(db, scientist.id)).toEqual({ NAVIGATION: { level: 0, xp: 0 }, SCANNING: { level: 2, xp: 0 }, ENGINEERING: { level: 0, xp: 0 }, RESEARCH: { level: 2, xp: 0 } }) // SCIENTIST
|
||||
expect(await skillMap(db, pilot.id)).toEqual({ NAVIGATION: { level: 2, xp: 10 }, SCANNING: { level: 0, xp: 0 }, ENGINEERING: { level: 0, xp: 0 }, RESEARCH: { level: 0, xp: 0 } }) // PILOT
|
||||
expect(await skillMap(db, scientist.id)).toEqual({ NAVIGATION: { level: 0, xp: 0 }, SCANNING: { level: 2, xp: 10 }, ENGINEERING: { level: 0, xp: 0 }, RESEARCH: { level: 2, xp: 10 } }) // SCIENTIST
|
||||
expect(await skillMap(db, gunner.id)).toEqual({ NAVIGATION: { level: 0, xp: 0 }, SCANNING: { level: 0, xp: 0 }, ENGINEERING: { level: 0, xp: 0 }, RESEARCH: { level: 0, xp: 0 } }) // GUNNER (all L0)
|
||||
for (const c of crewBefore) { // full invariant: EVERY member (incl. the random starting crew) matches its role map, xp 0
|
||||
const expected = Object.fromEntries((Object.keys(STARTING_LEVELS[c.role]) as SkillName[]).map((s) => [s, { level: STARTING_LEVELS[c.role][s], xp: 0 }]))
|
||||
for (const c of crewBefore) { // full invariant: EVERY member (incl. the random starting crew) matches its role map, xp = the level's threshold (levelFromXp round-trips)
|
||||
const expected = Object.fromEntries((Object.keys(STARTING_LEVELS[c.role]) as SkillName[]).map((s) => [s, { level: STARTING_LEVELS[c.role][s], xp: STARTING_LEVELS[c.role][s] > 0 ? XP_THRESHOLDS[STARTING_LEVELS[c.role][s] - 1] : 0 }]))
|
||||
expect(await skillMap(db, c.id)).toEqual(expected)
|
||||
}
|
||||
expect((await db.db.select().from(schema.saves))[0].turn).toBe(turnBefore) // Review Focus 1 (v8): turn / crew / inventory
|
||||
|
||||
Reference in New Issue
Block a user