feat(templates): T4 sendTemplated() + outbound provenance

- IiosOutboundCommand gains templateKey/version/locale/renderedHash (migration).
- OutboundService.send accepts an optional opaque `provenance` and writes it into
  the command on BOTH the PENDING and RATE_LIMITED create paths — the only way to
  stamp provenance by construction, since send() creates the row itself (review
  finding). OutboundService still neither renders nor resolves templates.
- TemplatedSender.sendTemplated: render -> OutboundService.send -> provenance, one
  entry point. EMAIL payload = {subject,html,text}; SMS = {text}. Idempotent per key.

Tests: 4 sender + 16 adapters regression green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-18 12:28:28 +05:30
parent 8ce647552a
commit 10f3545a25
6 changed files with 162 additions and 3 deletions
@@ -4,7 +4,7 @@ import { SandboxProvider } from './sandbox.provider';
import { HttpProvider } from './http.provider';
import { EmailProvider } from './email.provider';
const DEFAULT_CHANNELS = ['WEBHOOK', 'EMAIL', 'WHATSAPP', 'PORTAL'];
const DEFAULT_CHANNELS = ['WEBHOOK', 'EMAIL', 'SMS', 'WHATSAPP', 'PORTAL'];
/**
* Maps a channelType to the provider that executes egress for it. Sandbox by