# UpdateNotificationTemplate

## Permission Scope

template

## Overview

updateNotificationTemplate mutates the content fields of an existing NotificationTemplate row — `subject`, `body`, `htmlBody`, and `variableSchema`. The triple `(eventType, channelId, locale)` is the row identity and is not mutable. Updates are picked up by the next render call without redeploying the module; previously persisted Notifications retain whatever content was rendered at their original dispatch time (each Notification row immutably carries the `subject` / `body` / `htmlBody` rendered at dispatch alongside `payloadVars`, so historical rows are never retroactively rewritten). Variable-reference validation runs on every save so authoring drift is caught at the boundary.

## Business Rules

- `templateId` is required to identify the target row (or, equivalently, the `(eventType, channelId, locale)` triple)
- A NotificationTemplate row must exist for the supplied identifier
- `subject`, `body`, `htmlBody`, and `variableSchema` are individually optional but at least one must be supplied
- When `subject` or `body` is supplied, it must be non-blank after trimming
- Every `{{variable}}` reference in the resulting `subject` / `body` / `htmlBody` must be declared in the resulting `variableSchema` (after applying the update)
- Already-persisted Notifications are not retroactively re-rendered

## Process Flow

```mermaid
flowchart TD
    A[Receive update template request] --> B{NotificationTemplate exists?}
    B -->|No| C[Return TEMPLATE_NOT_FOUND]
    B -->|Yes| D{At least one mutable field supplied?}
    D -->|No| E[Return MISSING_REQUIRED_FIELD]
    D -->|Yes| F{Supplied subject / body non-blank where present?}
    F -->|No| E
    F -->|Yes| G[Compose post-update view of subject, body, htmlBody, variableSchema]
    G --> H{Every placeholder reference declared in variableSchema?}
    H -->|No| I[Return UNDECLARED_VARIABLE_REFERENCE]
    H -->|Yes| J[Update NotificationTemplate row with supplied fields]
    J --> K[Return updated template]
```

## External Dependencies

- None (operates on module-owned NotificationTemplate only)

## Error Scenarios

- **TEMPLATE_NOT_FOUND**: No NotificationTemplate row matches the supplied identifier
- **UNDECLARED_VARIABLE_REFERENCE**: subject / body / htmlBody contains a {{variable}} reference that is not declared in variableSchema
- **MISSING_REQUIRED_FIELD**: One or more required input fields are missing or blank

## Test Cases

- updates the subject on an existing NotificationTemplate row
- updates body and htmlBody together in one call
- updates the variableSchema and persists the new declared variables
- returns TEMPLATE_NOT_FOUND when the row does not exist
- returns UNDECLARED_VARIABLE_REFERENCE when the new body references a variable removed from variableSchema in the same update
- returns MISSING_REQUIRED_FIELD when no mutable field is supplied
- returns MISSING_REQUIRED_FIELD when supplied subject is blank
- subsequent renders pick up the new content immediately
- previously persisted Notifications retain their original rendered content
