pdf task-h
This commit is contained in:
153
scripts/audit-pdf-runtime-payload.ts
Normal file
153
scripts/audit-pdf-runtime-payload.ts
Normal file
@@ -0,0 +1,153 @@
|
||||
import { buildAuditPayload, createSqlClient, summarizeIssues } from './pdf-audit-utils.ts';
|
||||
|
||||
type PayloadFinding = {
|
||||
field: string;
|
||||
source: 'documentData' | 'templateInput' | 'topicInputs';
|
||||
status: 'PASS' | 'WARNING' | 'FAIL';
|
||||
value: unknown;
|
||||
message: string;
|
||||
};
|
||||
|
||||
function pushFinding(findings: PayloadFinding[], finding: PayloadFinding) {
|
||||
findings.push(finding);
|
||||
}
|
||||
|
||||
function walkValue(
|
||||
findings: PayloadFinding[],
|
||||
source: PayloadFinding['source'],
|
||||
prefix: string,
|
||||
value: unknown
|
||||
) {
|
||||
if (value === undefined) {
|
||||
pushFinding(findings, {
|
||||
field: prefix,
|
||||
source,
|
||||
status: 'FAIL',
|
||||
value,
|
||||
message: 'Value is undefined'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (value === null) {
|
||||
pushFinding(findings, {
|
||||
field: prefix,
|
||||
source,
|
||||
status: 'WARNING',
|
||||
value,
|
||||
message: 'Value is null'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeof value === 'string') {
|
||||
pushFinding(findings, {
|
||||
field: prefix,
|
||||
source,
|
||||
status: value.trim() ? 'PASS' : 'WARNING',
|
||||
value,
|
||||
message: value.trim() ? 'String is populated' : 'String is empty'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (Array.isArray(value)) {
|
||||
if (source === 'documentData' && value.some((row) => !Array.isArray(row))) {
|
||||
pushFinding(findings, {
|
||||
field: prefix,
|
||||
source,
|
||||
status: 'PASS',
|
||||
value: `rows:${value.length}`,
|
||||
message: 'Collection payload is populated'
|
||||
});
|
||||
|
||||
for (const [index, item] of value.entries()) {
|
||||
walkValue(findings, source, `${prefix}[${index}]`, item);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const validTable = value.every(
|
||||
(row) => Array.isArray(row) && row.every((cell) => typeof cell === 'string')
|
||||
);
|
||||
|
||||
pushFinding(findings, {
|
||||
field: prefix,
|
||||
source,
|
||||
status: validTable ? 'PASS' : 'FAIL',
|
||||
value: Array.isArray(value) ? `rows:${value.length}` : value,
|
||||
message: validTable ? 'Array shape is valid' : 'Array shape is invalid for PDF payload'
|
||||
});
|
||||
|
||||
for (const [index, item] of value.entries()) {
|
||||
if (Array.isArray(item)) {
|
||||
for (const [cellIndex, cell] of item.entries()) {
|
||||
if (typeof cell !== 'string') {
|
||||
pushFinding(findings, {
|
||||
field: `${prefix}[${index}][${cellIndex}]`,
|
||||
source,
|
||||
status: 'FAIL',
|
||||
value: cell,
|
||||
message: 'Table cell is not a string'
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeof value === 'object') {
|
||||
for (const [key, childValue] of Object.entries(value)) {
|
||||
walkValue(findings, source, prefix ? `${prefix}.${key}` : key, childValue);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
pushFinding(findings, {
|
||||
field: prefix,
|
||||
source,
|
||||
status: 'PASS',
|
||||
value,
|
||||
message: 'Scalar value is populated'
|
||||
});
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const sql = createSqlClient();
|
||||
|
||||
try {
|
||||
const payload = await buildAuditPayload(sql);
|
||||
const findings: PayloadFinding[] = [];
|
||||
|
||||
walkValue(findings, 'documentData', 'documentData', payload.documentData);
|
||||
walkValue(findings, 'templateInput', 'templateInput', payload.templateInput);
|
||||
walkValue(findings, 'topicInputs', 'topicInputs', payload.topicInputs);
|
||||
|
||||
const status = summarizeIssues(findings.map((finding) => finding.status));
|
||||
console.log(
|
||||
JSON.stringify(
|
||||
{
|
||||
audit: 'runtime-payload',
|
||||
overallStatus: status,
|
||||
quotationCode: payload.quotationCode,
|
||||
templateName: payload.templateName,
|
||||
templateVersion: payload.templateVersion,
|
||||
findingCount: findings.length,
|
||||
findings
|
||||
},
|
||||
null,
|
||||
2
|
||||
)
|
||||
);
|
||||
} finally {
|
||||
await sql.end({ timeout: 5 });
|
||||
}
|
||||
}
|
||||
|
||||
main().catch((error) => {
|
||||
console.error(`[audit-pdf-runtime-payload] ${error.message}`);
|
||||
process.exit(1);
|
||||
});
|
||||
Reference in New Issue
Block a user