Skip to main content

CRM Software Design Document (SDD)

Contact Relationship Management System

Document Information

  • Version: 1.0
  • Date: October 2025
  • Status: Draft
  • References: crm-requirements-document.md

Table of Contents

  1. System Architecture
  2. Component Design
  3. Data Architecture
  4. API Design
  5. Integration Architecture
  6. Security Architecture
  7. Performance Design
  8. Deployment Architecture

System Architecture

High-Level Architecture

Architecture Principles

  1. Microservices Pattern: Each major feature is a separate service
  2. Event-Driven: Asynchronous processing for enrichment and viral mechanics
  3. API-First: All functionality exposed through RESTful APIs
  4. Cache-Heavy: Redis caching for performance
  5. Cloud-Native: Designed for GCP services

Component Design

Contact Service

Purpose: Core CRUD operations for contact management

Key Components:

// src/services/contact_service.rs
pub struct ContactService {
db_pool: PgPool,
cache: RedisClient,
event_publisher: PubSubClient,
}

pub struct Contact {
pub id: Uuid,
pub user_id: Uuid,
pub email: String,
pub name: String,
pub company: Option<String>,
pub enrichment_status: EnrichmentStatus,
pub social_profiles: HashMap<String, String>,
pub custom_fields: JsonValue,
pub tags: Vec<String>,
pub relationship_stage: RelationshipStage,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}

Key Methods:

  • create_contact(): Create with duplicate detection
  • bulk_import(): Import with progress tracking
  • search_contacts(): Full-text search with filters
  • merge_contacts(): Intelligent duplicate merging

Enrichment Service

Purpose: AI-powered contact data enrichment

Architecture:

// src/services/enrichment_service.rs
pub struct EnrichmentService {
providers: Vec<Box<dyn EnrichmentProvider>>,
cache: RedisClient,
rate_limiter: RateLimiter,
}

#[async_trait]
pub trait EnrichmentProvider {
async fn enrich(&self, contact: &Contact) -> Result<EnrichmentData>;
fn provider_name(&self) -> &str;
fn cost_per_enrichment(&self) -> f64;
}

pub struct EnrichmentOrchestrator {
queue: PubSubSubscriber,
service: EnrichmentService,
credit_manager: CreditManager,
}

Enrichment Flow:

  1. Contact created/imported → Publish enrichment event
  2. Orchestrator consumes event → Check user credits
  3. Query multiple providers in parallel
  4. Merge and deduplicate data
  5. Update contact with enriched data
  6. Award credits for data contribution

Social Graph Service

Purpose: Relationship mapping and network analysis

Graph Model:

// src/services/social_graph_service.rs
pub struct SocialGraphService {
graph_db: GraphDatabase, // Could use PostgreSQL with recursive CTEs
cache: RedisClient,
analytics: GraphAnalytics,
}

pub struct Relationship {
pub from_contact_id: Uuid,
pub to_contact_id: Uuid,
pub relationship_type: RelationType,
pub strength: f32, // 0.0 to 1.0
pub interaction_count: i32,
pub last_interaction: DateTime<Utc>,
}

pub struct NetworkPath {
pub nodes: Vec<Uuid>,
pub total_distance: i32,
pub connection_quality: f32,
}

Key Algorithms:

  • Dijkstra's algorithm for shortest path
  • PageRank for influence scoring
  • Community detection for clustering
  • Relationship strength calculation

Communication Hub

Purpose: Unified communication tracking and analytics

Design:

// src/services/communication_hub.rs
pub struct CommunicationHub {
email_integrations: Vec<EmailProvider>,
sms_gateway: SmsGateway,
message_queue: MessageQueue,
analytics: CommunicationAnalytics,
}

pub struct Communication {
pub id: Uuid,
pub contact_id: Uuid,
pub channel: CommunicationChannel,
pub direction: Direction, // Inbound/Outbound
pub content: String,
pub sentiment_score: f32,
pub timestamp: DateTime<Utc>,
}

