52 lines
3.1 KiB
TypeScript
52 lines
3.1 KiB
TypeScript
import assert from 'node:assert/strict';
|
|
import test from 'node:test';
|
|
import { readFileSync } from 'node:fs';
|
|
import { resolve } from 'node:path';
|
|
|
|
const read = (path: string) => readFileSync(resolve(process.cwd(), path), 'utf8');
|
|
const migration = read('src/database/migrations/1788890400000-phase-d5-3-25-verification-event-history.ts');
|
|
const findings = read('src/inspection-findings/inspection-findings.service.ts');
|
|
const findingsController = read('src/inspection-findings/inspection-findings.controller.ts');
|
|
const verifications = read('src/inspection-verifications/inspection-verifications.service.ts');
|
|
const ledger = read('src/inspection-verifications/verification-event-ledger.ts');
|
|
|
|
test('D5.3.25 creates an append-only verification event ledger and reconstructs prior history', () => {
|
|
assert.match(migration, /CREATE TABLE inspection_finding_verification_events/);
|
|
assert.match(migration, /FROM inspection_finding_versions version/);
|
|
assert.match(migration, /FROM inspection_finding_verification_visits verification_link/);
|
|
assert.match(migration, /REVOKE UPDATE, DELETE ON TABLE inspection_finding_verification_events/);
|
|
assert.doesNotMatch(ledger, /UPDATE inspection_finding_verification_events/);
|
|
assert.doesNotMatch(ledger, /DELETE FROM inspection_finding_verification_events/);
|
|
});
|
|
|
|
test('D5.3.25 records every office control-date change without replacing historical events', () => {
|
|
assert.match(findings, /dto\.nextControlOn !== undefined && dto\.nextControlOn !== before\.nextControlOn/);
|
|
assert.match(findings, /InspectionFindingVerificationEventType\.CONTROL_DATE_DEFINED/);
|
|
assert.match(findings, /InspectionFindingVerificationEventType\.CONTROL_DATE_CHANGED/);
|
|
assert.match(findings, /InspectionFindingVerificationEventType\.CONTROL_DATE_CLEARED/);
|
|
assert.match(findings, /appendVerificationEvent\(manager/);
|
|
});
|
|
|
|
test('D5.3.25 makes one field result immutable and appends its result event', () => {
|
|
assert.match(verifications, /VERIFICATION_RESULT_IMMUTABLE/);
|
|
assert.match(verifications, /InspectionFindingVerificationEventType\.RESULT_RECORDED/);
|
|
assert.match(migration, /protect_inspection_verification_result_immutability/);
|
|
assert.match(migration, /trg_inspection_verification_result_immutable/);
|
|
assert.match(migration, /OLD\.result_recorded_at IS NOT NULL/);
|
|
});
|
|
|
|
test('D5.3.25 preserves successive verification visits as separate historical attempts', () => {
|
|
assert.match(verifications, /visit\.status IN \('DRAFT', 'PLANNED', 'IN_PROGRESS'\)/);
|
|
assert.match(verifications, /INSERT INTO inspection_finding_verification_visits/);
|
|
assert.match(verifications, /InspectionFindingVerificationEventType\.VISIT_PLANNED/);
|
|
assert.doesNotMatch(verifications, /DELETE FROM inspection_finding_verification_visits/);
|
|
});
|
|
|
|
test('D5.3.25 exposes the complete verification history through finding detail and a dedicated endpoint', () => {
|
|
assert.match(findingsController, /@Get\(':id\/verification-history'\)/);
|
|
assert.match(findings, /loadVerificationHistory/);
|
|
assert.match(findings, /inspection_finding_verification_events event/);
|
|
assert.match(findings, /verificationHistory/);
|
|
assert.match(findings, /evidenceCount/);
|
|
});
|