import { mkdtemp, rm } from 'node:fs/promises'; import { tmpdir } from 'node:os'; import { join } from 'node:path'; import { afterEach, beforeEach, describe, expect, it } from 'vitest'; import { SqliteLocalIngestStore } from '../../../src/context/ingest/sqlite-local-ingest-store.js'; import type { LocalIngestRunRecord } from '../../../src/context/ingest/local-stage-ingest.js'; function runRecord(overrides: Partial = {}): LocalIngestRunRecord { return { runId: 'local-run-1', jobId: 'local-run-1', status: 'done', adapter: 'fake', connectionId: 'warehouse', sourceDir: '/tmp/source', syncId: '2026-04-27-120000-local-run-1', startedAt: '2026-04-27T12:00:00.000Z', completedAt: '2026-04-27T12:00:01.000Z', progress: 1, done: true, previousRunId: null, diffSummary: { added: 1, modified: 0, deleted: 0, unchanged: 0, }, diffPaths: { added: ['orders/orders.json'], modified: [], deleted: [], unchanged: [], }, workUnitCount: 1, rawFileCount: 1, workUnits: [ { unitKey: 'fake-orders', rawFiles: ['orders/orders.json'], peerFileIndex: [], dependencyPaths: [], }, ], evictionDeletedRawPaths: [], errors: [], ...overrides, }; } describe('SqliteLocalIngestStore', () => { let tempDir: string; let dbPath: string; beforeEach(async () => { tempDir = await mkdtemp(join(tmpdir(), 'ktx-sqlite-local-ingest-')); dbPath = join(tempDir, '.ktx', 'db.sqlite'); }); afterEach(async () => { await rm(tempDir, { recursive: true, force: true }); }); it('persists and reads a local ingest run by id', () => { const store = new SqliteLocalIngestStore({ dbPath }); const record = runRecord(); store.saveCompletedRun({ record, rawContentHashes: { 'orders/orders.json': 'hash-1', }, }); expect(store.findRunById('local-run-1')).toEqual(record); expect(store.findRunById('missing-run')).toBeNull(); }); it('returns the latest completed report for the same connection and adapter', () => { const store = new SqliteLocalIngestStore({ dbPath }); const first = runRecord({ runId: 'local-run-1', jobId: 'local-run-1', completedAt: '2026-04-27T12:00:00.000Z', }); const second = runRecord({ runId: 'local-run-2', jobId: 'local-run-2', syncId: '2026-04-27-120500-local-run-2', completedAt: '2026-04-27T12:05:00.000Z', previousRunId: 'local-run-1', }); const otherAdapter = runRecord({ runId: 'metabase-run-1', jobId: 'metabase-run-1', adapter: 'metabase', syncId: '2026-04-27-121000-metabase-run-1', completedAt: '2026-04-27T12:10:00.000Z', }); store.saveCompletedRun({ record: first, rawContentHashes: { 'orders/orders.json': 'hash-1', }, }); store.saveCompletedRun({ record: second, rawContentHashes: { 'orders/orders.json': 'hash-2', 'orders/payments.json': 'hash-3', }, }); store.saveCompletedRun({ record: otherAdapter, rawContentHashes: { 'cards/revenue.json': 'hash-4', }, }); expect(store.findLatestCompletedReport('warehouse', 'fake')).toMatchObject({ runId: 'local-run-2', previousRunId: 'local-run-1', rawContentHashes: { 'orders/orders.json': 'hash-2', 'orders/payments.json': 'hash-3', }, }); expect(store.findLatestCompletedReport('warehouse', 'fake', { excludeRunId: 'local-run-2' })).toMatchObject({ runId: 'local-run-1', rawContentHashes: { 'orders/orders.json': 'hash-1', }, }); expect(store.findLatestCompletedReport('warehouse', 'fake', { excludeRunId: 'local-run-1' })).toMatchObject({ runId: 'local-run-2', rawContentHashes: { 'orders/orders.json': 'hash-2', 'orders/payments.json': 'hash-3', }, }); expect(store.findLatestCompletedReport('warehouse', 'metabase')).toMatchObject({ runId: 'metabase-run-1', rawContentHashes: { 'cards/revenue.json': 'hash-4', }, }); expect(store.findLatestCompletedReport('missing', 'fake')).toBeNull(); }); it('ignores malformed run ids when reading status', () => { const store = new SqliteLocalIngestStore({ dbPath }); expect(store.findRunById('../escape')).toBeNull(); expect(store.findRunById('')).toBeNull(); }); });