Viral Mechanics Engine

Purpose: Drive viral growth through gamification and incentives

Components:

// src/services/viral_engine.rs
pub struct ViralEngine {
credit_system: CreditSystem,
gamification: GamificationEngine,
analytics: ViralAnalytics,
}

pub struct ViralAction {
pub action_type: ActionType, // Import, Share, Referral, etc.
pub user_id: Uuid,
pub credits_earned: i32,
pub xp_earned: i32,
pub triggered_achievements: Vec<Achievement>,
}

pub struct ViralMetrics {
pub k_factor: f32,
pub viral_cycle_time: Duration,
pub conversion_rate: f32,
}

Data Architecture

Primary Database Schema

-- Core Contacts Table
CREATE TABLE contacts (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL REFERENCES users(id),
email VARCHAR(255) NOT NULL,
name VARCHAR(255) NOT NULL,
company VARCHAR(255),
title VARCHAR(255),
phone VARCHAR(50),
enrichment_status VARCHAR(50) DEFAULT 'pending',
enrichment_data JSONB,
social_profiles JSONB,
custom_fields JSONB,
tags TEXT[],
relationship_stage VARCHAR(50),
source VARCHAR(100),
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW(),
CONSTRAINT unique_user_email UNIQUE(user_id, email)
);

-- Social Graph Relationships
CREATE TABLE relationships (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
from_contact_id UUID REFERENCES contacts(id),
to_contact_id UUID REFERENCES contacts(id),
relationship_type VARCHAR(50),
strength DECIMAL(3,2),
interaction_count INTEGER DEFAULT 0,
last_interaction TIMESTAMPTZ,
metadata JSONB,
created_at TIMESTAMPTZ DEFAULT NOW(),
CONSTRAINT unique_relationship UNIQUE(from_contact_id, to_contact_id)
);

-- Communication History
CREATE TABLE communications (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
contact_id UUID REFERENCES contacts(id),
user_id UUID REFERENCES users(id),
channel VARCHAR(50),
direction VARCHAR(10),
subject TEXT,
content TEXT,
sentiment_score DECIMAL(3,2),
metadata JSONB,
occurred_at TIMESTAMPTZ,
created_at TIMESTAMPTZ DEFAULT NOW()
);

-- Viral Mechanics
CREATE TABLE viral_actions (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID REFERENCES users(id),
action_type VARCHAR(50),
credits_earned INTEGER,
xp_earned INTEGER,
metadata JSONB,
created_at TIMESTAMPTZ DEFAULT NOW()
);

-- Enrichment Credits
CREATE TABLE user_credits (
user_id UUID PRIMARY KEY REFERENCES users(id),
balance INTEGER DEFAULT 100,
lifetime_earned INTEGER DEFAULT 100,
lifetime_spent INTEGER DEFAULT 0,
updated_at TIMESTAMPTZ DEFAULT NOW()
);

Caching Strategy

Redis Cache Structure:

# Contact Cache
contact:{user_id}:{contact_id} -> Contact JSON (TTL: 1 hour)

# Search Cache
search:{user_id}:{query_hash} -> Contact IDs (TTL: 15 minutes)

# Social Graph Cache
graph:paths:{from_id}:{to_id} -> Path JSON (TTL: 1 hour)
graph:network:{user_id} -> Network Stats (TTL: 30 minutes)

# Enrichment Cache
enrichment:{email_hash} -> Enrichment Data (TTL: 7 days)

# User Credits Cache
credits:{user_id} -> Credit Balance (TTL: 5 minutes)

API Design

RESTful Endpoints

Contact Management:

POST   /api/crm/contacts                 Create contact
GET /api/crm/contacts List contacts (paginated)
GET /api/crm/contacts/:id Get contact details
PUT /api/crm/contacts/:id Update contact
DELETE /api/crm/contacts/:id Delete contact
POST /api/crm/contacts/bulk-import Import contacts
POST /api/crm/contacts/merge Merge duplicates
GET /api/crm/contacts/search Search contacts

