Traducción. Autoritativo: fs-msg-0002-templates.md.
Contexto
La falla que esta feature previene es la que todo cliente ha visto:Hola {{first_name}}, llegando a
una bandeja. Ocurre cuando las plantillas aceptan variables arbitrarias y nadie las verifica contra
datos reales.
Acá las plantillas son componentes React Email en el repositorio, versionados y revisados como
código. Es un canje deliberado contra un editor visual: significa que cambiar una plantilla es un
deploy, y también que un marketero no la puede romper un viernes a las 6. Las variables se validan
contra core.attribute_definitions, de modo que una plantilla que referencia un campo que el tenant
no tiene falla al publicar y no al enviar.
Alcance (normativo)
messaging.message_templates: versionadas, por tenant, por canal.- Componentes React Email con contrato de variables declarado.
- Validación de variables contra
core.attribute_definitionsal publicar. - Branding por tenant: logo, colores, nombre del remitente, pie.
- Variantes por locale de la misma plantilla.
- Vista previa con datos de ejemplo y envío de prueba a una dirección elegida.
Fuera de alcance (normativo)
- Un editor de arrastrar y soltar. Las plantillas son código.
- Traducción de textos. El tenant aporta el texto por locale.
- Testing A/B — F2, y pertenece a campañas y no a plantillas.
Comportamiento (normativo)
- Una plantilla es versionada e inmutable una vez publicada. Un envío registra la versión que usó, así un mensaje se puede reproducir exacto un año después durante una disputa.
- Toda plantilla declara su contrato de variables. Publicar valida cada variable contra las definiciones de atributos del tenant y la forma del payload del evento; una variable desconocida bloquea la publicación.
- Renderizar con un valor ausente usa el fallback declarado, obligatorio para toda variable. No hay camino que renderice un placeholder vacío ni un token crudo.
- Una plantilla pertenece a exactamente un canal. El mismo mensaje en email y push son dos plantillas, porque las restricciones no son comparables.
- Las variantes por locale comparten id; la resolución usa el locale del destinatario y cae al default del tenant. Una variante ausente cae, no falla.
- Las plantillas de marketing deben incluir enlace de baja, inyectado por el renderer y no removible por el autor.
- Vista previa y envíos de prueba tienen rate limit y quedan auditados. Un envío de prueba va solo a una dirección que el probador controla.
- PROHIBIDO: renderizar con una variable no validada · una plantilla de marketing sin baja · editar una versión publicada en sitio.
Datos (normativo)
API (normativo)
Eventos (normativo)
Ninguno. Los cambios de plantilla son administrativos y quedan cubiertos por la auditoría.Criterios de aceptación (normativo)
- Publicar una plantilla con una variable inexistente para el tenant se rechaza, nombrándola.
- Una versión publicada no se puede editar; editar crea la versión + 1.
- Un envío registra su versión de plantilla, y esa versión renderiza igual un año después.
- Un valor ausente renderiza su fallback declarado — nunca un placeholder vacío ni un token crudo.
- Una plantilla de marketing renderiza con enlace de baja aunque el autor lo haya omitido.
- Un destinatario con locale no soportado recibe la variante por defecto del tenant.
- Un envío de prueba llega solo a la dirección indicada y queda auditado.
- Negativo: ninguna variable sin fallback declarado se puede publicar.
Ejecución
Un solo slice, comando síncrono. Los componentes viven enpackages/email-templates; el registro y
los endpoints en backend/api. El renderizado ocurre en el worker, nunca en el request de la API.