feat(templates): add service language template management

Add normalized service and template catalogs, scoped administration, migration, validation, and regression coverage.

Ref: IT-1601
This commit is contained in:
2026-10-17 22:02:43 +03:00
parent 36810dc5f1
commit 81654c0d33
73 changed files with 4061 additions and 820 deletions
+2 -2
View File
@@ -15,7 +15,7 @@ Accepted messages must have all of the following:
- non-empty `ServiceName`, `TemplateKey`, `RecipientEmail`, `RecipientName`, and `LanguageCode`
- a valid recipient address and a non-null `Variables` object
The service resolves a template by the exact `ServiceName`, `TemplateKey`, and normalized lower-case `LanguageCode`. It does not silently fall back to another language. Every variable marked `Required` by the selected template must have a non-empty value before rendering.
The worker first resolves a template by exact `ServiceName`, `TemplateKey` and the requested `LanguageCode`. If that exact version is missing, it makes one compatibility lookup using `LanguageCode.Trim().ToLowerInvariant()`, only when the result differs ordinally. Thus `RU` selects an existing exact `RU` version before `ru`, while `RU` or ` ru ` can resolve `ru` when their exact version is absent. There is no case-insensitive scan, regional substitution or fallback to another language; `RU-ru` does not search for `ru-RU` or `ru`. Blank codes are rejected. Every variable marked `Required` by the selected template must have a non-empty value before rendering.
## Delivery and acknowledgement policy
@@ -40,7 +40,7 @@ confirmed failure.
Delivery remains at least once. There is no inbox/deduplication store in this MVP, so a broker redelivery or a process failure after SMTP acceptance but before acknowledgement can produce a duplicate. `MessageId`, `CorrelationId`, and `MessageType` are added to the structured log scope for correlation. Recipient addresses are masked, and template variable names/values and rendered links are not logged.
No database migration is required. Existing channel selection, SMTP settings, quota checks, and usage counters remain in place.
The template model now requires the transactional [email template localization migration](email-template-localizations.md). Existing channel selection, SMTP settings, quota checks, and usage counters remain in place. Exact language codes, including regional variants, are preserved. API requests remain exact; worker sends retain only the bounded compatibility retry described above. Prefer the configured code to make the selected version explicit.
## Local end-to-end setup