diff --git a/renderer/carbone-templates/433a0593-d3cf-414e-8763-ab5f87cbc75c.docx b/renderer/carbone-templates/433a0593-d3cf-414e-8763-ab5f87cbc75c.docx index ef2e299..234f070 100644 Binary files a/renderer/carbone-templates/433a0593-d3cf-414e-8763-ab5f87cbc75c.docx and b/renderer/carbone-templates/433a0593-d3cf-414e-8763-ab5f87cbc75c.docx differ diff --git a/renderer/carbone-templates/registry.json b/renderer/carbone-templates/registry.json index 8220a8d..39a6d72 100644 --- a/renderer/carbone-templates/registry.json +++ b/renderer/carbone-templates/registry.json @@ -6,6 +6,6 @@ "originalName": "master_cv_template.docx", "path": "/root/workspace/cv-app/renderer/carbone-templates/433a0593-d3cf-414e-8763-ab5f87cbc75c.docx", "uploadedAt": "2026-07-16T09:03:29.601Z", - "updatedAt": "2026-07-16T12:06:39.375Z" + "updatedAt": "2026-07-16T12:09:36.709Z" } ] \ No newline at end of file diff --git a/renderer/onlyoffice-service.js b/renderer/onlyoffice-service.js index 5804d30..7906b19 100644 --- a/renderer/onlyoffice-service.js +++ b/renderer/onlyoffice-service.js @@ -147,11 +147,11 @@ router.get('/:templateId/config', (req, res) => { const docKey = generateDocKey(templateId, Date.now()); const fileName = template.originalName || template.name + '.docx'; - // Add file mtime as cache-buster to the document URL so ONLYOFFICE - // always fetches the latest version from our backend. - // The mtime changes every time the file is saved, so the URL is - // different after each save, forcing ONLYOFFICE to re-download. - const documentUrl = `${BACKEND_PUBLIC_URL}/api/onlyoffice/${templateId}/download?mtime=${fileMtime}&cb=${Date.now()}`; + // Add the doc key to the download URL path so ONLYOFFICE treats + // every edit session as a completely fresh document URL. + // Query params alone aren't enough — ONLYOFFICE may ignore them for caching. + const keyHash = docKey.split('_').pop(); + const documentUrl = `${BACKEND_PUBLIC_URL}/api/onlyoffice/${templateId}/download/${keyHash}?mtime=${fileMtime}&cb=${Date.now()}`; const callbackUrl = `${BACKEND_PUBLIC_URL}/api/onlyoffice/${templateId}/callback`; const config = { @@ -223,9 +223,35 @@ router.get('/:templateId/config', (req, res) => { // ============================================================ // ENDPOINT: GET /api/onlyoffice/:templateId/download -// ONLYOFFICE fetches the .docx file from this URL +// ONLYOFFICE fetches the .docx file from this URL. +// The optional :keyHash path param provides per-session cache-busting. // ============================================================ +router.get('/:templateId/download/:keyHash', (req, res) => { + const templateId = req.params.templateId; + const registry = loadRegistry(); + const template = registry.find(t => t.id === templateId); + + if (!template) { + return res.status(404).json({ error: 'Template not found' }); + } + + if (!fs.existsSync(template.path)) { + return res.status(404).json({ error: 'Template file missing' }); + } + + const fileName = template.originalName || template.name + '.docx'; + res.setHeader('Content-Type', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'); + res.setHeader('Content-Disposition', `attachment; filename="${fileName}"`); + res.setHeader('Cache-Control', 'no-cache, no-store, must-revalidate'); + res.setHeader('Pragma', 'no-cache'); + res.setHeader('Expires', '0'); + + const fileStream = fs.createReadStream(template.path); + fileStream.pipe(res); +}); + +// Fallback route without keyHash (backward compatibility) router.get('/:templateId/download', (req, res) => { const templateId = req.params.templateId; const registry = loadRegistry(); diff --git a/static/carbone.js b/static/carbone.js index 0e66a1d..18b33a4 100644 --- a/static/carbone.js +++ b/static/carbone.js @@ -283,9 +283,11 @@ function closeOnlyofficeEditor() { // Reload the page to clear ONLYOFFICE's in-memory state. // Save the active page so the user returns to Templates automatically sessionStorage.setItem('returnPage', 'templates'); + // Wait 2 seconds for the save callback (status=2) to complete + // on our backend before reloading the page setTimeout(() => { location.reload(); - }, 300); + }, 2000); } // Open ONLYOFFICE editor in a modal diff --git a/static/index.html b/static/index.html index 79e4bce..23968c1 100644 --- a/static/index.html +++ b/static/index.html @@ -139,7 +139,7 @@ - - + + \ No newline at end of file