fix(f6.9): include every field photo and preserve document revisions
Android CI / RC / Android · lint, tests, debug APK, release compile (push) Successful in 3m8s
DH V2 CI / WEB · typecheck, build (push) Successful in 19s
DH V2 CI / API · typecheck, tests, build (push) Successful in 32s
Production dependency audit / API · production dependencies (push) Successful in 8s
Production dependency audit / WEB · production dependencies (push) Successful in 9s
DH V2 CI / Docker / scripts contract (push) Successful in 59s

This commit is contained in:
DH V2
2026-09-15 19:18:31 -03:00
parent 669c0d2656
commit 60ba37c287
9 changed files with 169 additions and 18 deletions
@@ -50,10 +50,10 @@ test('F6.9 technical Informe embeds evidence and its institutional source hash',
test('F6.9 keeps prior sealed PDF and prior company responses available for audit', () => {
const pdf = readFileSync(resolve(process.cwd(), 'src/inspection-reports/inspection-act-pdf.service.ts'), 'utf8');
const controller = readFileSync(resolve(process.cwd(), 'src/act-administration/act-administration.controller.ts'), 'utf8');
assert.match(pdf, /inspection_act_consolidated_pdf_artifacts/);
assert.match(pdf, /inspection_act_consolidated_pdf_revisions/);
const word = readFileSync(resolve(process.cwd(), 'src/inspection-reports/inspection-report-word.service.ts'), 'utf8');
assert.match(word, /inspection_report_consolidated_word_artifacts/);
assert.match(pdf, /ON CONFLICT \(act_id\) DO NOTHING/);
assert.match(word, /inspection_report_consolidated_word_revisions/);
assert.match(pdf, /ON CONFLICT \(act_id,template_version\) DO NOTHING/);
assert.match(controller, /responseContent\(responseId\)/);
assert.doesNotMatch(controller, /@Post\('responses'\)/);
});
@@ -84,3 +84,25 @@ test('F6.9 built CommonJS runtime renders signed PDF and WebP evidence', async (
const pdf = await runtimePdf.buildInspectionActPdf(sealed, [{ ...evidence, buffer: rendered, sha256: digest(webp) }]);
assert.ok(pdf.buffer.subarray(0, 8).equals(Buffer.from('%PDF-1.4')));
});
test('F6.9 revision migration archives both first document versions before serving the corrected template', () => {
const migration = readFileSync(resolve(process.cwd(),
'src/database/migrations/1790135400000-f6-9-consolidated-document-revisions.ts'), 'utf8');
assert.match(migration, /SELECT act_id,1,stored_name,original_name,size_bytes,sha256,generated_at/);
assert.match(migration, /SELECT report_id,1,stored_name,original_name,size_bytes,sha256,generated_at/);
assert.match(migration, /PRIMARY KEY \(act_id,template_version\)/);
assert.match(migration, /PRIMARY KEY \(report_id,template_version\)/);
});
test('F6.9 includes field photos from installations without their own findings', 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);
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')));
assert.ok(word.buffer.includes(Buffer.from('word/media/photo-2.png')));
assert.ok(word.buffer.includes(other));
});