Developer Docs

Alert Templates

The Alert Templates UI is a frontend-only template management system accessible from the Admin Dashboard's Templates tab. It allows Malet Owners and platform administrators to design, preview, and export email and SMS alert templates using Handlebars syntax โ€” without requiring backend CRUD infrastructure.

NOTE

The backend alerts subgraph is a TCP microservice that reads .hbs templates from disk at startup. It does not yet expose a GraphQL CRUD API for template management. This frontend tool provides a design workspace for authoring templates, with JSON export for manual backend deployment. See Alerts Resilience for the backend architecture.

Architecture

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚         Admin Dashboard (+page.svelte)               โ”‚
โ”‚  Tab: "Templates" (lazy-loaded)                      โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚
โ”‚  โ”‚         AlertTemplateEditor.svelte               โ”‚ โ”‚
โ”‚  โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ โ”‚
โ”‚  โ”‚ โ”‚ Sidebar  โ”‚ โ”‚ Editor Pane  โ”‚ โ”‚ Preview Panel โ”‚ โ”‚ โ”‚
โ”‚  โ”‚ โ”‚ (List +  โ”‚ โ”‚ (Body/Subj/  โ”‚ โ”‚ (Email iframe โ”‚ โ”‚ โ”‚
โ”‚  โ”‚ โ”‚ Filters) โ”‚ โ”‚  Variants)   โ”‚ โ”‚  or SMS phone โ”‚ โ”‚ โ”‚
โ”‚  โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚  mockup)      โ”‚ โ”‚ โ”‚
โ”‚  โ”‚                               โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚
โ”‚                      โ†•                                โ”‚
โ”‚         alertTemplateStore.svelte.ts                  โ”‚
โ”‚         (localStorage persistence)                    โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Store: `alertTemplateStore.svelte.ts`

A Svelte 5 runes class (AlertTemplateStore) managing:

  • Templates array โ€” persisted to localStorage under mall_alert_templates
  • CRUD operations โ€” create, update, delete, duplicate
  • A/B variants โ€” up to 3 variants per template (A, B, C)
  • Variable detection โ€” auto-extracts {{variable}} patterns from body and subject
  • Template compilation โ€” client-side Handlebars-like substitution with sample data
  • Zod validation โ€” runtime schema validation via AlertTemplateSchema

Component: `AlertTemplateEditor.svelte`

Three-panel layout:

  1. Sidebar โ€” Template list with search, channel filter (All/Email/SMS), create form, export all button
  2. Editor Pane โ€” Name input, channel selector, subject line (Email only), A/B variant tabs, Handlebars body textarea, variable inspector
  3. Preview Panel โ€” Live-rendered preview with device toggle

Component: `AlertTemplatePreview.svelte`

Renders two preview modes:

  • Email โ€” Sandboxed <iframe> with browser-chrome mockup (traffic light dots, From address, subject line), Desktop/Mobile width toggle
  • SMS โ€” Phone mockup with notch, carrier bar, iMessage-style bubble, character count with multi-segment warning (>160 chars)

Data Model

AlertTemplate

interface AlertTemplate {
  id: string;                           // Auto-generated: tpl_{timestamp}_{random}
  name: string;                         // Required, min 1 char
  channel: 'EMAIL' | 'SMS';            // Delivery channel
  subject: string;                      // Email subject line (empty for SMS)
  body: string;                         // Handlebars template body
  variables: string[];                  // Auto-detected {{variable}} names
  variants: TemplateVariant[];          // A/B overrides (max 3)
  sampleData: Record<string, string>;   // Variable โ†’ sample value mapping
  createdAt: string;                    // ISO timestamp
  updatedAt: string;                    // ISO timestamp
}

TemplateVariant

interface TemplateVariant {
  key: 'A' | 'B' | 'C';   // Variant identifier
  subject: string;          // Override subject line
  body: string;             // Override body template
  isControl: boolean;       // Whether this is the control variant
}

CRUD Operations

