Files
sciagent/docs/document-templates-feature.md
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

2.9 KiB

Document Templates — admin-managed forms (feature)

A from-scratch subsystem (2026-06-14): admins upload .docx templates with Jinja {{ placeholders }}; applicants fill a form generated from each template's fields and download a server-rendered PDF. Independent of the hardcoded sáng kiến form pipeline (which stays as-is).

Data + storage

  • Table document_templates (migration 015_document_templates.sql, model DocumentTemplate): id, name, description, storage_key, original_filename, content_sha256, fields JSONB ([{key,label,type}]), is_active, created_by, created_at, updated_at.
  • MinIO bucket initiative-templates (S3Settings.s3_bucket_templates, has a default; created by ensure_buckets_exist). Server-side only — no browser CORS / presign needed.

Backend — be0/src/template_routes.py (mounted /api/v1/templates)

  • POST /templates (admin) — multipart .docx → extract {{placeholders}} → MinIO + row.
  • GET /templates (authed; admin sees inactive too) · GET /{id} · GET /{id}/file (admin, raw docx).
  • PUT /{id} (admin) metadata · DELETE /{id} (admin) soft-delete, ?hard=true removes row + object.
  • POST /{id}/render (authed) — fill with values → DOCX (docxtpl) or PDF (reuses src.be01.docx_to_pdf.convert_docx_bytes_to_pdf, LibreOffice).
  • Placeholder extraction: docxtpl get_undeclared_template_variables() with a regex-on-stripped-XML fallback — DOCX often splits {{ }} across <w:r> runs, so stripping tags first recovers them.
  • Auth mirrors the extracted admin routers (decode_access_token_user_id/decode_bearer_token; admin = "admin" in JWT roles).

Frontend

  • @ump/shared/lib/templateApi.tsDocumentTemplate/TemplateField types + list/get/create (FormData)/update/delete/render (postArrayBuffer)/downloadFile + saveArrayBufferAs / arrayBufferToObjectUrl.
  • frontend_admin pages/TemplatesPage.tsx (+ layouts/AdminLayout.tsx shell; route /templates, admin-gated) — upload / list / edit meta / activate-deactivate / download / hard-delete (alert-dialog). Its first real feature.
  • frontend_user pages/TemplatesFillPage.tsx (route /dashboard/templates, sidebar « Mẫu tài liệu ») — pick a template → form generated from its fields → server PDF → iframe preview + download.

Verified

Backend e2e live against the dev stack: create → extract fields → render (filled values) → delete. @ump/shared + frontend_user + frontend_admin tsc --noEmit + vite build all clean. Commits c6d003c (BE) + 4f1cb3e (FE).

Deferred (v1 limitations)

  • No file-replace endpoint — delete + re-create to change a template's .docx (metadata edit works).
  • All fields render as single-line text — no type/date/number/long-text per field.
  • No audit-log entries on template create/update/delete (the rest of the app audits admin mutations).