Automations deep redesign: message design studio with WhatsApp-native preview
COMPLETE RETHINK — from monitoring dashboard to message design studio.
## The Big Idea
Aaisha doesn't need a dashboard that says 'is it working?'
She needs a studio where she can SEE what Ahmed sees on his phone,
EDIT the words, TEST different approaches, and DESIGN cross-channel
sequences. The WhatsApp phone mockup is the star.
## New: Phone Mockups (3 channels)
- WhatsApp: green bubbles, blue ticks, org avatar, chat wallpaper,
full formatting (*bold*, _italic_, `code`, ━━━ dividers)
- Email: macOS mail client chrome, From header, subject line
- SMS: iOS Messages style, grey bubbles, contact avatar
## New: Template Editor
- Editable templates per step (receipt, day 2, 7, 14) per channel
- Live preview in phone mockup as you type
- Variable insertion chips: {{name}}, {{amount}}, {{reference}}, etc.
- Subject line editor for email channel
- Character count + SMS segment counter
## New: A/B Testing
- Create Variant B of any step/channel message
- 50/50 split traffic automatically
- Track sent count + conversion rate (paid after receiving)
- Side-by-side stats: 'A: 33% paid, B: 54% paid ★'
- Delete variant to revert to single message
## New: Channel Strategy Matrix
- 3 presets: Waterfall (default), Belt & Suspenders, Escalation
- Visual matrix: steps × channels with status indicators
- 1st = primary, fb = fallback, + = parallel send
- Waterfall: WhatsApp → SMS → Email (most cost-effective)
- Belt & Suspenders: all channels for receipts + final
- Escalation: start gentle (WA only), add channels as urgency increases
## New: Customizable Timing
- Each step's delay is editable inline (dropdown next to phone)
- Default: Day 2, Day 7, Day 14
- Can change to any schedule: Day 1, Day 3, Day 21, Day 28
## Schema: 2 new models
- MessageTemplate: per-org editable templates with A/B variants
(step, channel, variant, body, subject, splitPercent, sentCount, convertedCount)
- AutomationConfig: per-org timing + strategy + channel matrix
## API: /api/automations (GET/PATCH/DELETE)
- GET seeds defaults on first load (12 templates: 4 steps × 3 channels)
- PATCH upserts templates and config
- DELETE removes variant B and resets A to 100%
## Default templates (src/lib/templates.ts)
Extracted from hardcoded whatsapp.ts + reminders.ts into editable templates:
- WhatsApp: receipt, gentle, impact, final (with emoji + formatting)
- Email: receipt, gentle, impact, final (with cancel/pledge URLs)
- SMS: receipt, gentle, impact, final (160-char optimized)
## Architecture
templates.ts → resolvePreview() fills {{variables}} with examples
templates.ts → resolveTemplate() fills {{variables}} with real data
messaging.ts → sendToDonor() routes via channel waterfall
automations/route.ts → seeds + CRUD for templates + config
## Visual: Step timeline at top
4 tabs across the top with emoji, timing, description
Active step is dark (111827), others are white
Click to switch — editor and phone update together
## Layout
[Step Timeline — 4 tabs across top]
[Phone Mockup (left) | Editor (right)]
[Channel Strategy — expandable matrix]
[Live Feed — condensed stats + scheduled + messages]
This commit is contained in:
@@ -37,10 +37,12 @@ model Organization {
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
users User[]
|
||||
events Event[]
|
||||
pledges Pledge[]
|
||||
imports Import[]
|
||||
users User[]
|
||||
events Event[]
|
||||
pledges Pledge[]
|
||||
imports Import[]
|
||||
messageTemplates MessageTemplate[]
|
||||
automationConfig AutomationConfig?
|
||||
|
||||
@@index([slug])
|
||||
}
|
||||
@@ -234,6 +236,41 @@ model Import {
|
||||
@@index([organizationId])
|
||||
}
|
||||
|
||||
model MessageTemplate {
|
||||
id String @id @default(cuid())
|
||||
organizationId String
|
||||
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
|
||||
step Int // 0=receipt, 1=day2_gentle, 2=day7_impact, 3=day14_final
|
||||
channel String // whatsapp, email, sms
|
||||
variant String @default("A") // A, B for A/B testing
|
||||
name String // human label: "Gentle reminder", "Impact nudge"
|
||||
subject String? // email-only: subject line
|
||||
body String // template with {{variables}}
|
||||
isActive Boolean @default(true)
|
||||
splitPercent Int @default(100) // A/B: e.g. 50 = 50% get this variant
|
||||
sentCount Int @default(0)
|
||||
convertedCount Int @default(0) // donors who paid after receiving this
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@unique([organizationId, step, channel, variant])
|
||||
@@index([organizationId])
|
||||
}
|
||||
|
||||
model AutomationConfig {
|
||||
id String @id @default(cuid())
|
||||
organizationId String @unique
|
||||
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
|
||||
isActive Boolean @default(true)
|
||||
step1Delay Int @default(2) // days after pledge for step 1
|
||||
step2Delay Int @default(7) // days after pledge for step 2
|
||||
step3Delay Int @default(14) // days after pledge for step 3
|
||||
strategy String @default("waterfall") // waterfall, parallel, escalation, custom
|
||||
channelMatrix Json? // per-step channel config: { "0": ["whatsapp","email"], "1": ["whatsapp"], ... }
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
}
|
||||
|
||||
model AnalyticsEvent {
|
||||
id String @id @default(cuid())
|
||||
eventType String // pledge_start, amount_selected, rail_selected, identity_submitted, pledge_completed, instruction_copy_clicked, i_paid_clicked, payment_matched
|
||||
|
||||
Reference in New Issue
Block a user