Operation Method Behavior
Create store.create(name, channel) Scaffolds a template with default Handlebars body
Update store.update(id, updates) Auto-re-extracts variables on body change
Delete store.delete(id) Removes from store + localStorage
Duplicate store.duplicate(id) Deep clone with " (Copy)" name suffix
Export store.exportTemplate(id) JSON download of a single template
Export All store.exportAll() JSON download of the full template array
Import store.importTemplates(json) Zod-validated bulk import with regenerated IDs

Variable Detection

Templates use {{variable}} Handlebars syntax for dynamic content. The variable extractor scans the body and subject for {{ ... }} patterns and automatically populates the Variable Inspector panel.

The extractor excludes Handlebars control constructs:

  • Block helpers: {{#if ready}}, {{/if}}, {{#each items}}
  • Comments: {{! this is a comment }}
  • Partials: {{> header_partial}}

Detected variables appear with editable sample value inputs. Changes to sample values immediately update the live preview.

A/B Variant Comparison

Each template supports up to 3 variants (A, B, C) accessed via pill tabs above the body editor. Each variant independently overrides the subject line and body content.

Compare Mode

Toggle the โ‡„ Compare button to view all variants side-by-side in the preview panel. This enables visual comparison of variant wording, layout, and length without switching tabs.

TIP

Variants are a design-time tool โ€” they don't distribute traffic. When the backend adds A/B testing support, the variant data structure (TemplateVariant) is ready for GraphQL transmission.

Preview Rendering

Email Preview

Feature Implementation
Rendering Sandboxed <iframe> with sandbox="" (no scripts)
Chrome Traffic light dots, "From: noreply@ngwenya.app", subject line
Desktop Full iframe width
Mobile Constrained to 375px max-width

SMS Preview

Feature Implementation
Rendering Stripped HTML โ†’ plain text in bubble UI
Chrome Phone frame with notch, "Mallnline" carrier, live clock
Bubble Blue iMessage-style right-aligned bubble
Length Character count with "multi-segment" warning at >160 chars

Admin Dashboard Integration

The Templates tab is lazy-loaded in src/routes/admin/+page.svelte:

{#if activeTab === 'templates'}
  {#await import('$lib/components/admin/AlertTemplateEditor.svelte') then module}
    <module.default />
  {/await}
{/if}

This ensures the template editor and its dependencies (Handlebars compilation, Zod schemas) are only loaded when the user navigates to the Templates tab.

Persistence

Templates are stored in localStorage under the key mall_alert_templates as a JSON array. The export format matches the AlertTemplate interface exactly, enabling:

  • Manual backup via single or bulk JSON export
  • Cross-environment migration via import
  • Backend handoff when the alerts subgraph adds GraphQL CRUD

Future Backend Wiring

When the alerts subgraph exposes a GraphQL TemplateService:

  1. Replace localStorage persistence with GraphQL mutations
  2. Wire CRUD operations to CREATE_ALERT_TEMPLATE / UPDATE_ALERT_TEMPLATE mutations
  3. Add server-side Handlebars compilation for production-accurate preview
  4. Wire A/B variants to the backend distribution engine

File Map

File Purpose
src/stores/alertTemplateStore.svelte.ts Store: CRUD, variants, compilation, validation
src/lib/components/admin/AlertTemplateEditor.svelte Three-panel editor UI
src/lib/components/admin/AlertTemplatePreview.svelte Email iframe + SMS phone preview
src/routes/admin/+page.svelte Templates tab integration
tests/alertTemplateStore.test.ts 29 unit tests

  • Alerts Resilience โ€” Backend alerts architecture, TCP transport, Handlebars templates, delivery pipeline
  • Alerts Subgraph โ€” Subgraph internals: preference storage, email/SMS delivery, WebSocket subscriptions
  • Blog Editor UX โ€” Companion editor in the Admin Dashboard with its own pipeline workflow
  • Admin Analytics Dashboards โ€” Analytics tabs alongside the Templates tab in the Admin Dashboard
  • Invite & Notification Pipeline โ€” Cross-subgraph notification flow using the alerts TCP service
  • uMail Domain Verification โ€” DNS setup for mallnline.com ensuring email template delivery via verified Resend sender