28 lines
1.7 KiB
TypeScript
28 lines
1.7 KiB
TypeScript
import { readFile } from 'node:fs/promises';
|
|
import { resolve } from 'node:path';
|
|
import { describe, expect, it } from 'vitest';
|
|
import { databaseMigrations } from '../../server/postgres/migration-catalog';
|
|
|
|
const migrationPath = resolve(import.meta.dirname, '..', '..', 'server', 'postgres', 'migrations', '003_ingestion_artifacts_jobs.sql');
|
|
|
|
describe('PostgreSQL ingestion persistence schema', () => {
|
|
it('registers an immutable additive migration for artifacts, processing history and jobs', async () => {
|
|
const sql = await readFile(migrationPath, 'utf8');
|
|
expect(databaseMigrations.find(migration => migration.version === '003')).toMatchObject({ version: '003', name: 'ingestion-artifacts-jobs' });
|
|
expect(sql).toContain('CREATE TABLE assessor_import_artifacts');
|
|
expect(sql).toContain('CREATE TABLE assessor_import_processing_runs');
|
|
expect(sql).toContain('CREATE TABLE assessor_ingestion_jobs');
|
|
expect(sql).toContain('parent_artifact_id text REFERENCES assessor_import_artifacts(id) ON DELETE CASCADE');
|
|
expect(sql).toContain('supersedes_run_id text REFERENCES assessor_import_processing_runs(id) ON DELETE RESTRICT');
|
|
});
|
|
|
|
it('enforces hashes, idempotency, retry bounds, lease consistency and claim indexes', async () => {
|
|
const sql = await readFile(migrationPath, 'utf8');
|
|
expect(sql).toContain("sha256 ~ '^[a-f0-9]{64}$'");
|
|
expect(sql).toContain('UNIQUE (project_id, idempotency_key)');
|
|
expect(sql).toContain('max_attempts >= 1 AND attempts <= max_attempts');
|
|
expect(sql).toContain("job_status = 'running' AND btrim(lease_owner) <> '' AND lease_expires_at IS NOT NULL");
|
|
expect(sql).toContain('assessor_ingestion_jobs_claim_idx');
|
|
});
|
|
});
|