vedanshmadan21 commited on
Commit
27746a4
·
1 Parent(s): 3a752ea

fix: auto-regenerate CAM artifacts when PDF/DOCX missing

Browse files
Files changed (1) hide show
  1. backend/src/routes/cam.js +47 -10
backend/src/routes/cam.js CHANGED
@@ -12,11 +12,14 @@ router.get("/:jobId/download/:format", async (c) => {
12
  if (!["pdf", "docx"].includes(format)) {
13
  return c.json({ error: "Valid formats: pdf, docx" }, 400);
14
  }
15
- try {
16
- const resp = await axios.get(
17
- `${config.aiServiceUrl}/api/v1/cam/download/${jobId}/${format}`,
18
- { responseType: "arraybuffer", timeout: 30000 },
19
- );
 
 
 
20
  const ct =
21
  format === "pdf"
22
  ? "application/pdf"
@@ -28,13 +31,47 @@ router.get("/:jobId/download/:format", async (c) => {
28
  `${disposition}; filename="${jobId}_Credit_Memo.${format}"`,
29
  );
30
  return c.body(resp.data);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
  } catch (err) {
32
  const status = err.response?.status || 500;
33
- const msg =
34
- status === 404
35
- ? `${format.toUpperCase()} not yet available`
36
- : "Download failed";
37
- return c.json({ error: msg }, status);
 
 
 
 
 
 
 
 
 
 
38
  }
39
  });
40
 
 
12
  if (!["pdf", "docx"].includes(format)) {
13
  return c.json({ error: "Valid formats: pdf, docx" }, 400);
14
  }
15
+
16
+ const aiDownloadUrl = `${config.aiServiceUrl}/api/v1/cam/download/${jobId}/${format}`;
17
+
18
+ async function proxyDownloadOnce() {
19
+ const resp = await axios.get(aiDownloadUrl, {
20
+ responseType: "arraybuffer",
21
+ timeout: 30000,
22
+ });
23
  const ct =
24
  format === "pdf"
25
  ? "application/pdf"
 
31
  `${disposition}; filename="${jobId}_Credit_Memo.${format}"`,
32
  );
33
  return c.body(resp.data);
34
+ }
35
+
36
+ async function waitForCamArtifacts() {
37
+ // Trigger regenerate, then poll CAM result until not processing.
38
+ await axios.post(
39
+ `${config.aiServiceUrl}/api/v1/cam/regenerate`,
40
+ { job_id: jobId },
41
+ { timeout: 120000 },
42
+ );
43
+
44
+ for (let i = 0; i < 40; i++) {
45
+ const pollRes = await axios.get(
46
+ `${config.aiServiceUrl}/api/v1/cam/result/${jobId}`,
47
+ { timeout: 30000 },
48
+ );
49
+ if (pollRes.data?.status !== "processing") return;
50
+ await new Promise((r) => setTimeout(r, 2000));
51
+ }
52
+
53
+ throw new Error("CAM regeneration timed out");
54
+ }
55
+
56
+ try {
57
+ return await proxyDownloadOnce();
58
  } catch (err) {
59
  const status = err.response?.status || 500;
60
+ // Auto-heal missing artifacts for completed jobs: regenerate CAM and retry once.
61
+ if (status === 404) {
62
+ try {
63
+ await waitForCamArtifacts();
64
+ return await proxyDownloadOnce();
65
+ } catch (regenErr) {
66
+ const msg =
67
+ regenErr?.message === "CAM regeneration timed out"
68
+ ? "PDF regeneration timed out. Please retry in a minute."
69
+ : `${format.toUpperCase()} not yet available`;
70
+ return c.json({ error: msg }, 504);
71
+ }
72
+ }
73
+
74
+ return c.json({ error: "Download failed" }, status);
75
  }
76
  });
77