Enrichment:

POST   /api/crm/enrichment/enrich/:id    Trigger enrichment
GET /api/crm/enrichment/status/:id Check enrichment status
GET /api/crm/enrichment/credits Get credit balance
POST /api/crm/enrichment/verify Verify and earn credits

Social Graph:

GET    /api/crm/graph/network/:id        Get contact's network
GET /api/crm/graph/path Find path between contacts
GET /api/crm/graph/influence/:id Get influence score
POST /api/crm/graph/introduce Request introduction

Communication Hub:

GET    /api/crm/communications/:contact  Get communication history
POST /api/crm/communications/track Track communication
GET /api/crm/communications/analytics Communication analytics
POST /api/crm/communications/remind Set reminder

Viral Mechanics:

GET    /api/crm/viral/stats              Get viral metrics
POST /api/crm/viral/refer Create referral
GET /api/crm/viral/leaderboard Get leaderboard
GET /api/crm/viral/achievements Get achievements

GraphQL Schema (Optional)

type Contact {
id: ID!
name: String!
email: String!
company: String
enrichmentData: EnrichmentData
relationships: [Relationship!]!
communications(limit: Int, offset: Int): [Communication!]!
networkStats: NetworkStats!
}

type Query {
contact(id: ID!): Contact
contacts(filter: ContactFilter, limit: Int, offset: Int): ContactConnection!
shortestPath(fromId: ID!, toId: ID!): NetworkPath
myViralStats: ViralStats!
}

type Mutation {
createContact(input: CreateContactInput!): Contact!
enrichContact(id: ID!): EnrichmentJob!
requestIntroduction(fromId: ID!, toId: ID!, message: String): IntroductionRequest!
}

Integration Architecture

Platform Integration Points

1. Authentication Integration:

// Shared with main platform
pub trait AuthProvider {
async fn validate_token(&self, token: &str) -> Result<User>;
async fn get_user_permissions(&self, user_id: Uuid) -> Result<Permissions>;
}

2. Event Bus Integration:

# Pub/Sub Topics
topics:
- contact.created
- contact.enriched
- viral.action.completed
- introduction.requested
- credits.earned

3. Billing Integration:

// Shared billing service
pub trait BillingProvider {
async fn check_subscription(&self, user_id: Uuid) -> Result<Subscription>;
async fn track_usage(&self, user_id: Uuid, feature: &str, amount: i32);
}

External Service Integrations

Enrichment Providers:

  • Clearbit: Company and person data
  • FullContact: Social profiles
  • Hunter.io: Email verification
  • Custom scrapers: LinkedIn, Twitter

Communication Providers:

  • SendGrid: Email tracking
  • Twilio: SMS gateway
  • Gmail API: Email sync
  • Outlook API: Calendar/email sync

Security Architecture

Data Protection

Encryption:

  • At rest: AES-256 for PII fields
  • In transit: TLS 1.3 minimum
  • Field-level encryption for sensitive data

Access Control:

pub enum ContactPermission {
ViewOwn,
ViewTeam,
EditOwn,
EditTeam,
Delete,
Export,
ShareExternal,
}

pub struct ContactAccessControl {
pub fn can_access(&self, user: &User, contact: &Contact, permission: ContactPermission) -> bool {
// Implement RBAC logic
}
}

Privacy Controls

Data Minimization:

  • Store only necessary data
  • Automatic PII purging after retention period
  • Anonymization for analytics

Consent Management:

pub struct ConsentManager {
pub fn record_consent(&self, contact_id: Uuid, consent_type: ConsentType);
pub fn check_consent(&self, contact_id: Uuid, action: &str) -> bool;
pub fn withdraw_consent(&self, contact_id: Uuid, consent_type: ConsentType);
}

Performance Design

Optimization Strategies

1. Database Optimization:

  • Composite indexes on (user_id, email)
  • Partial indexes for active contacts
  • Materialized views for analytics
  • Connection pooling with pgbouncer

