fix(actas): keep sealed act content findings-only

This commit is contained in:
Maximo
2026-09-15 20:59:59 -03:00
parent ff297c8d93
commit 215f443f71
14 changed files with 82 additions and 72 deletions
@@ -0,0 +1,48 @@
import { readFileSync } from 'node:fs';
import { resolve } from 'node:path';
import test from 'node:test';
import assert from 'node:assert/strict';
const api = (path: string) => readFileSync(resolve(process.cwd(), 'src', path), 'utf8');
const web = (path: string) => readFileSync(resolve(process.cwd(), '..', 'web-v2', 'src', path), 'utf8');
test('Acta PDF renders Hallazgos and finding evidence, never standalone Inventory or field photos', () => {
const source = api('inspection-reports/inspection-act-pdf-builder.ts');
assert.match(source, /heading\('Hallazgos y fotografías'\)/);
assert.match(source, /item\.findingId === text\(finding\.id\)/);
assert.doesNotMatch(source, /Instalaciones inspeccionadas/);
assert.doesNotMatch(source, /Otras instalaciones inspeccionadas/);
assert.doesNotMatch(source, /item\.assetId === text\(finding\.assetId\)/);
});
test('Dashboard Acta shows only Hallazgos and evidence directly attached to them', () => {
const media = web('features/inspections/InspectionActMediaPanel.tsx');
const editor = web('pages/InspectionActEditorPage.tsx');
assert.match(media, /listInspectionFindingEvidence/);
assert.doesNotMatch(media, /listInspectionActFieldMedia/);
assert.doesNotMatch(media, /getAssetMediaBlob/);
assert.doesNotMatch(media, /Fotos de otras instalaciones/);
assert.doesNotMatch(editor, /Instalaciones inspeccionadas/);
});
test('Company signing view exposes Hallazgos as Acta content without a standalone Inventory list', () => {
const service = api('inspection-closing/company-signature-invite.service.ts');
const viewBody = service.slice(service.indexOf(' async view(token: string)'), service.indexOf(' async sign('));
const page = web('pages/CompanySignaturePage.tsx');
assert.match(viewBody, /findings/);
assert.doesNotMatch(viewBody, /inventories/);
assert.match(page, />Hallazgos</);
assert.doesNotMatch(page, /Inventario inspeccionado/);
assert.doesNotMatch(page, /view\.inventories/);
});
test('Acta sealed snapshot excludes Inventory that has no Hallazgo and PDF skips standalone asset media', () => {
const closing = api('inspection-closing/inspection-closing.service.ts');
const pdfService = api('inspection-reports/inspection-act-pdf.service.ts');
const snapshotBody = closing.slice(closing.indexOf(' private async buildLockedSnapshot('), closing.indexOf(' private async deadlinePolicy('));
assert.match(snapshotBody, /EXISTS \(\s*SELECT 1 FROM inspection_findings finding/);
assert.match(snapshotBody, /finding\.asset_id=asset\.id/);
assert.match(snapshotBody, /finding\.status<>'VOIDED'/);
assert.match(pdfService, /fieldImages\(actId, false\)/);
assert.match(pdfService, /includeAssetPhotos \? await this\.dataSource\.query/);
});
@@ -94,12 +94,12 @@ test('F6.9 revision migration archives both first document versions before servi
assert.match(migration, /PRIMARY KEY \(report_id,template_version\)/);
});
test('F6.9 includes field photos from installations without their own findings', async () => {
test('Acta ignores standalone field photos while the technical Informe remains independent', async () => {
const other = await sharp(photo).resize(75).png().toBuffer();
const unlinked = { id: 'photo-other-asset', assetId: 'asset-2', title: 'Otra instalación', sha256: digest(other), buffer: other };
const withUnlinked = await buildInspectionActPdf(sealed, [evidence, unlinked]);
const linkedOnly = await buildInspectionActPdf(sealed, [evidence]);
assert.ok(withUnlinked.buffer.length > linkedOnly.buffer.length + 500);
assert.ok(Math.abs(withUnlinked.buffer.length - linkedOnly.buffer.length) < 500);
const word = buildInspectionReportWord({ code: 'INF-OTHER', title: 'Informe', generatedAt: new Date(),
frozenSha256: 'c'.repeat(64), frozenSnapshot: { sealedAct: sealed }, photos: [evidence, unlinked] });
assert.ok(word.buffer.includes(Buffer.from('OTRAS INSTALACIONES INSPECCIONADAS')));