346 lines
8.1 KiB
Markdown

# Email Templates
The Email Templates feature provides a complete email template management system with variable substitution, versioning, and rich text editing. Create reusable email templates for campaigns, notifications, and communications.
## Overview
The Email Templates system consists of four integrated components:
1. **[Template System](template-system.md)** - Template CRUD and management
2. **[Editor](editor.md)** - Rich text editor with variable insertion
3. **[Variables](variables.md)** - Dynamic content placeholders
4. **[Versioning](versioning.md)** - Template version history
## Features
### Template Management
- Create/edit/delete templates
- Category organization
- Template types (campaign, notification, system)
- Published/draft status
- Search and filtering
- Clone templates
### Rich Text Editor
- WYSIWYG HTML editor
- Variable insertion menu
- Preview mode
- HTML source view
- Image upload (future)
- Link management
### Variable System
Dynamic placeholders:
- **User variables** - `{{user.name}}`, `{{user.email}}`
- **Campaign variables** - `{{campaign.name}}`, `{{campaign.description}}`
- **Representative variables** - `{{rep.name}}`, `{{rep.title}}`, `{{rep.email}}`
- **Custom variables** - Template-specific placeholders
- **System variables** - `{{site.name}}`, `{{current.date}}`
### Version History
- Auto-save on changes
- Version diff viewer
- Restore previous versions
- Change log
## User Flow
### Admin Experience
1. **Create Template** (`/app/email-templates`)
- Click "New Template"
- Enter name and category
- Set template type
- Save draft
2. **Edit Template** (`/app/email-templates/:id/edit`)
- Full-screen rich text editor
- Insert variables from dropdown
- Preview with sample data
- Save changes
3. **Use Template**
- Select template in campaign form
- Variables auto-populated from context
- Send email with processed template
4. **Manage Versions** (`/app/email-templates/:id/versions`)
- View version history
- Compare versions
- Restore previous version
## Architecture
### Backend Components
**Module:**
- `api/src/modules/email-templates/email-templates.routes.ts` - Template CRUD
- `api/src/modules/email-templates/email-templates.service.ts` - Business logic
- `api/src/modules/email-templates/email-templates.schemas.ts` - Zod validation
**Database Models:**
- `EmailTemplate` - Template definitions (name, content, variables)
- `EmailTemplateVersion` - Version history (future)
**Email Processing:**
- Variable substitution in `email.service.ts`
- Mustache-style templating: `{{variable}}`
- HTML escaping for security
### Frontend Components
**Admin Pages:**
- `admin/src/pages/EmailTemplatesPage.tsx` - Template management table
- `admin/src/pages/EmailTemplateEditorPage.tsx` - Full-screen editor
**Editor Components:**
- `admin/src/components/email-templates/TemplateEditor.tsx` - Rich text editor
- `admin/src/components/email-templates/VariableInserter.tsx` - Variable dropdown
## Configuration
### Template Types
- **campaign** - Campaign email templates
- **notification** - User notifications
- **system** - System emails (verification, password reset)
- **custom** - Custom templates
### Template Categories
- **Influence** - Campaign-related templates
- **Map** - Shift/canvass notifications
- **User** - User account emails
- **System** - Automated system emails
## Variable System
### Available Variables
**User Context:**
```
{{user.id}} # User ID
{{user.email}} # Email address
{{user.name}} # Full name
{{user.role}} # User role
```
**Campaign Context:**
```
{{campaign.id}} # Campaign ID
{{campaign.name}} # Campaign name
{{campaign.description}} # Description
{{campaign.emailTemplate}} # Email body
```
**Representative Context:**
```
{{rep.name}} # Representative name
{{rep.title}} # Title (MP, MLA, etc.)
{{rep.email}} # Email address
{{rep.phone}} # Phone number
{{rep.district}} # District name
```
**System Context:**
```
{{site.name}} # Site name
{{site.url}} # Site URL
{{current.date}} # Current date
{{current.year}} # Current year
```
### Variable Insertion
```typescript
// Insert variable at cursor position
editor.insertContent('{{user.name}}');
// Variable dropdown menu
<Select>
<Option value="{{user.name}}">User Name</Option>
<Option value="{{user.email}}">User Email</Option>
<Option value="{{rep.name}}">Representative Name</Option>
</Select>
```
### Variable Processing
Server-side processing in `email.service.ts`:
```typescript
function processTemplate(
template: string,
variables: Record<string, any>
): string {
let processed = template;
for (const [key, value] of Object.entries(variables)) {
const placeholder = `{{${key}}}`;
processed = processed.replace(
new RegExp(placeholder, 'g'),
escapeHtml(String(value))
);
}
return processed;
}
```
## Database Schema
### EmailTemplate Model
```prisma
model EmailTemplate {
id Int @id @default(autoincrement())
name String
subject String
body String @db.Text
category String?
type String @default("custom")
variables Json? # Available variables
published Boolean @default(false)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
```
## API Endpoints
### Admin Endpoints
```
GET /api/email-templates # List templates
POST /api/email-templates # Create template
GET /api/email-templates/:id # Get template
PATCH /api/email-templates/:id # Update template
DELETE /api/email-templates/:id # Delete template
POST /api/email-templates/:id/clone # Clone template
GET /api/email-templates/:id/preview # Preview with sample data
```
## Security
### HTML Escaping
All variable values are HTML-escaped to prevent XSS:
```typescript
import { escapeHtml } from '../utils/sanitize';
const safe = escapeHtml(userInput);
// Converts: < > & " ' to HTML entities
```
### Template Validation
- Subject line: 1-200 characters
- Body: Required, max 50,000 characters
- Variables: Valid JSON object
- Category: Predefined list
## Best Practices
### Template Design
- Clear subject lines (50-60 chars)
- Personalize with variables
- Mobile-responsive HTML
- Plain text alternative
- Unsubscribe link
- Branding consistency
### Variable Usage
- Document available variables
- Provide defaults for missing values
- Test with sample data
- Validate variable names
### Version Management
- Meaningful version names
- Document changes
- Test before publishing
- Keep version history
## Desktop-Only Editor
Email template editor requires desktop browser:
```typescript
const screens = Grid.useBreakpoint();
const isMobile = !screens.md;
if (isMobile) {
return (
<Alert
message="Desktop Required"
description="Email editor requires desktop browser"
type="warning"
/>
);
}
```
## Integration Points
### Campaign Emails
Campaign emails use templates:
```typescript
// Select template in campaign form
<Select>
{templates.map(t => (
<Option value={t.id}>{t.name}</Option>
))}
</Select>
// Process template with campaign data
const emailBody = processTemplate(template.body, {
'user.name': user.name,
'campaign.name': campaign.name,
'rep.name': representative.name,
});
```
### System Emails
System emails (verification, password reset):
```typescript
// Load system template
const template = await getTemplateByType('email-verification');
// Process with user data
const emailBody = processTemplate(template.body, {
'user.name': user.name,
'verify.link': verificationUrl,
});
// Send email
await emailService.sendEmail({
to: user.email,
subject: template.subject,
html: emailBody,
});
```
## Related Documentation
- [Template System](template-system.md)
- [Editor](editor.md)
- [Variables](variables.md)
- [Versioning](versioning.md)
- [Email Templates Page](../../frontend/pages/admin/email-templates-page.md)
- [Email Template Editor Page](../../frontend/pages/admin/email-template-editor-page.md)
- [Email Service](../../backend/services/index.md)
- [Campaign Manager Guide](../../user-guides/campaign-manager-guide.md)