Communications Module Specification — Email, SMS, Push, Templates
This commit is contained in:
@@ -0,0 +1,301 @@
|
||||
# Communications Module — Specification
|
||||
|
||||
## Vision
|
||||
|
||||
**One platform. All channels. Unified history.**
|
||||
|
||||
Every message to or from a customer — email, SMS, push, in-app — goes through one system. Complete history. No silos.
|
||||
|
||||
## Channels
|
||||
|
||||
| Channel | Direction | Use Case |
|
||||
|---------|-----------|----------|
|
||||
| **Email** | Two-way | Fakturor, aviseringar, nyhetsbrev, support |
|
||||
| **SMS** | Two-way | Uppdragsnotiser, påminnelser, verifiering |
|
||||
| **Push** | Outbound | Mobilnotiser, statusuppdateringar |
|
||||
| **In-App** | Two-way | Chatt, notiser, meddelanden i UI |
|
||||
| **Slack/Teams** | Outbound | Integrationer, alerts till team |
|
||||
|
||||
## Core Principle
|
||||
|
||||
**Every communication is a Thread.**
|
||||
|
||||
```
|
||||
Thread
|
||||
├── Customer: Municipality of Stockholm
|
||||
├── Subject: Mission #1234 — Road inspection completed
|
||||
├── Messages:
|
||||
│ ├── [Email] "Your mission is complete" → sent
|
||||
│ ├── [SMS] "Mission done, check email for report" → sent
|
||||
│ ├── [Email] "Re: Invoice question" ← received
|
||||
│ └── [In-App] "Thanks, all good" ← received
|
||||
└── Status: Resolved
|
||||
```
|
||||
|
||||
## Data Model
|
||||
|
||||
```typescript
|
||||
interface CommunicationThread {
|
||||
id: string;
|
||||
customerId: string; // org-nr
|
||||
type: 'mission' | 'invoice' | 'support' | 'marketing' | 'system';
|
||||
subject: string;
|
||||
referenceId?: string; // mission_123, invoice_456
|
||||
|
||||
messages: Array<{
|
||||
id: string;
|
||||
channel: 'email' | 'sms' | 'push' | 'in-app' | 'slack';
|
||||
direction: 'inbound' | 'outbound';
|
||||
status: 'pending' | 'sent' | 'delivered' | 'read' | 'failed' | 'bounced';
|
||||
|
||||
// Content
|
||||
subject?: string;
|
||||
body: string; // Plain text or HTML
|
||||
bodyHtml?: string;
|
||||
|
||||
// Recipients
|
||||
to: string[];
|
||||
cc?: string[];
|
||||
from: string;
|
||||
|
||||
// Metadata
|
||||
sentAt?: Date;
|
||||
deliveredAt?: Date;
|
||||
readAt?: Date;
|
||||
failedAt?: Date;
|
||||
errorMessage?: string;
|
||||
|
||||
// Provider tracking
|
||||
providerMessageId?: string; // Mailgun, Twilio, etc.
|
||||
}>;
|
||||
|
||||
status: 'open' | 'waiting' | 'resolved' | 'closed';
|
||||
priority: 'low' | 'normal' | 'high' | 'urgent';
|
||||
assignedTo?: string; // User ID
|
||||
tags: string[];
|
||||
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
resolvedAt?: Date;
|
||||
}
|
||||
```
|
||||
|
||||
## API Endpoints
|
||||
|
||||
```
|
||||
# Threads
|
||||
GET /api/v1/communications/threads → Lista threads (filter: customer, type, status)
|
||||
POST /api/v1/communications/threads → Skapa ny thread
|
||||
GET /api/v1/communications/threads/:id → Hämta thread med alla meddelanden
|
||||
PUT /api/v1/communications/threads/:id → Uppdatera (status, assignedTo, priority)
|
||||
|
||||
# Messages
|
||||
POST /api/v1/communications/threads/:id/messages → Skicka meddelande
|
||||
GET /api/v1/communications/threads/:id/messages → Lista meddelanden
|
||||
|
||||
# Templates
|
||||
GET /api/v1/communications/templates → Lista mallar
|
||||
POST /api/v1/communications/templates → Skapa mall
|
||||
PUT /api/v1/communications/templates/:id → Uppdatera mall
|
||||
|
||||
# Webhooks (från providers)
|
||||
POST /webhooks/mailgun → Mailgun events
|
||||
POST /webhooks/twilio → Twilio events
|
||||
POST /webhooks/sendgrid → SendGrid events
|
||||
```
|
||||
|
||||
## Templates
|
||||
|
||||
```typescript
|
||||
interface MessageTemplate {
|
||||
id: string;
|
||||
name: string;
|
||||
channel: 'email' | 'sms' | 'push';
|
||||
subject?: string; // For email
|
||||
body: string; // Supports {{variables}}
|
||||
bodyHtml?: string;
|
||||
|
||||
variables: Array<{
|
||||
name: string;
|
||||
description: string;
|
||||
required: boolean;
|
||||
defaultValue?: string;
|
||||
}>;
|
||||
|
||||
// Usage
|
||||
usageCount: number;
|
||||
lastUsedAt?: Date;
|
||||
|
||||
// Governance
|
||||
category: 'mission' | 'invoice' | 'support' | 'marketing' | 'system';
|
||||
language: 'sv' | 'en';
|
||||
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
}
|
||||
```
|
||||
|
||||
### Exempel-mallar
|
||||
|
||||
**Mission Complete (Email)**
|
||||
```
|
||||
Subject: Mission {{missionId}} — {{status}}
|
||||
|
||||
Hi {{customerName}},
|
||||
|
||||
Your mission {{missionId}} has been completed.
|
||||
|
||||
📍 Location: {{location}}
|
||||
📅 Completed: {{completedAt}}
|
||||
📊 Findings: {{findingCount}}
|
||||
|
||||
View full report: {{reportUrl}}
|
||||
|
||||
---
|
||||
LandveX Control Intelligence
|
||||
```
|
||||
|
||||
**Invoice Reminder (SMS)**
|
||||
```
|
||||
LandveX: Invoice {{invoiceNumber}} for {{amount}} is due {{dueDate}}.
|
||||
Pay: {{paymentUrl}}
|
||||
Questions? Reply or call {{supportPhone}}
|
||||
```
|
||||
|
||||
**Budget Alert (Email)**
|
||||
```
|
||||
Subject: Budget Alert — {{percentUsed}}% used
|
||||
|
||||
Hi {{customerName}},
|
||||
|
||||
You have used {{percentUsed}}% of your monthly budget ({{usedAmount}} / {{budgetAmount}}).
|
||||
|
||||
Consider adjusting your budget or contact us to discuss.
|
||||
|
||||
---
|
||||
LandveX
|
||||
```
|
||||
|
||||
## Providers
|
||||
|
||||
### Email
|
||||
- **Primary:** Mailgun (transactional)
|
||||
- **Secondary:** SendGrid (marketing/bulk)
|
||||
- **Backup:** AWS SES
|
||||
|
||||
### SMS
|
||||
- **Primary:** Twilio
|
||||
- **Secondary:** 46elks (Swedish)
|
||||
- **Backup:** AWS SNS
|
||||
|
||||
### Push
|
||||
- **Primary:** Firebase Cloud Messaging
|
||||
- **Secondary:** OneSignal
|
||||
|
||||
## Implementation
|
||||
|
||||
### Architecture
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────┐
|
||||
│ Communications API (port 3010) │
|
||||
│ - Thread management │
|
||||
│ - Template engine │
|
||||
│ - Queue management │
|
||||
└─────────────┬───────────────────────────┘
|
||||
│
|
||||
┌─────────┼─────────┐
|
||||
│ │ │
|
||||
┌───▼───┐ ┌──▼────┐ ┌──▼────┐
|
||||
│Email │ │ SMS │ │ Push │
|
||||
│Queue │ │ Queue │ │ Queue │
|
||||
└───┬───┘ └───┬───┘ └───┬───┘
|
||||
│ │ │
|
||||
┌───▼───┐ ┌──▼────┐ ┌──▼────┐
|
||||
│Mailgun│ │Twilio │ │FCM │
|
||||
│SendGrid│ │46elks │ │OneSignal
|
||||
└───────┘ └───────┘ └───────┘
|
||||
```
|
||||
|
||||
### Queue System
|
||||
|
||||
Every message goes through a queue:
|
||||
|
||||
```
|
||||
1. API receives send request
|
||||
2. Message saved to DB (status: pending)
|
||||
3. Message queued (Redis/RabbitMQ)
|
||||
4. Worker picks up message
|
||||
5. Send via provider
|
||||
6. Update status (sent/delivered/failed)
|
||||
7. Webhook updates status when provider confirms
|
||||
```
|
||||
|
||||
### Retry Policy
|
||||
|
||||
| Failure | Retry | Delay |
|
||||
|---------|-------|-------|
|
||||
| Network error | 3x | 5s, 30s, 5min |
|
||||
| Rate limit | 5x | 1min, 5min, 15min, 1h, 4h |
|
||||
| Invalid address | 0x | Mark as bounced |
|
||||
| Provider down | 10x | Exponential backoff |
|
||||
|
||||
## Integration Points
|
||||
|
||||
### Intelligence Lab
|
||||
- Mission complete → Send notification
|
||||
- Decision approved → Send report
|
||||
- Urgent finding → Alert immediately
|
||||
|
||||
### Operations API
|
||||
- Invoice generated → Send invoice email
|
||||
- Budget threshold → Alert
|
||||
- New user added → Welcome email
|
||||
|
||||
### Support System
|
||||
- Ticket created → Acknowledgment
|
||||
- Ticket updated → Notification
|
||||
- SLA warning → Alert
|
||||
|
||||
## MVP (Sprint 1)
|
||||
|
||||
- [ ] Email sending (Mailgun)
|
||||
- [ ] SMS sending (Twilio)
|
||||
- [ ] Thread model
|
||||
- [ ] Basic templates
|
||||
- [ ] Webhook handling
|
||||
|
||||
## Sprint 2
|
||||
|
||||
- [ ] Template editor
|
||||
- [ ] Queue system
|
||||
- [ ] Retry logic
|
||||
- [ ] Delivery tracking
|
||||
- [ ] Inbound email (replies)
|
||||
|
||||
## Sprint 3
|
||||
|
||||
- [ ] Push notifications
|
||||
- [ ] In-app messages
|
||||
- [ ] Slack integration
|
||||
- [ ] Analytics (open rates, etc.)
|
||||
|
||||
## Sprint 4
|
||||
|
||||
- [ ] A/B testing for templates
|
||||
- [ ] Advanced scheduling
|
||||
- [ ] Compliance (GDPR, unsubscribe)
|
||||
- [ ] Multi-language
|
||||
|
||||
## Status
|
||||
|
||||
**Specification:** ✅ KLAR
|
||||
**Implementation:** 🔄 EJ PÅBÖRJAD
|
||||
**Dependencies:**
|
||||
- Mailgun account
|
||||
- Twilio account
|
||||
- Redis (for queues)
|
||||
|
||||
---
|
||||
|
||||
**Nästa steg:** Konfigurera Mailgun + Twilio, bygg grundläggande API
|
||||
Reference in New Issue
Block a user