# Template Module Boundary `govoplan-templates` owns reusable renderable templates, not the data selection or persistence semantics around the generated output. The core boundary decision register is in `/mnt/DATA/git/govoplan-core/docs/MODULE_ARCHITECTURE.md`. ## Ownership Templates owns: - 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 ## Boundaries Templates does not own: - 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 ## Initial Template Types - `letter` - `decision_document` - `permit` - `email` - `form` - `report` - `certificate` - `notice` - `workflow_message` 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.