67 lines
3.7 KiB
TypeScript
67 lines
3.7 KiB
TypeScript
import assert from 'node:assert/strict';
|
|
import fs from 'node:fs';
|
|
import path from 'node:path';
|
|
import test from 'node:test';
|
|
|
|
const root = process.cwd();
|
|
const read = (relative: string) => fs.readFileSync(path.join(root, relative), 'utf8');
|
|
|
|
test('D5.5 stores explicit Area and Operator context plus append-only checklist generations', () => {
|
|
const migration = read('src/database/migrations/1789063200000-phase-d5-5-web-planning-checklist.ts');
|
|
assert.match(migration, /ADD COLUMN operational_area_id uuid/);
|
|
assert.match(migration, /ADD COLUMN operator_company_id uuid/);
|
|
assert.match(migration, /CREATE TABLE inspection_visit_checklist_items/);
|
|
assert.match(migration, /generation_number integer NOT NULL/);
|
|
assert.match(migration, /REVOKE UPDATE, DELETE ON TABLE[\s\S]*inspection_visit_checklist_items, inspection_visit_asset_events/);
|
|
});
|
|
|
|
test('D5.5 exposes Area then active OPERATOR choices and a server-generated planning checklist', () => {
|
|
const controller = read('src/inspection-visits/inspection-visits.controller.ts');
|
|
const service = read('src/inspection-visits/inspection-visits.service.ts');
|
|
assert.match(controller, /@Get\('planning-context\/areas'\)/);
|
|
assert.match(controller, /@Get\('planning-context\/areas\/:areaId\/operators'\)/);
|
|
assert.match(controller, /@Post\(':id\/checklist\/generate'\)/);
|
|
assert.match(service, /relation\.relation_role = 'OPERATOR'/);
|
|
assert.match(service, /INSPECTION_OPERATOR_NOT_ACTIVE_IN_AREA/);
|
|
});
|
|
|
|
test('D5.5 classifies antecedents overdue items and next controls while adding actionable assets automatically', () => {
|
|
const service = read('src/inspection-visits/inspection-visits.service.ts');
|
|
assert.match(service, /'COMPANY_OVERDUE'/);
|
|
assert.match(service, /'VERIFICATION_OVERDUE'/);
|
|
assert.match(service, /'UPCOMING_CONTROL'/);
|
|
assert.match(service, /'ANTECEDENT'/);
|
|
assert.match(service, /item_kind IN \('COMPANY_OVERDUE','VERIFICATION_OVERDUE','UPCOMING_CONTROL'\)/);
|
|
assert.match(service, /'AUTO_INCLUDED'/);
|
|
});
|
|
|
|
test('D5.5 treats manual additions as preventive and requires an auditable reason for exclusions', () => {
|
|
const service = read('src/inspection-visits/inspection-visits.service.ts');
|
|
const dto = read('src/inspection-visits/dto/exclude-inspection-visit-asset.dto.ts');
|
|
assert.match(service, /planning_source[^\n]*[\s\S]*'PREVENTIVE'/);
|
|
assert.match(service, /INSPECTION_EXCLUSION_REASON_REQUIRED/);
|
|
assert.match(service, /INSPECTION_VISIT_ASSET_EXCLUDED/);
|
|
assert.match(service, /INSPECTION_VISIT_ASSET_REINCLUDED/);
|
|
assert.match(dto, /@MinLength\(10\)/);
|
|
});
|
|
|
|
test('D5.5 keeps verification visits inside the same Area Operator planning contract and start remains APK-only', () => {
|
|
const verification = read('src/inspection-verifications/inspection-verifications.service.ts');
|
|
const visits = read('src/inspection-visits/inspection-visits.service.ts');
|
|
assert.match(verification, /operationalAreaId: areaId/);
|
|
assert.match(verification, /operatorCompanyId: companyId/);
|
|
assert.match(verification, /planning_source = 'VERIFICATION'/);
|
|
assert.match(visits, /assertMobileInspector\(principal\)/);
|
|
assert.match(visits, /INSPECTION_CHECKLIST_REQUIRED/);
|
|
});
|
|
|
|
test('D5.5 confirmation requires a reviewed current checklist and keeps visit start under mobile inspector policy', () => {
|
|
const visits = read('src/inspection-visits/inspection-visits.service.ts');
|
|
const policy = read('src/inspection-operations/mobile-inspector-policy.ts');
|
|
assert.match(visits, /INSPECTION_CHECKLIST_REQUIRED/);
|
|
assert.match(visits, /checklistGeneratedAt/);
|
|
assert.match(visits, /assertMobileInspector\(principal\)/);
|
|
assert.match(policy, /transport !== 'bearer'/);
|
|
assert.match(policy, /includes\('inspector'\)/);
|
|
});
|