2. Caching Strategy:

  • Write-through cache for contacts
  • Cache-aside for enrichment data
  • Distributed caching with Redis Cluster
  • Cache warming for popular queries

3. Async Processing:

  • Background enrichment jobs
  • Batch import processing
  • Deferred analytics calculation
  • Event-driven viral tracking

4. Query Optimization:

-- Optimized contact search with FTS
CREATE INDEX idx_contacts_search ON contacts
USING gin(to_tsvector('english', name || ' ' || email || ' ' || company));

-- Efficient relationship queries
CREATE INDEX idx_relationships_graph ON relationships(from_contact_id, to_contact_id)
INCLUDE (strength, relationship_type);

Scalability Considerations

Horizontal Scaling:

  • Stateless services for easy scaling
  • Read replicas for PostgreSQL
  • Sharding strategy for large datasets
  • Auto-scaling based on CPU/memory

Performance Targets:

  • Contact search: <100ms for 1M contacts
  • Enrichment: <2s average per contact
  • Graph traversal: <500ms for 3 degrees
  • API response: <200ms p95

Deployment Architecture

Container Structure

# Base image for Rust services
FROM rust:1.75-alpine AS builder
WORKDIR /app
COPY cargo.toml Cargo.lock ./
COPY crm-module/src ./src
RUN cargo build --release

FROM alpine:3.19
RUN apk add --no-cache ca-certificates
COPY --from=builder /app/target/release/crm-service /usr/local/bin/
EXPOSE 8080
CMD ["crm-service"]

Kubernetes Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
name: crm-contact-service
spec:
replicas: 3
selector:
matchLabels:
app: crm-contact-service
template:
metadata:
labels:
app: crm-contact-service
spec:
containers:
- name: contact-service
image: gcr.io/project/crm-contact-service:latest
ports:
- containerPort: 8080
env:
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: crm-secrets
key: database-url
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "500m"

Monitoring & Observability

Metrics:

  • Contact creation rate
  • Enrichment success rate
  • API latency percentiles
  • Cache hit rates
  • Viral K-factor

Logging:

use tracing::{info, error, instrument};

#[instrument]
pub async fn create_contact(&self, input: CreateContactInput) -> Result<Contact> {
info!("Creating contact for user {}", input.user_id);
// Implementation
}

Distributed Tracing:

  • OpenTelemetry integration
  • Trace ID propagation
  • Performance bottleneck identification

Testing Strategy

Unit Tests

#[cfg(test)]
mod tests {
use super::*;

#[tokio::test]
async fn test_contact_creation() {
let service = ContactService::new_test();
let contact = service.create_contact(/*...*/).await.unwrap();
assert_eq!(contact.email, "test@example.com");
}
}

Integration Tests

  • Test against real PostgreSQL
  • Mock external services
  • Test event publishing
  • Verify cache behavior

Performance Tests

  • Load test with k6
  • Benchmark critical paths
  • Stress test enrichment queue
  • Graph traversal performance

Migration Strategy

From Existing System

  1. Export existing contacts
  2. Transform to new schema
  3. Batch import with deduplication
  4. Gradual enrichment rollout
  5. Parallel run for validation

Database Migrations

-- Migration 001: Initial schema
CREATE TABLE contacts (...);

-- Migration 002: Add viral mechanics
CREATE TABLE viral_actions (...);

-- Migration 003: Performance indexes
CREATE INDEX CONCURRENTLY ...;

Risk Mitigation

Technical Risks

  1. Enrichment API Rate Limits: Multiple providers, caching, backoff
  2. Data Quality: Verification system, community validation
  3. Scale: Designed for 10M+ contacts from day one
  4. Privacy: GDPR compliance built-in

Business Risks

  1. Viral Growth Control: Circuit breakers for exponential growth
  2. Credit System Abuse: Fraud detection, rate limiting
  3. Data Accuracy: Multiple source verification
  4. Competition: Unique value proposition focus