fix(reference): select verified station deterministically

This commit is contained in:
jb
2026-09-19 09:57:48 -04:00
parent 18515efbdf
commit 0c03a59b02
3 changed files with 16 additions and 9 deletions
+3 -2
View File
@@ -202,6 +202,7 @@ export function createReferenceSchema(db: Database): void {
CREATE INDEX systems_name_idx ON systems(name);
CREATE INDEX gates_destination_idx ON gates(destination_system_id);
CREATE INDEX stations_system_idx ON stations(system_id);
CREATE INDEX stations_source_verified_idx ON stations(source_verified, station_id);
`);
}
@@ -209,7 +210,7 @@ export function createReferenceSchema(db: Database): void {
export function assertReferenceReaderSchema(db: Database): void {
const version = Number((db.query<{ user_version: number }, []>('PRAGMA user_version').get() as { user_version: number } | null)?.user_version ?? 0);
const row = db.query<{ present: number }, []>("SELECT COUNT(*) AS present FROM sqlite_master WHERE type='table' AND name IN ('types','type_search','type_search_fts','categories','groups','regions','constellations','systems','stations')").get();
const index = db.query<{ present: number }, []>("SELECT COUNT(*) AS present FROM sqlite_master WHERE type='index' AND name='type_search_normalized_name_idx'").get();
const indexes = db.query<{ present: number }, []>("SELECT COUNT(*) AS present FROM sqlite_master WHERE type='index' AND name IN ('type_search_normalized_name_idx','stations_source_verified_idx')").get();
const requiredColumns: Record<string, string[]> = {
types: ['type_id', 'group_id', 'category_id', 'name_json', 'published', 'volume'],
type_search: ['type_id', 'language', 'name', 'normalized_name'],
@@ -225,7 +226,7 @@ export function assertReferenceReaderSchema(db: Database): void {
const present = new Set(db.query<{ name: string }, []>(`PRAGMA table_info(${table})`).all().map((column) => column.name));
return columns.every((column) => present.has(column));
});
if (version !== SCHEMA_VERSION || !row || Number(row.present) !== 9 || !index || Number(index.present) !== 1 || !columnsValid) throw new Error(`active reference database has an incompatible schema version (expected ${SCHEMA_VERSION})`);
if (version !== SCHEMA_VERSION || !row || Number(row.present) !== 9 || !indexes || Number(indexes.present) !== 2 || !columnsValid) throw new Error(`active reference database has an incompatible schema version (expected ${SCHEMA_VERSION})`);
}
const bool = (value: boolean | undefined): number | null => value === undefined ? null : value ? 1 : 0;
+9 -5
View File
@@ -1,5 +1,6 @@
import { expect, test } from 'bun:test';
import { cp, mkdtemp, readFile, rm, writeFile } from 'node:fs/promises';
import { Database } from 'bun:sqlite';
import { join } from 'node:path';
import { tmpdir } from 'node:os';
import { ReferenceCompiler, SqliteReferenceRepository, readReferenceManifest } from '../src/lib/server/reference';
@@ -15,8 +16,8 @@ test('reference readers search normalized types and expose group/category/system
const universe = JSON.parse(await readFile(universePath, 'utf8')) as Record<string, unknown>;
universe.regions = { '10000001': { region_id: 10000001, name: 'The Forge' } };
universe.constellations = { '20000020': { constellation_id: 20000020, name: 'Kimotoro', region_id: 10000001 } };
universe.stations = { '60003760': { station_id: 60003760, system_id: 30000142, name: 'Jita IV - Moon 4 - Caldari Navy Assembly Plant', type_id: 587, owner_id: 1000035, position: { x: 1, y: 2, z: 3 } } };
(universe.systems as Record<string, Record<string, unknown>>)['30000142'].stations = [60003761];
universe.stations = { '60003761': { station_id: 60003761, system_id: 30000142, name: 'Jita IV - Moon 4 - Caldari Navy Assembly Plant', type_id: 587, owner_id: 1000035, position: { x: 1, y: 2, z: 3 } } };
(universe.systems as Record<string, Record<string, unknown>>)['30000142'].stations = [60003760];
await writeFile(universePath, JSON.stringify(universe));
const result = await new ReferenceCompiler({ directory, profile: 'fixture', sources: fixtureSources(sources) }).compile();
@@ -32,10 +33,13 @@ test('reference readers search normalized types and expose group/category/system
const stations = await reader.stations({ systemId: 30000142 });
expect(stations).toHaveLength(2);
expect(stations).toEqual([
{ id: 60003760, systemId: 30000142, systemName: 'Jita', regionId: 10000001, evidence: 'verified', sourceVerified: true, name: 'Jita IV - Moon 4 - Caldari Navy Assembly Plant', typeId: 587, ownerId: 1000035, x: 1, y: 2, z: 3 },
{ id: 60003761, systemId: 30000142, systemName: 'Jita', regionId: 10000001, evidence: 'system_listed', sourceVerified: false, name: null, typeId: null, ownerId: null, x: null, y: null, z: null },
{ id: 60003760, systemId: 30000142, systemName: 'Jita', regionId: 10000001, evidence: 'system_listed', sourceVerified: false, name: null, typeId: null, ownerId: null, x: null, y: null, z: null },
{ id: 60003761, systemId: 30000142, systemName: 'Jita', regionId: 10000001, evidence: 'verified', sourceVerified: true, name: 'Jita IV - Moon 4 - Caldari Navy Assembly Plant', typeId: 587, ownerId: 1000035, x: 1, y: 2, z: 3 },
]);
expect(await reader.stations({ query: 'assembly' })).toEqual([stations[0]]);
const db = new Database(reader.databasePath, { readonly: true, strict: true });
try { expect(db.query<{ station_id: number }, []>('SELECT station_id FROM stations WHERE source_verified = 1 ORDER BY station_id LIMIT 1').get()?.station_id).toBe(60003761); }
finally { db.close(); }
expect(await reader.stations({ query: 'assembly' })).toEqual([stations[1]]);
const pinned = reader.pin();
try { expect((await pinned.searchTypesByName('pyerite'))[0]?.id).toBe(35); }
finally { pinned.close(); }
+4 -2
View File
@@ -27,8 +27,10 @@ try {
assert(verifiedStations > 0);
const joinedStations = Number((db.query<{ n: number }, []>('SELECT COUNT(*) AS n FROM stations st JOIN systems s ON s.system_id = st.system_id JOIN constellations c ON c.constellation_id = s.constellation_id JOIN regions r ON r.region_id = c.region_id').get() as { n: number }).n);
assert.equal(joinedStations, counts.stations, 'every station must join through system, constellation, and region');
const verifiedStation = (await repository.stations({ limit: 1 })).find((station) => station.sourceVerified);
assert(verifiedStation, 'reader must expose a verified station row');
const verifiedStationId = db.query<{ station_id: number }, []>('SELECT station_id FROM stations WHERE source_verified = 1 ORDER BY station_id LIMIT 1').get()?.station_id;
assert(verifiedStationId !== undefined, 'published artifact must contain a verified station row');
const verifiedStation = (await repository.stations([verifiedStationId]))[0];
assert(verifiedStation?.sourceVerified, 'reader must expose the selected verified station row');
assert.deepEqual(await repository.stations([Number.MAX_SAFE_INTEGER]), [], 'unknown station IDs must remain absent rather than fabricated');
const integrity = db.query<{ integrity_check: string }, []>('PRAGMA integrity_check').all();
assert.deepEqual(integrity.map(row => row.integrity_check), ['ok']);