Implement typed template library and rendering
This commit is contained in:
@@ -0,0 +1,32 @@
|
||||
# Templates Administrator Guide
|
||||
|
||||
## Permissions
|
||||
|
||||
- `templates:template:read` reads definitions and evidence.
|
||||
- `templates:template:write` creates immutable revisions.
|
||||
- `templates:template:publish` selects the revision allowed for final output.
|
||||
- `templates:template:render` validates and renders supplied snapshots.
|
||||
- `templates:template:admin` manages every visible tenant/group/user definition.
|
||||
|
||||
The managed `template_manager` role contains read, write, publish, and render.
|
||||
|
||||
## Scope And Publication
|
||||
|
||||
Definitions can be tenant-, group-, or user-scoped. Non-administrators may only
|
||||
write their own user templates and templates belonging to one of their groups.
|
||||
Published output remains pinned even when a later draft revision is created.
|
||||
|
||||
## Output Storage
|
||||
|
||||
Files is optional. When `files.artifact_store` is present and the actor has
|
||||
`files:file:upload`, managed output is written below `Generated/Templates` with
|
||||
template, input, and output hashes. Otherwise Templates stores a bounded
|
||||
database payload. Review database and Files retention together before deleting
|
||||
render evidence.
|
||||
|
||||
## Operations
|
||||
|
||||
Apply the module Alembic migration before startup. Monitor rejected renders for
|
||||
contract drift, output limits, missing Files permission, and reused idempotency
|
||||
keys. HTML is designed for browser/OS printing; do not treat it as a signed PDF
|
||||
or proof of physical printer delivery.
|
||||
+43
-101
@@ -1,113 +1,55 @@
|
||||
# Template Module Boundary
|
||||
|
||||
`govoplan-templates` owns reusable renderable templates, not the data selection
|
||||
or persistence semantics around the generated output.
|
||||
`govoplan-templates` owns reusable render definitions and immutable render
|
||||
evidence. Callers own data selection, approval, delivery, and lifecycle state.
|
||||
|
||||
The core boundary decision register is in
|
||||
`/mnt/DATA/git/govoplan-core/docs/MODULE_ARCHITECTURE.md`.
|
||||
## Owned Concepts
|
||||
|
||||
## Ownership
|
||||
- scoped template definitions and immutable revisions;
|
||||
- template type, usage, locale, required-field contracts, output profiles, and
|
||||
page/media hints;
|
||||
- safe HTML/text bodies and deterministic token substitution;
|
||||
- draft preview and published final rendering;
|
||||
- template, input, renderer, and output hashes plus item/page counts and
|
||||
diagnostics; and
|
||||
- bounded fallback payloads when no artifact store is available.
|
||||
|
||||
Templates owns:
|
||||
The implemented printable types are `label`, `label_sheet`, `envelope`,
|
||||
`serial_letter`, `form_letter`, and `list_layout`. `email` and `generic` use the
|
||||
same contract while preserving their explicit usage.
|
||||
|
||||
- template definitions for letters, decisions, permits, emails, forms, reports,
|
||||
certificates, notices, and workflow messages
|
||||
- template versions, draft/published lifecycle, localization, and merge-field
|
||||
declarations
|
||||
- render profiles such as output format, page/layout hints, fallback language,
|
||||
and safe preview mode
|
||||
- render-context schema declarations so callers know which fields are required
|
||||
- reusable template fragments inside configuration packages
|
||||
- rendering capability contracts exposed to mail, campaign, reporting, forms,
|
||||
workflow, cases, DMS, and files
|
||||
## Consumer Boundary
|
||||
|
||||
## Boundaries
|
||||
Templates never imports Addresses, Distribution Lists, Campaign, Files, Mail,
|
||||
Reporting, Forms, or Workflow internals. Consumers discover
|
||||
`templates.catalog` and `templates.renderer` through Core and submit plain
|
||||
provider-neutral DTOs. The supplied `input_snapshot` records a stable source
|
||||
reference; Templates does not fetch or silently refresh that source.
|
||||
|
||||
Templates does not own:
|
||||
Files optionally implements `files.artifact_store`. A final render can request
|
||||
managed persistence through that contract. If Files is absent, incompatible,
|
||||
or unauthorized, the result carries a warning and remains available through a
|
||||
5 MiB bounded Templates download. Managed output is not duplicated in the
|
||||
Templates payload column.
|
||||
|
||||
- report data selection, aggregation, dashboards, scheduled exports, or BI
|
||||
semantics; those belong to `govoplan-reporting`
|
||||
- document lifecycle, collaborative editing, locks, approvals, legal hold, or
|
||||
records management; those belong to `govoplan-dms` and `govoplan-records`
|
||||
- file/blob storage and file permissions; those belong to `govoplan-files`
|
||||
- mail sending, mailbox behavior, and mail profile policy; those belong to
|
||||
`govoplan-mail`
|
||||
- form submissions, drafts, receipts, and public submission state; those belong
|
||||
to `govoplan-forms-runtime` when implemented
|
||||
- workflow transitions, tasks, and case lifecycle
|
||||
## Safety And Determinism
|
||||
|
||||
## Initial Template Types
|
||||
- backend sanitization removes scripts, styles, active embeds, unsafe links,
|
||||
event handlers, and undeclared attributes;
|
||||
- substituted values are HTML escaped;
|
||||
- output is limited to 5,000 items and 5 MiB;
|
||||
- final output requires a published revision and idempotency key;
|
||||
- reusing an idempotency key with changed input is rejected;
|
||||
- every render pins the immutable definition hash and canonical input hash;
|
||||
- final artifacts contain hashes and references, not credentials or plaintext
|
||||
secrets in provenance; and
|
||||
- browser/OS printing from deterministic HTML is the baseline. PDF conversion
|
||||
and managed printer delivery belong to future connector adapters.
|
||||
|
||||
- `letter`
|
||||
- `decision_document`
|
||||
- `permit`
|
||||
- `email`
|
||||
- `form`
|
||||
- `report`
|
||||
- `certificate`
|
||||
- `notice`
|
||||
- `workflow_message`
|
||||
## Recovery
|
||||
|
||||
Template types can share a render engine but should keep type-specific metadata
|
||||
explicit, especially when retention, signature, accessibility, or delivery
|
||||
rules differ.
|
||||
|
||||
## Render Context Contract
|
||||
|
||||
Candidate render request:
|
||||
|
||||
```json
|
||||
{
|
||||
"template_id": "permit-decision",
|
||||
"template_version_id": "v1",
|
||||
"template_type": "permit",
|
||||
"locale": "de-DE",
|
||||
"output_format": "pdf",
|
||||
"context": {
|
||||
"case_id": "case-1",
|
||||
"recipient": {"display_name": "Example Person"},
|
||||
"decision": {"approved": true}
|
||||
},
|
||||
"trace": {"correlation_id": "request-1"}
|
||||
}
|
||||
```
|
||||
|
||||
Candidate render response:
|
||||
|
||||
```json
|
||||
{
|
||||
"render_id": "render-1",
|
||||
"template_id": "permit-decision",
|
||||
"template_version_id": "v1",
|
||||
"output_format": "pdf",
|
||||
"artifact": {
|
||||
"content_type": "application/pdf",
|
||||
"storage_ref": "files://generated/render-1.pdf",
|
||||
"checksum": "sha256:..."
|
||||
},
|
||||
"warnings": []
|
||||
}
|
||||
```
|
||||
|
||||
Generated artifact storage can be delegated to files/DMS through capabilities.
|
||||
Templates should not import those modules directly.
|
||||
|
||||
## Candidate Capabilities
|
||||
|
||||
- `templates.catalog`
|
||||
- `templates.renderer`
|
||||
- `templates.preview`
|
||||
- `templates.schema`
|
||||
- `templates.packageFragments`
|
||||
|
||||
Consumers should request these through core-mediated capability lookup. The
|
||||
template module should not import consumer modules.
|
||||
|
||||
## First Implementation Slice
|
||||
|
||||
1. Define manifest metadata, permissions, and capability names.
|
||||
2. Add template definition/version DTOs.
|
||||
3. Add render-context schema validation for one safe text/PDF preview path.
|
||||
4. Add package fragment format for reusable templates.
|
||||
5. Add tests that mail/campaign/reporting/forms can detect template capability
|
||||
presence without importing template internals.
|
||||
Template definitions, revisions, render evidence, and bounded output are in the
|
||||
shared database and therefore follow platform backup and restore. Managed Files
|
||||
artifacts follow Files recovery. Retiring the module is destructive only after
|
||||
the installer captures a database snapshot; consumers retain pinned hashes and
|
||||
must diagnose the now-unavailable provider.
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
# Templates User Guide
|
||||
|
||||
Open **Templates** to create or select a reusable definition.
|
||||
|
||||
1. Choose the template type and the contexts in which it may be used, such as
|
||||
`campaign.postal`.
|
||||
2. Declare every required input path and its type. Use the same paths as tokens
|
||||
in the body, for example `{{name}}` or `{{postal.address}}`.
|
||||
3. Configure page size and, for label sheets, rows, columns, and spacing.
|
||||
4. Save to create a new immutable revision. Publish the revision before using
|
||||
it for final output.
|
||||
5. In **Preview**, supply a representative JSON item. Compatibility validation
|
||||
explains missing fields, wrong types, unsupported usages, and output-format
|
||||
mismatches before output is produced.
|
||||
6. Preview a draft or render final output. Store it in Files when that module is
|
||||
available and you have upload permission; otherwise use the bounded download.
|
||||
|
||||
Render evidence shows the exact revision and abbreviated template, input, and
|
||||
output hashes. A consumer such as Campaign can submit many frozen recipients;
|
||||
the UI sample intentionally validates one representative item.
|
||||
Reference in New Issue
Block a user