fix(mgmt-perf): /mgmt-perf 정적 제공, Chart.js 동봉, 파일명 복원·차트 리플로

- Express에 /mgmt-perf → public/mgmt-perf 정적 마운트(기존 뷰 경로와 일치)
- jsdelivr 대신 chart.umd.min.js 동봉으로 CDN 차단·오프라인 대응
- decodeMultipartFilename: Latin-1→UTF-8 복원 시 한글 검사 제거(ASCII·깨진 문자열 모두)
- 페이로드/Chart 실패 시 사용자에게 빨간 안내, 차트 resize 이중 rAF

Made-with: Cursor
This commit is contained in:
2026-04-13 18:52:17 +09:00
parent 419f529d06
commit 3ab42d58ce
6 changed files with 57 additions and 4 deletions

View File

@@ -34,10 +34,12 @@ const mgmtPerf = require("./lib/mgmt-perf");
*/
function decodeMultipartFilename(name) {
if (name == null || typeof name !== "string") return "";
// 이미 한글 등 BMP가 올바르게 들어온 경우(멀티바이트 그대로) 덮어쓰지 않음
if (/[\uAC00-\uD7A3]/.test(name)) return name;
try {
const dec = Buffer.from(name, "latin1").toString("utf8");
if (dec && !dec.includes("\uFFFD") && /[\uAC00-\uD7A3]/.test(dec)) return dec;
// UTF-8이 Latin-1로 잘못 해석된 경우 복원. ASCII-only 파일명은 dec ≈ name.
if (dec && !dec.includes("\uFFFD")) return dec;
} catch (_) {
/* ignore */
}
@@ -1194,6 +1196,8 @@ async function syncAutoChecklistFromMeetingMinutes(openai, { pgPool, email, meet
}
app.use("/public", express.static(path.join(ROOT_DIR, "public")));
/** 경영성과 대시보드 정적 자산 (`/mgmt-perf/*` — 뷰에서 이 경로로 참조) */
app.use("/mgmt-perf", express.static(path.join(ROOT_DIR, "public", "mgmt-perf")));
app.get("/favicon.ico", (req, res) => {
res.type("image/x-icon");
res.sendFile(path.join(ROOT_DIR, "public", "favicon.ico"));