From b24c3787c97a1d69b5c3b8b8073d9c2e066ffee0 Mon Sep 17 00:00:00 2001 From: enlineawork Date: Tue, 8 Sep 2026 09:08:00 -0300 Subject: [PATCH] fix: require verification results when closing inspection --- .../inspection-visit-lifecycle.service.ts | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/api-v3/src/inspection-visits/inspection-visit-lifecycle.service.ts b/api-v3/src/inspection-visits/inspection-visit-lifecycle.service.ts index 013bfbe..cb1c4c5 100644 --- a/api-v3/src/inspection-visits/inspection-visit-lifecycle.service.ts +++ b/api-v3/src/inspection-visits/inspection-visit-lifecycle.service.ts @@ -174,6 +174,7 @@ export class InspectionVisitLifecycleService { pendingActs: pending.map((act) => ({ id: act.id, code: act.code, status: act.status })), }); } + await this.assertVerificationResultsComplete(manager, id); const serverClosedAt = new Date(); const clientClosedAt = new Date(dto.clientClosedAt); @@ -216,6 +217,7 @@ export class InspectionVisitLifecycleService { transition: 'CLOSE', source: 'ANDROID', allActsSealed: true, + allVerificationResultsRecorded: true, }, }, manager); }); @@ -277,6 +279,22 @@ export class InspectionVisitLifecycleService { return visit; } + private async assertVerificationResultsComplete(manager: EntityManager, inspectionId: string): Promise { + const [row] = await manager.query(` + SELECT + COUNT(*)::integer AS total, + COUNT(*) FILTER (WHERE outcome IS NOT NULL)::integer AS completed + FROM inspection_finding_verification_visits + WHERE visit_id=$1 + `, [inspectionId]) as Array<{ total: number; completed: number }>; + if (Number(row?.total ?? 0) > 0 && Number(row.completed) !== Number(row.total)) { + throw new ConflictException({ + code: 'INSPECTION_VERIFICATION_RESULTS_REQUIRED', + message: 'Registrá el resultado de todas las verificaciones antes de cerrar la Inspección', + }); + } + } + private async validatePlanningContext(manager: EntityManager, visit: InspectionVisit): Promise { if (!visit.operationalAreaId || !visit.operatorCompanyId || !visit.leadInspectorUserId || !visit.plannedStartAt) { throw new ConflictException({