Files
sciagent/fe0/scripts/save-report-to-public.mjs
T
Thinh Lam 688fac73e9
CI/CD / backend (push) Failing after 2m8s
CI/CD / frontend (push) Failing after 1m40s
CI/CD / deploy (push) Has been skipped
sciagent code + Gitea Actions CI/CD
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 09:38:30 +07:00

118 lines
3.8 KiB
JavaScript

#!/usr/bin/env node
import fs from "node:fs";
import path from "node:path";
import process from "node:process";
import * as XLSX from "xlsx";
function parseArgs(argv) {
const args = { input: "", caseId: "" };
for (let i = 2; i < argv.length; i += 1) {
const token = argv[i];
if (token === "--input") args.input = argv[++i] ?? "";
else if (token === "--case-id") args.caseId = argv[++i] ?? "";
}
return args;
}
function usageAndExit() {
console.error("Usage: node scripts/save-report-to-public.mjs --input <json-file> [--case-id CASE-123]");
process.exit(1);
}
function normalizeCaseId(raw) {
const base = raw && raw.trim() ? raw : `CASE-${Date.now()}`;
return base.replace(/[^a-zA-Z0-9_-]/g, "");
}
function ensureDir(dirPath) {
fs.mkdirSync(dirPath, { recursive: true });
}
function toExcelRow(data, caseId) {
return {
caseId,
savedAt: new Date().toISOString(),
submissionDate: data.submissionDate ?? "",
authorName: data.authorName ?? "",
initiativeName: data.initiativeName ?? "",
representativeAuthor: data.representativeAuthor ?? "",
representativePhone: data.representativePhone ?? "",
representativeEmail: data.representativeEmail ?? "",
applicationField: data.applicationField ?? "",
introduction: data.introduction ?? "",
currentStatus: data.currentStatus ?? "",
purpose: data.purpose ?? "",
solutionContent: data.solutionContent ?? "",
implementationSteps: data.implementationSteps ?? "",
firstAppliedUnit: data.firstAppliedUnit ?? "",
conditions: data.conditions ?? "",
achievedResult: data.achievedResult ?? "",
novelty: data.novelty ?? "",
effectivenessEconomic: data.effectiveness?.economic ?? "",
effectivenessSocial: data.effectiveness?.social ?? "",
effectivenessTeaching: data.effectiveness?.teaching ?? "",
effectivenessProductivity: data.effectiveness?.productivity ?? "",
effectivenessQuality: data.effectiveness?.quality ?? "",
effectivenessEnvironment: data.effectiveness?.environment ?? "",
effectivenessSafety: data.effectiveness?.safety ?? "",
confidentialInfo: data.confidentialInfo ?? "",
trialUnits: Array.isArray(data.trialUnits)
? data.trialUnits.map((u, i) => `${i + 1}. ${u.name ?? ""} | ${u.address ?? ""} | ${u.field ?? ""}`).join("\n")
: "",
};
}
function updateIndexFile(indexPath, entry) {
let rows = [];
if (fs.existsSync(indexPath)) {
try {
rows = JSON.parse(fs.readFileSync(indexPath, "utf-8"));
if (!Array.isArray(rows)) rows = [];
} catch {
rows = [];
}
}
rows = [entry, ...rows.filter((r) => r.fileName !== entry.fileName)];
fs.writeFileSync(indexPath, JSON.stringify(rows, null, 2), "utf-8");
}
function main() {
const args = parseArgs(process.argv);
if (!args.input) usageAndExit();
const inputPath = path.resolve(process.cwd(), args.input);
if (!fs.existsSync(inputPath)) {
console.error(`Input file not found: ${inputPath}`);
process.exit(1);
}
const data = JSON.parse(fs.readFileSync(inputPath, "utf-8"));
const caseId = normalizeCaseId(args.caseId);
const projectRoot = process.cwd();
const publicDir = path.resolve(projectRoot, "public");
ensureDir(publicDir);
const workbook = XLSX.utils.book_new();
const worksheet = XLSX.utils.json_to_sheet([toExcelRow(data, caseId)]);
XLSX.utils.book_append_sheet(workbook, worksheet, "InitiativeReport");
const fileName = `${caseId}.xlsx`;
const outputPath = path.join(publicDir, fileName);
XLSX.writeFile(workbook, outputPath);
const indexPath = path.join(publicDir, "application-report-index.json");
const stats = fs.statSync(outputPath);
updateIndexFile(indexPath, {
caseId,
fileName,
publicUrl: `/${fileName}`,
sizeBytes: stats.size,
updatedAt: new Date(stats.mtimeMs).toISOString(),
});
console.log(`Saved: ${outputPath}`);
}
main();