/* Patch backend.py: 1) Thêm /api/log + /api/logs để nhận client-side errors (React crash, WebGL, promise rejection) từ ErrorBoundary / window.onerror. 2) VERSION_ID ổn định: trước đây `uuid.uuid4().hex[:8]` đổi mỗi lần Space restart → client so sánh version.json thấy khác → tưởng "Có bản mới" và tự reload liên tục. Giờ dùng hằng số "v6" khớp cache-bust bundle, chỉ đổi khi ta chủ động deploy bản mới. Chạy trong Dockerfile build stage (backend.py được COPY vào build stage). Nếu pattern không khớp -> exit(1). */ import fs from 'node:fs' const path = 'backend.py' let s = fs.readFileSync(path, 'utf8') // --- VERSION_ID ổn định (khớp ?v=6 cache-bust) --- const oldVer = 'VERSION_ID = uuid.uuid4().hex[:8]' if (!s.includes(oldVer)) { console.error('PATCH FAILED: VERSION_ID marker not found') process.exit(1) } s = s.replace(oldVer, 'VERSION_ID = "v6"') // IMPORTANT: phải chèn TRƯỚC catch-all @app.get("/{path:path}") (serve_static) — // nếu chèn sau, FastAPI match route theo thứ tự đăng ký → GET /api/logs bị // catch-all nuốt, trả index.html thay vì JSON (không đọc được client errors). const markers = [ '@app.get("/{path:path}")', // nơi lý tưởng: chèn ngay trước catch-all 'if __name__ == "__main__":', // fallback cũ (chỉ dùng nếu không tìm thấy catch-all) ] let idx = -1 let used = -1 for (let i = 0; i < markers.length; i++) { const m = markers[i] const at = s.indexOf(m) if (at !== -1) { // tìm đầu dòng để chèn sạch sẽ const lineStart = s.lastIndexOf('\n', at) + 1 idx = lineStart used = i break } } if (idx === -1) { console.error('PATCH FAILED: marker not found') process.exit(1) } const inject = `# ============ Client error log (từ ErrorBoundary / window.onerror) ============ _client_logs = [] @app.post("/api/log") async def api_log(req: dict): entry = {"at": time.time()} if isinstance(req, dict): entry.update(req) _client_logs.append(entry) del _client_logs[:-400] return {"ok": True} @app.get("/api/logs") async def api_logs(): return {"logs": _client_logs[-200:]} ` s = s.slice(0, idx) + inject + s.slice(idx) fs.writeFileSync(path, s) console.log(`patched backend.py ok: VERSION_ID=v6, /api/log + /api/logs (marker [${used}])`)