import assert from 'node:assert/strict'; import { readFileSync } from 'node:fs'; import { resolve } from 'node:path'; import test from 'node:test'; function source(relative: string): string { return readFileSync(resolve(process.cwd(), relative), 'utf8'); } test('D5.3.5 migration creates append-preserving import analysis tables and search indexes', () => { const migration = source('src/database/migrations/1787594400000-phase-d5-3-5-import-center-scalability.ts'); assert.match(migration, /CREATE EXTENSION IF NOT EXISTS pg_trgm/); assert.match(migration, /CREATE TABLE asset_import_batches/); assert.match(migration, /CREATE TABLE asset_import_rows/); assert.match(migration, /asset_imports\.read/); assert.match(migration, /asset_imports\.manage/); assert.match(migration, /GRANT SELECT, INSERT, UPDATE ON TABLE asset_import_batches, asset_import_rows/); assert.match(migration, /REVOKE DELETE ON TABLE asset_import_batches, asset_import_rows/); assert.match(migration, /idx_assets_name_trgm/); assert.match(migration, /idx_asset_external_identifiers_value_trgm/); }); test('D5.3.5 import analysis itself does not create Maestro assets', () => { const service = source('src/asset-imports/asset-imports.service.ts'); const upload = service.slice(service.indexOf('async upload'), service.indexOf('async reconcile')); assert.match(upload, /INSERT INTO asset_import_batches/); assert.match(upload, /INSERT INTO source_documents/); assert.doesNotMatch(upload, /INSERT INTO assets\s*\(/); assert.doesNotMatch(upload, /UPDATE assets\s+SET/); assert.match(service, /INSERT INTO asset_import_rows/); assert.match(service, /FOR UPDATE OF batch/); }); test('D5.3.5 hierarchy loads children on demand instead of returning the full tree', () => { const controller = source('src/asset-master/assets.controller.ts'); const service = source('src/asset-master/assets.service.ts'); assert.match(controller, /@Get\('tree-children'\)/); assert.match(service, /async treeChildren/); assert.match(service, /query\.limit \+ 1/); });