116 lines
4.5 KiB
TypeScript
116 lines
4.5 KiB
TypeScript
import { readFile, writeFile } from 'node:fs/promises';
|
|
import path from 'node:path';
|
|
import {
|
|
AUDIT_ARTIFACTS_DIR,
|
|
buildAuditPayload,
|
|
createSqlClient,
|
|
summarizeIssues,
|
|
writeAuditArtifact
|
|
} from './pdf-audit-utils.ts';
|
|
|
|
async function readReport<T>(fileName: string): Promise<T | null> {
|
|
const filePath = path.resolve(AUDIT_ARTIFACTS_DIR, fileName);
|
|
try {
|
|
const raw = await readFile(filePath, 'utf8');
|
|
return JSON.parse(raw) as T;
|
|
} catch {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
async function main() {
|
|
const sql = createSqlClient();
|
|
|
|
try {
|
|
const payload = await buildAuditPayload(sql);
|
|
const templateVersionReport = await readReport<Record<string, unknown>>(
|
|
'template-version-report.json'
|
|
);
|
|
const placeholderReport = await readReport<Record<string, unknown>>(
|
|
'placeholder-integrity-report.json'
|
|
);
|
|
const payloadReport = await readReport<Record<string, unknown>>('payload-parity-report.json');
|
|
const snapshotReport = await readReport<Record<string, unknown>>('signature-audit-report.json');
|
|
const statuses = [
|
|
String(templateVersionReport?.overallStatus ?? 'WARNING'),
|
|
String(placeholderReport?.overallStatus ?? 'WARNING'),
|
|
String(payloadReport?.overallStatus ?? 'WARNING'),
|
|
String(snapshotReport?.overallStatus ?? 'WARNING')
|
|
] as Array<'PASS' | 'WARNING' | 'FAIL'>;
|
|
const overallStatus = summarizeIssues(statuses);
|
|
const topicRuntimeReport = {
|
|
audit: 'topic-runtime',
|
|
overallStatus: Object.keys(payload.topicInputs).length > 0 ? 'PASS' : 'FAIL',
|
|
quotationCode: payload.quotationCode,
|
|
topicCount: payload.quotationMetrics.topicCount,
|
|
topicInputKeys: Object.keys(payload.topicInputs)
|
|
.filter((key) => key.startsWith('topic_'))
|
|
.sort(),
|
|
itemTopicInputKeys: Object.keys(payload.topicInputs)
|
|
.filter((key) => key.startsWith('item_topic_'))
|
|
.sort(),
|
|
duplicateKeys: Object.keys(payload.topicInputs).filter(
|
|
(key, index, array) => array.indexOf(key) !== index
|
|
),
|
|
emptySections: Object.entries(payload.topicInputs)
|
|
.filter(([, value]) => !Array.isArray(value) || value.length === 0)
|
|
.map(([key]) => key)
|
|
};
|
|
await writeAuditArtifact('topic-runtime-report.json', topicRuntimeReport);
|
|
const summary = {
|
|
generatedAt: new Date().toISOString(),
|
|
overallStatus,
|
|
quotationCode: payload.quotationCode,
|
|
artifacts: {
|
|
templateVersionReport: 'template-version-report.json',
|
|
placeholderIntegrityReport: 'placeholder-integrity-report.json',
|
|
payloadParityReport: 'payload-parity-report.json',
|
|
topicRuntimeReport: 'topic-runtime-report.json',
|
|
signatureAuditReport: 'signature-audit-report.json'
|
|
},
|
|
statuses: {
|
|
templateVersion: templateVersionReport?.overallStatus ?? 'WARNING',
|
|
placeholderIntegrity: placeholderReport?.overallStatus ?? 'WARNING',
|
|
payloadParity: payloadReport?.overallStatus ?? 'WARNING',
|
|
topicRuntime: topicRuntimeReport.overallStatus,
|
|
approvedSnapshotParity: snapshotReport?.overallStatus ?? 'WARNING'
|
|
}
|
|
};
|
|
const artifactPath = await writeAuditArtifact('summary.json', summary);
|
|
const markdown = [
|
|
'# PDF Integrity Summary',
|
|
'',
|
|
`- Generated At: ${summary.generatedAt}`,
|
|
`- Overall Status: ${summary.overallStatus}`,
|
|
`- Quotation Code: ${summary.quotationCode}`,
|
|
'',
|
|
'## Statuses',
|
|
'',
|
|
`- Template Version Integrity: ${summary.statuses.templateVersion}`,
|
|
`- Placeholder Integrity: ${summary.statuses.placeholderIntegrity}`,
|
|
`- Payload Parity: ${summary.statuses.payloadParity}`,
|
|
`- Topic Runtime: ${summary.statuses.topicRuntime}`,
|
|
`- Approved Snapshot Parity: ${summary.statuses.approvedSnapshotParity}`,
|
|
'',
|
|
'## Artifact Files',
|
|
'',
|
|
`- ${summary.artifacts.templateVersionReport}`,
|
|
`- ${summary.artifacts.placeholderIntegrityReport}`,
|
|
`- ${summary.artifacts.payloadParityReport}`,
|
|
`- ${summary.artifacts.topicRuntimeReport}`,
|
|
`- ${summary.artifacts.signatureAuditReport}`
|
|
].join('\n');
|
|
const markdownPath = path.resolve(AUDIT_ARTIFACTS_DIR, 'summary.md');
|
|
await writeFile(markdownPath, `${markdown}\n`, 'utf8');
|
|
|
|
console.log(JSON.stringify({ ...summary, artifactPath, markdownPath }, null, 2));
|
|
} finally {
|
|
await sql.end({ timeout: 5 });
|
|
}
|
|
}
|
|
|
|
main().catch((error) => {
|
|
console.error(`[generate-pdf-integrity-report] ${error.message}`);
|
|
process.exit(1);
|
|
});
|