sciagent code + Gitea Actions CI/CD
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,40 @@
|
||||
# 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.ts`** — `DocumentTemplate`/`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).
|
||||
Reference in New Issue
Block a user