Technical Specification
This document covers the technical details of the CRM & Marketing Platform including event integration, API design, security, and performance requirements.
Event Integration
Event Transport
Phase 1: Redis + BullMQ (existing infrastructure)
Events Consumed
| Source | Event | CRM Action |
|---|---|---|
| SCL | member.created | Create/link profile, activity |
| SCL | member.updated | Update profile, activity |
| SCL | tier.changed | Update tier, activity, rescore |
| SCL | payment.received | Update LTV, activity |
| TeeTime | player.created | Create/link profile, activity |
| TeeTime | teetime.booked | Activity, update frequency |
| TeeTime | teetime.completed | Activity, trigger review |
| TeeTime | competition.published | Auto-promote (if enabled) |
| TeeTime | handicap.updated | Activity, update handicap |
| Messaging | message.sent | Activity |
| Messaging | message.delivered | Activity |
| Messaging | email.opened | Activity, engagement |
| Messaging | email.clicked | Activity, engagement |
| Messaging | contactPreference.updated | Update opt-in flags |
Events Produced
| Event | Trigger | Consumers |
|---|---|---|
| crm.profile.created | New profile | Analytics |
| crm.profile.merged | Duplicate merge | Messaging (update contact) |
| crm.segment.membership.changed | Segment refresh | Messaging (sync) |
| crm.campaign.scheduled | Campaign created | Job scheduler |
| crm.campaign.sent | Campaign executed | Analytics |
| crm.churn.risk.high | Risk score > 80 | Alerting |
API Design
REST Endpoints Summary
# Customer Profiles
GET /api/v1/customers
GET /api/v1/customers/:id
GET /api/v1/customers/resolve
POST /api/v1/customers
PATCH /api/v1/customers/:id
POST /api/v1/customers/:id/merge
# Activity Timeline
GET /api/v1/customers/:id/activities
POST /api/v1/customers/:id/activities
# Notes
GET /api/v1/customers/:id/notes
POST /api/v1/customers/:id/notes
# Segments
GET /api/v1/segments
POST /api/v1/segments
GET /api/v1/segments/:id/members
POST /api/v1/segments/:id/refresh
POST /api/v1/segments/:id/sync-to-messaging
# Campaigns
GET /api/v1/campaigns
POST /api/v1/campaigns
GET /api/v1/campaigns/:id
PATCH /api/v1/campaigns/:id
POST /api/v1/campaigns/:id/schedule
POST /api/v1/campaigns/:id/pause
POST /api/v1/campaigns/:id/resume
# Journeys
GET /api/v1/journeys
POST /api/v1/journeys
GET /api/v1/journeys/:id/steps
POST /api/v1/journeys/:id/activate
# Social
GET /api/v1/social/connections
POST /api/v1/social/connections/connect
DELETE /api/v1/social/connections/:id
GET /api/v1/social/posts
POST /api/v1/social/posts
POST /api/v1/social/posts/:id/publish
# Event Promotion
GET /api/v1/promotions
POST /api/v1/promotions
PATCH /api/v1/promotions/:id
# Analytics
GET /api/v1/analytics/engagement
GET /api/v1/analytics/campaigns
GET /api/v1/analytics/social
See API Reference for complete documentation.
Security & Privacy
Multi-Tenancy
- All queries filtered by
tenantId - Row-level security enforced
- No cross-tenant data leakage
Authentication & Authorization
API authenticated via existing IDP tokens.
Role-based access:
| Role | Permissions |
|---|---|
crm:read | View profiles, timeline |
crm:write | Add notes, tags |
crm:campaigns | Manage campaigns |
crm:social | Manage social connections |
crm:admin | Merge profiles, manage segments |
Social Token Security
- OAuth tokens encrypted at rest (AES-256)
- Refresh tokens stored separately
- Token expiry monitored and auto-refreshed
- Tokens never exposed in API responses
Data Privacy
- Consent flags synced from Messaging (read-only)
- GDPR right-to-erasure supported
- PII encrypted at rest
- Audit log for all data access
Right to Erasure (GDPR)
async eraseCustomer(profileId: string): Promise<void> {
// 1. Mark profile as DELETED
// 2. Anonymize PII fields
// 3. Remove from all segments
// 4. Notify downstream services
// 5. Create audit log entry
}
Performance Requirements
| Metric | Target |
|---|---|
| Profile lookup | under 100ms p99 |
| Timeline query | under 500ms p99 |
| Segment refresh | under 30 seconds for 10k members |
| Campaign scheduling | under 5 seconds |
| Social post publish | under 10 seconds |
| Event processing | under 5 seconds |
Caching Strategy
| Data | Cache TTL | Invalidation |
|---|---|---|
| Profile | 5 minutes | On update |
| Segment membership | 1 hour | On refresh |
| OAuth tokens | Until expiry | On refresh |
Database Optimization
Indexes
Primary query patterns are indexed:
-- Customer lookups
CREATE INDEX idx_customer_tenant_email ON CustomerProfile(tenantId, email);
CREATE INDEX idx_customer_tenant_phone ON CustomerProfile(tenantId, phoneNumber);
CREATE INDEX idx_customer_tenant_status ON CustomerProfile(tenantId, status);
-- Timeline queries
CREATE INDEX idx_activity_customer_date ON Activity(customerId, occurredAt DESC);
-- Segment queries
CREATE INDEX idx_membership_segment ON CustomerSegmentMembership(segmentId, customerId);
Partitioning (Future)
For high-volume tables:
-- Activity table partitioned by month
CREATE TABLE Activity (
...
) PARTITION BY RANGE (occurredAt);
Scaling Considerations
Current Design (v1)
- Single CRM database
- Redis/BullMQ for events
- 2 API replicas
Future Scale (v2)
| Component | Scale Strategy |
|---|---|
| Database | Read replicas, connection pooling |
| Event processing | Kafka for higher throughput |
| Search | Elasticsearch for full-text |
| Cache | Redis Cluster |
| API | Horizontal scaling |
Estimated Capacity (v1)
| Metric | Capacity |
|---|---|
| Profiles | 1M+ |
| Activities/day | 100K+ |
| Campaigns/day | 1000+ |
| Events/second | 100+ |
Monitoring & Observability
Metrics
| Metric | Type | Description |
|---|---|---|
crm_profiles_total | Gauge | Total profiles |
crm_events_processed_total | Counter | Events processed |
crm_event_processing_duration | Histogram | Processing time |
crm_api_request_duration | Histogram | API latency |
crm_campaign_sent_total | Counter | Messages sent |
Alerts
| Alert | Condition | Severity |
|---|---|---|
| High event queue depth | Queue > 10,000 | Warning |
| Event processing failures | Rate > 5% | Critical |
| API latency spike | p99 > 1s | Warning |
| Database connection pool exhausted | Available < 10% | Critical |
Logging
Structured JSON logs with:
{
"timestamp": "2024-12-14T10:00:00Z",
"level": "info",
"service": "crm",
"traceId": "abc123",
"event": "profile.created",
"tenantId": "tenant_123",
"profileId": "profile_456"
}
Error Handling
Retry Strategy
const retryConfig = {
attempts: 3,
backoff: {
type: 'exponential',
delay: 1000, // 1s, 2s, 4s
},
};
Dead Letter Queue
Failed events after all retries go to DLQ:
const dlqConfig = {
name: 'crm-events-dlq',
retentionDays: 7,
};
Circuit Breaker
For external service calls (Messaging, Social):
const circuitBreaker = {
threshold: 5, // failures before open
timeout: 30000, // ms before half-open
resetTimeout: 60000 // ms before close
};