---
id: DOM-ACC-BKS-004
title: Document Template
realises: CON-ACC-BKS-004
product_area: accounting
module: books
revision: 1
status: draft
design_intent: proposed
implementation_evidence: partially-observed
source_sha:
  services-accounting: f47cb263875bbc0c5640fba7dae6785ec32695f8
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
owned_by: SVC-ACC-BKS-books
readable_by:
  - SVC-ACC-BKS-maintenance
lifecycle: STATE-ACC-BKS-003
custom_fields: none
identity: >-
  Customer templates use immutable configuration identities within a workspace.
  Rhythm’s nine built-ins live in code under reserved identities and do not
  occupy customer template rows.
attributes:
  - name: kind
    kind: enum
    required: true
    computed: false
    notes: >-
      The fixed kind selects invoice, payment receipt, refund receipt, statement
      or batch-download behavior.
  - name: name and description
    kind: text
    required: true
    computed: false
    notes: A name is mandatory and descriptive wording is optional.
  - name: body source
    kind: text
    required: true
    computed: false
    notes: >-
      Liquid content is checked against the variables and filters offered for
      its kind.
  - name: e-mail parts
    kind: collection
    required: false
    computed: false
    notes: >-
      Email subject and body are paired; sender name and reply-to are optional,
      with up to ten CC and ten BCC addresses separately. Statements require
      email and downloads forbid it.
  - name: download output
    kind: collection
    required: false
    computed: false
    notes: 'Downloads require CSV, IIF or text output plus a Liquid filename.'
  - name: statement recipients
    kind: enum
    required: false
    computed: false
    notes: >-
      Statements default to all customer contacts; role selection instead names
      one to fifty roles.
  - name: active
    kind: enum
    required: true
    computed: false
    notes: The stored availability flag controls eligibility for resolution.
  - name: built-in
    kind: computed
    required: true
    computed: true
    notes: The returned record identifies protected code-based content as built-in.
  - name: used by
    kind: computed
    required: false
    computed: true
    notes: >-
      A computed usage list identifies current unit and statement-default
      references.
  - name: lock and version
    kind: computed
    required: true
    computed: true
    notes: Records retain a mutation version and a stored protection setting.
relationships:
  - to: DOM-ACC-BKS-001
    cardinality: Multiple units can select the same content for its document kind
    ownership: >-
      Units maintain their document selections; each shared template maintains
      its own content.
    cross_service: false
  - to: DOM-ACC-BKS-006
    cardinality: Workspace settings select at most one statement template
    ownership: >-
      Workspace settings maintain the single optional statement-default
      selection.
    cross_service: false
invariants:
  - id: INV-DOM-ACC-BKS-004-01
    statement: >-
      The kind assigned at customer-template creation cannot change in a later
      replacement.
    enforced_at:
      - service
      - database
    provenance: test
    source: >-
      services-accounting:modules/books/tests/e2e/document-templates.e2e.spec.js#answers
      409 to a change of kind, which is write-once
  - id: INV-DOM-ACC-BKS-004-02
    statement: >-
      Before saving, the service validates Liquid syntax and the variables and
      filters permitted for the document kind.
    enforced_at:
      - api
      - service
    provenance: test
    source: >-
      services-accounting:modules/books/tests/e2e/document-templates.e2e.spec.js#answers
      400 naming the line and column of Liquid that cannot be read
  - id: INV-DOM-ACC-BKS-004-03
    statement: >-
      Stored message, recipient and download parts satisfy the constraints for
      the template’s kind.
    enforced_at:
      - api
      - database
    provenance: test
    source: >-
      services-accounting:modules/books/tests/integration/db/document-templates.table.integration.spec.js#refuses
      a statement without its e-mail (Rhythm 1.0’s V6)
  - id: INV-DOM-ACC-BKS-004-04
    statement: >-
      Built-in content cannot be replaced or deleted through configuration, and
      customer identities cannot use its reserved prefix.
    enforced_at:
      - service
      - database
    provenance: test
    source: >-
      services-accounting:modules/books/tests/e2e/document-templates.e2e.spec.js#answers
      409 to a replacement of a built-in
  - id: INV-DOM-ACC-BKS-004-05
    statement: >-
      A template referenced by a unit or the statement default must remain
      active and cannot be removed.
    enforced_at:
      - service
      - database
    provenance: test
    source: >-
      services-accounting:modules/books/tests/e2e/document-templates.e2e.spec.js#answers
      409 to deleting the business unit’s template, naming the unit
  - id: INV-DOM-ACC-BKS-004-06
    statement: >-
      The resolver rejects an unusable explicit selection and never returns an
      inactive customer template.
    enforced_at:
      - service
    provenance: test
    source: >-
      services-accounting:modules/books/tests/unit/document-templates/resolution.spec.js#refuses
      an inactive template named explicitly, in Rhythm 1.0’s words
physical:
  - accounting.document_templates
  - built-in templates in code (no table)
evidence:
  - >-
    services-accounting at f47cb263:
    modules/books/db/document-templates.table.ts
  - >-
    services-accounting at f47cb263:
    modules/books/services/document-templates/built-ins.ts, filters.ts,
    previews.ts, resolution.ts, sample-data.ts, template-sources.ts,
    variables.ts; services/persistence/document-templates.ts
  - >-
    services-accounting at f47cb263:
    modules/transactions/services/invoices/invoice-rendering.ts,
    modules/billing/services/actions/send-statements.action.ts (cited producers)
  - >-
    react-console at baf6dae3: components/document-templates/*,
    components/configuration/resources/document-templates.tsx
---

# Document Template

## What It Models

Templates supply the content used to render Accounting documents and software downloads. They combine prepared wording with merge values, and include message or output parts where the kind requires them. Selection belongs to the requesting producer, unit or workspace settings; Books supplies the shared resolver.

## Identity and Attributes

Customer templates are workspace records. The nine protected built-ins are code-based defaults that can be read, previewed and copied. A copy becomes a separate active customer template.

Kind remains fixed. Liquid sources use a kind-specific catalogue, statements add recipient choices, and downloads add output and filename settings. The returned usage list helps staff identify current configuration dependencies.

## Relationships

Unit document choices and the statement default reference content without owning it. Those references protect the content from removal or deactivation. Invoice rendering uses the shared resolver; the examined statement action handles its own choice, so uniform producer adoption is not established.

## Invariants

Saved sources receive syntax and vocabulary validation, while database checks enforce kind-specific parts. Built-ins remain protected. Explicit resolution fails when the requested template is absent, wrong-kind or inactive; an unusable configured fallback is skipped in favor of built-in resolution.

## How It Is Stored and Shared

Books maintains customer content, built-ins, variables, filters and preview behavior. Preview uses sample data and does not save or send a document. Producing modules load content and render it within their own workflows. Maintenance includes customer templates in workspace export and erasure.

Template rows carry no custom-field capability. Workspace foreign keys and row policies prevent cross-customer configuration references.

## Open Design Questions

Each producer needs examination of resolver adoption. Rejecting inactive receipt, statement and download content remains a proposed departure from the described legacy behavior. The design does not establish language-specific template selection.
