diff --git a/api-v3/test/unit/f6-1-inspection-planning-hierarchy.test.ts b/api-v3/test/unit/f6-1-inspection-planning-hierarchy.test.ts new file mode 100644 index 0000000..bef8470 --- /dev/null +++ b/api-v3/test/unit/f6-1-inspection-planning-hierarchy.test.ts @@ -0,0 +1,61 @@ +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 inspection planning exposes Departamento → Área → Yacimiento explicitly', () => { + const hierarchy = source('src/inspection-visits/inspection-planning-hierarchy.service.ts'); + const controller = source('src/inspection-visits/inspection-visits.controller.ts'); + const createPage = source('../web-v2/src/pages/InspectionVisitCreateF61Page.tsx'); + + assert.match(hierarchy, /lower\(type\.code\)='departamento'/); + assert.match(hierarchy, /area\.parent_id=\$1::uuid/); + assert.match(hierarchy, /lower\(type\.code\)='yacimiento'/); + assert.match(hierarchy, /yacimiento\.parent_id=\$1::uuid/); + assert.match(controller, /planning-context\/departments/); + assert.match(controller, /planning-context\/departments\/:departmentId\/areas/); + assert.match(controller, /planning-context\/areas\/:areaId\/yacimientos/); + assert.match(createPage, /Departamento → Área → Yacimiento/); + assert.match(createPage, /Departamento<\/span>/); + assert.match(createPage, /Área<\/span>/); + assert.match(createPage, /Yacimiento<\/span>/); + assert.doesNotMatch(createPage, /Área \/ Yacimiento/); +}); + +test('F6.1 WEB creation freezes Area and uses the selected Yacimiento as physical scope', () => { + const dto = source('src/inspection-visits/dto/create-inspection-visit.dto.ts'); + const scope = source('src/inspection-visits/inspection-planning-scope.ts'); + const create = source('src/inspection-visits/inspection-planning-create.service.ts'); + const createPage = source('../web-v2/src/pages/InspectionVisitCreateF61Page.tsx'); + + assert.match(dto, /scopeAssetId\?: string/); + assert.match(scope, /yacimiento\.parent_id=\$2::uuid/); + assert.match(scope, /lower\(type\.code\)='yacimiento'/); + assert.match(create, /scopeAssetId,/); + assert.match(create, /operationalAreaId: dto\.operationalAreaId/); + assert.match(create, /relation\.relation_role='OPERATOR'/); + assert.match(create, /relation\.valid_from <= \$3::timestamptz/); + assert.match(createPage, /scopeAssetId: yacimientoId/); +}); + +test('F6.1 WEB inspection creation does not use Inventory operator snapshots', () => { + const create = source('src/inspection-visits/inspection-planning-create.service.ts'); + + assert.match(create, /area_company_relations relation/); + assert.doesNotMatch(create, /inventory\.operator_company_id/); + assert.doesNotMatch(create, /asset\.operator_company_id/); +}); + +test('Field preparation is an Inspection stage, not a parallel sidebar module', () => { + const layout = source('../web-v2/src/layout/AppLayout.tsx'); + const briefing = source('../web-v2/src/pages/FieldBriefingsPage.tsx'); + + assert.doesNotMatch(layout, /label: 'Preparación de campo'/); + assert.match(briefing, /ETAPA DE LA INSPECCIÓN/); + assert.match(briefing, /inspectionId/); + assert.match(briefing, /Volver a la inspección/); +});