diff --git a/api-v3/test/unit/f6-1-operational-context-consistency.test.ts b/api-v3/test/unit/f6-1-operational-context-consistency.test.ts new file mode 100644 index 0000000..50eb34d --- /dev/null +++ b/api-v3/test/unit/f6-1-operational-context-consistency.test.ts @@ -0,0 +1,48 @@ +import assert from 'node:assert/strict'; +import { readFileSync } from 'node:fs'; +import { resolve } from 'node:path'; +import test from 'node:test'; + +function source(path: string): string { + return readFileSync(resolve(process.cwd(), path), 'utf8'); +} + +test('F6.1 preserves Inventory operator snapshots and changes operator only through Area relations', () => { + const relations = source('src/asset-master/asset-operational-relations.service.ts'); + const migration = source('src/database/migrations/1790087250000-f5-operational-context-compatibility.ts'); + + assert.match(migration, /Runtime ownership and search MUST NOT depend on it/); + assert.match(migration, /La Empresa se cambia en la relación temporal del Área, no en el Inventario/); + assert.match(relations, /operatorSnapshotPreserved:true/); + assert.doesNotMatch(relations, /UPDATE assets asset[\s\S]*SET operator_company_id=/); +}); + +test('F6.1 blocks operator mutation through generic Inventory edit DTOs', () => { + const updateDto = source('src/asset-master/dto/update-asset.dto.ts'); + const contextDto = source('src/asset-master/dto/change-asset-context.dto.ts'); + + for (const dto of [updateDto, contextDto]) { + assert.match(dto, /@IsEmpty/); + assert.match(dto, /La Operadora se administra en la relación temporal del Área, no en el Inventario/); + } +}); + +test('F6.1 resolves temporal Inventory operator from Area relation history', () => { + const temporal = source('src/asset-master/asset-temporal.service.ts'); + + assert.match(temporal, /FROM area_company_relations relation/); + assert.match(temporal, /relation\.valid_from <= \$2/); + assert.match(temporal, /relation\.valid_until IS NULL OR relation\.valid_until > \$2/); + assert.match(temporal, /operator_company\.id=operator_relation\.company_id/); + assert.doesNotMatch(temporal, /operator_company\.id=history\.operator_company_id/); +}); + +test('F6.1 verification planning uses Area relation truth instead of Inventory operator snapshot', () => { + const verification = source('src/inspection-verifications/inspection-verifications.service.ts'); + + assert.match(verification, /FROM area_company_relations relation/); + assert.match(verification, /relation\.valid_from <= \$2::timestamptz/); + assert.match(verification, /VERIFICATION_OPERATOR_NOT_ACTIVE/); + assert.match(verification, /operatorSource: 'area_company_relations'/); + assert.doesNotMatch(verification, /company\.id = asset\.operator_company_id/); +});