import assert from 'node:assert/strict'; import test from 'node:test'; import { readFileSync } from 'node:fs'; import { resolve } from 'node:path'; const verificationService = readFileSync(resolve(process.cwd(), 'src/inspection-verifications/inspection-verifications.service.ts'), 'utf8'); const evidenceService = readFileSync(resolve(process.cwd(), 'src/inspection-findings/inspection-evidence.service.ts'), 'utf8'); const closingService = readFileSync(resolve(process.cwd(), 'src/inspection-closing/inspection-closing.service.ts'), 'utf8'); const lifecycleService = readFileSync(resolve(process.cwd(), 'src/inspection-visits/inspection-visit-lifecycle.service.ts'), 'utf8'); const findingsService = readFileSync(resolve(process.cwd(), 'src/inspection-findings/inspection-findings.service.ts'), 'utf8'); const migration = readFileSync(resolve(process.cwd(), 'src/database/migrations/1788199200000-phase-d5-3-17-verification-execution.ts'), 'utf8'); test('D5.3.17 records one controlled field result for a linked verification finding', () => { assert.match(verificationService, /assertMobileInspector\(principal\)/); assert.match(verificationService, /VERIFICATION_VISIT_NOT_IN_PROGRESS/); assert.match(verificationService, /InspectionVerificationOutcome\.RESOLVED/); assert.match(verificationService, /InspectionVerificationOutcome\.NOT_RESOLVED/); assert.match(verificationService, /InspectionVerificationOutcome\.REQUIRES_NEW_DATE/); assert.match(verificationService, /VERIFICATION_RECORDED/); assert.match(verificationService, /INSPECTION_VERIFICATION_RESULT_RECORDED/); }); test('D5.3.17 preserves the original target and only reschedules when explicitly requested', () => { assert.match(verificationService, /target_control_on/); assert.match(verificationService, /rescheduled_control_on/); assert.match(verificationService, /VERIFICATION_NEW_DATE_REQUIRED/); assert.match(verificationService, /VERIFICATION_NEW_DATE_NOT_FUTURE/); }); test('D5.3.17 links verification photos to the verification visit', () => { assert.match(evidenceService, /InspectionEvidencePurpose\.VERIFICATION/); assert.match(evidenceService, /verification_visit_id/); assert.match(evidenceService, /INSPECTION_VERIFICATION_VISIT_REQUIRED/); assert.match(evidenceService, /INSPECTION_VERIFICATION_PHOTO_REQUIRED/); }); test('F4 requires every linked verification result before closing the inspection, not before locking one act', () => { assert.doesNotMatch(closingService, /assertVerificationResultsComplete/); assert.match(lifecycleService, /assertVerificationResultsComplete\(manager, id\)/); assert.match(lifecycleService, /INSPECTION_VERIFICATION_RESULTS_REQUIRED/); assert.match(lifecycleService, /FROM inspection_finding_verification_visits/); assert.match(lifecycleService, /WHERE visit_id=\$1/); }); test('D5.3.17 moves verified conforming findings into an office ready-to-close queue', () => { assert.match(findingsService, /READY_TO_CLOSE/); assert.match(findingsService, /readyToClose/); assert.match(findingsService, /latestVerificationOutcome/); }); test('D5.3.17 migration adds verification outcome and verification evidence linkage', () => { assert.match(migration, /target_control_on date/); assert.match(migration, /outcome varchar\(24\)/); assert.match(migration, /verified_at timestamptz/); assert.match(migration, /rescheduled_control_on date/); assert.match(migration, /verification_visit_id uuid/); assert.match(migration, /'VERIFICATION'/); });