# Architecture Documentation

**Service**: mkt-whatsapp-service-net  
**Version**: 1.0  
**Last Updated**: 2026-01-18

## System Overview

The MKT WhatsApp Service is a comprehensive microservice built on Clean Architecture principles, implementing Domain-Driven Design (DDD) and CQRS patterns. It provides three core capabilities:

1. **Automation Chatbot**: Rule-based conversation flows
2. **AI Chatbot**: LLM-powered intelligent responses  
3. **Customer Management**: Unified CRM for WhatsApp interactions

### High-Level Architecture

```mermaid
graph TB
    subgraph External
        WA[WhatsApp Cloud API]
        OPENAI[OpenAI GPT-4]
        Customer[End Users]
    end
    
    subgraph "GoodGo Platform"
        GATEWAY[Traefik Gateway]
        
        subgraph "mkt-whatsapp-service-net"
            API[API Layer]
            APP[Application Layer]
            DOMAIN[Domain Layer]
            INFRA[Infrastructure Layer]
        end
        
        PG[(PostgreSQL)]
        REDIS[(Redis)]
        RABBIT[RabbitMQ]
    end
    
    subgraph "Other Services"
        MERCHANT[merchant-service]
        ANALYTICS[analytics-service]
    end
    
    Customer -->|Messages| WA
    WA -->|Webhooks| GATEWAY
    GATEWAY --> API
    API --> APP
    APP --> DOMAIN
    APP --> INFRA
    INFRA --> PG
    INFRA --> REDIS
    INFRA --> WA
    INFRA --> OPENAI
    INFRA --> RABBIT
    RABBIT --> MERCHANT
    RABBIT --> ANALYTICS
    
    style Customer fill:#2C3E50,color:#ECF0F1,stroke:#34495E,stroke-width:3px
    style WA fill:#3498DB,color:#ECF0F1,stroke:#2980B9,stroke-width:3px
    style OPENAI fill:#3498DB,color:#ECF0F1,stroke:#2980B9,stroke-width:3px
    style GATEWAY fill:#3498DB,color:#ECF0F1,stroke:#2980B9,stroke-width:3px
    style API fill:#8E44AD,color:#ECF0F1,stroke:#7D3C98,stroke-width:2px
    style APP fill:#8E44AD,color:#ECF0F1,stroke:#7D3C98,stroke-width:2px
    style DOMAIN fill:#8E44AD,color:#ECF0F1,stroke:#7D3C98,stroke-width:2px
    style INFRA fill:#8E44AD,color:#ECF0F1,stroke:#7D3C98,stroke-width:2px
    style PG fill:#34495E,color:#ECF0F1,stroke:#2C3E50,stroke-width:2px
    style REDIS fill:#34495E,color:#ECF0F1,stroke:#2C3E50,stroke-width:2px
    style RABBIT fill:#34495E,color:#ECF0F1,stroke:#2C3E50,stroke-width:2px
    style MERCHANT fill:#27AE60,color:#ECF0F1,stroke:#229954,stroke-width:2px
    style ANALYTICS fill:#27AE60,color:#ECF0F1,stroke:#229954,stroke-width:2px
```

## Clean Architecture Layers

### 1. API Layer (`MktWhatsAppService.API`)

**Responsibility**: HTTP interface, request/response handling

#### Controllers
- `WebhooksController` - WhatsApp webhook verification and message events
- `WhatsAppAccountsController` - Account connection management
- `ConversationsController` - Conversation and message endpoints
- `CustomersController` - Customer profile management
- `AutomationFlowsController` - Automation flow CRUD
- `AIAgentsController` - AI agent configuration
- `AnalyticsController` - Metrics and reporting

#### Background Jobs
- `ConversationExpiryJob` - Close expired 24h conversations
- `MessageStatusSyncJob` - Sync delivery/read status from WhatsApp
- `FlowSchedulerJob` - Trigger time-based automation flows

### 2. Application Layer (`MktWhatsAppService.API/Application`)

**Responsibility**: Use cases, orchestration, CQRS

#### Commands (Writes)

**WhatsApp Account**
- `ConnectWhatsAppAccountCommand` - Register new account
- `UpdateWebhookCommand` - Update webhook configuration
- `DisconnectWhatsAppAccountCommand` - Deactivate account

**Messages**
- `ProcessIncomingMessageCommand` - Handle incoming WhatsApp message
- `SendMessageCommand` - Send outbound message
- `SendTemplateMessageCommand` - Send pre-approved template

**Automation**
- `CreateAutomationFlowCommand` - Define new flow
- `UpdateFlowStepCommand` - Modify flow logic
- `ActivateFlowCommand` - Enable automation
- `DeactivateFlowCommand` - Disable automation

**AI Agent**
- `CreateAIAgentCommand` - Configure AI chatbot
- `UpdateAgentPersonalityCommand` - Modify AI behavior
- `GenerateAIResponseCommand` - Get AI reply

**Customers**
- `CreateCustomerCommand` - Register new customer
- `UpdateCustomerOptInCommand` - Manage opt-in consent
- `TagCustomerCommand` - Add/remove tags

#### Queries (Reads)

**Conversations**
- `GetConversationQuery` - Single conversation with messages
- `GetActiveConversationsQuery` - List ongoing conversations
- `SearchConversationsQuery` - Full-text search

**Customers**
- `GetCustomerQuery` - Customer profile by WaId
- `GetCustomersQuery` - Paginated customer list
- `GetCustomerConversationHistoryQuery` - All past conversations

**Analytics**
- `GetMessageStatsQuery` - Message volume metrics
- `GetConversationMetricsQuery` - Response times, resolution rates
- `GetAutomationPerformanceQuery` - Flow execution stats

#### MediatR Pipeline Behaviors
1. **Logging Behavior** - Log all commands/queries
2. **Validation Behavior** - FluentValidation integration
3. **Transaction Behavior** - Unit of Work for commands

### 3. Domain Layer (`MktWhatsAppService.Domain`)

**Responsibility**: Business logic, entities, business rules

#### Aggregates

##### WhatsAppAccount Aggregate
**Aggregate Root**: `WhatsAppAccount`

Properties:
- `Id` (Guid)
- `ShopId` (Guid)
- `PhoneNumberId` (string) - WhatsApp phone number ID
- `AccessToken` (string, encrypted)
- `WebhookUrl` (string)
- `Status` (Active/Suspended)
- `MessageTier` (1K/10K/100K/Unlimited)

Business Methods:
- `Activate()` - Activate account
- `UpdateWebhook(url)` - Change webhook URL
- `Suspend()` - Suspend account

Domain Events:
- `WhatsAppAccountConnectedEvent`
- `WebhookVerifiedEvent`

##### Conversation Aggregate
**Aggregate Root**: `Conversation`

Properties:
- `Id` (Guid)
- `ShopId` (Guid)
- `CustomerWaId` (string)
- `Status` (Active/Closed/Expired)
- `AssignedAgentId` (Guid, nullable)
- `LastMessageAt` (DateTime)
- `Tags` (List<string>)

Entities:
- `Message`
  - `Id` (Guid)
  - `WhatsAppMessageId` (string)  
  - `Direction` (Inbound/Outbound)
  - `Content` (MessageContent value object)
  - `Status` (Sent/Delivered/Read/Failed)
  - `Timestamp` (DateTime)

Business Methods:
- `AddMessage(content, direction)` - Add message to conversation
- `AssignToAgent(agentId)` - Assign conversation  
- `Close()` - Close conversation
- `CheckExpiry()` - Check 24h window

Domain Events:
- `ConversationStartedEvent`
- `MessageReceivedEvent`
- `MessageSentEvent`
- `ConversationClosedEvent`

##### AutomationFlow Aggregate
**Aggregate Root**: `AutomationFlow`

Properties:
- `Id` (Guid)
- `ShopId` (Guid)
- `FlowName` (string)
- `TriggerType` (Keyword/Event/Schedule)
- `TriggerConfig` (JSON)
- `IsActive` (bool)

Entities:
- `FlowStep`
  - `Order` (int)
  - `Action` (SendMessage/TagCustomer/CallWebhook/Delay)
  - `ActionConfig` (JSON)
  - `Conditions` (JSON, optional)
  - `NextStepId` (int, nullable)

Business Methods:
- `AddStep(action, config, conditions)` - Add flow step
- `ValidateFlow()` - Check for cycles, validate structure
- `Activate()` - Enable flow
- `Deactivate()` - Disable flow

##### AIAgent Aggregate
**Aggregate Root**: `AIAgent`

Properties:
- `Id` (Guid)
- `ShopId` (Guid)
- `AgentName` (string)
- `Personality` (AgentPersonality value object)
- `KnowledgeBaseId` (Guid, nullable)
- `IsActive` (bool)

Value Objects:
- `AgentPersonality`
  - `Tone` (Friendly/Professional/Casual)
  - `Language` (Vietnamese/English)
  - `Constraints` (List<string>)
  - `PromptTemplate` (string)

Business Methods:
- `UpdatePersonality(personality)` - Change AI behavior
- `Activate()` - Enable AI responses
- `Deactivate()` - Disable AI

##### Customer Aggregate
**Aggregate Root**: `Customer`

Properties:
- `Id` (Guid)
- `WaId` (string) - WhatsApp ID (phone number)
- `ShopId` (Guid)
- `Name` (string)
- `ProfilePictureUrl` (string, nullable)
- `Consent` (OptInConsent value object)
- `Tags` (List<string>)
- `CustomFields` (Dictionary<string, string>)
- `FirstContactedAt` (DateTime)

Value Objects:
- `OptInConsent`
  - `Status` (OptedIn/OptedOut/Pending)
  - `Timestamp` (DateTime)
  - `Source` (Web/WhatsApp/Manual)

Business Methods:
- `UpdateOptIn(status, source)` - Manage consent
- `AddTag(tag)` - Add customer tag
- `RemoveTag(tag)` - Remove tag
- `UpdateCustomField(key, value)` - Set custom field

### 4. Infrastructure Layer (`MktWhatsAppService.Infrastructure`)

**Responsibility**: External concerns, persistence, API clients

#### Data Access
- `MktWhatsAppServiceContext` - EF Core DbContext
- Entity Configurations using Fluent API
- Repositories implementing domain interfaces

#### External Services

##### WhatsAppCloudApiClient
HTTP client for WhatsApp Cloud API with Polly resilience policies:

Methods:
- `SendMessageAsync()` - Send text/media/interactive messages
- `SendTemplateMessageAsync()` - Send pre-approved templates
- `MarkMessageAsReadAsync()` - Send read receipts
- `GetMediaAsync()` - Download media files

Resilience:
- **Retry**: 3 attempts, exponential backoff (500ms, 1.5s, 4.5s)
- **Circuit Breaker**: 50% failure ratio, 30s sampling, 30s break
- **Timeout**: 10s per request

##### LlmService
LLM provider abstraction (OpenAI implementation):

Methods:
- `GenerateResponseAsync()` - Get AI response with context
- `ExtractIntentAsync()` - Classify user intent
- `StreamResponseAsync()` - Streaming for long responses

Features:
- Token usage tracking
- Cost calculation
- Context window management (last 10 messages)
- Safety filters

## Message Processing Flow

### Incoming Message Flow

```mermaid
sequenceDiagram
    participant WA as WhatsApp
    participant Webhook as WebhooksController
    participant Cmd as ProcessIncomingMessageHandler
    participant AutoEngine as AutomationEngine
    participant AIEngine as AIEngine
    participant DB as Database
    
    WA->>Webhook: POST /webhooks (message event)
    Webhook->>Webhook: Verify signature
    Webhook->>Cmd: ProcessIncomingMessageCommand
    Webhook-->>WA: 200 OK (immediate)
    
    Cmd->>DB: Get/Create Conversation
    Cmd->>DB: Save Message
    
    alt Active Automation Flow
        Cmd->>AutoEngine: Check triggers
        AutoEngine->>AutoEngine: Match keywords/conditions
        AutoEngine->>WA: Send automated response
    else AI Agent Active
        Cmd->>AIEngine: GenerateAIResponseCommand
        AIEngine->>DB: Get history (last 10 msgs)
        AIEngine->>AIEngine: Build prompt
        AIEngine->>OpenAI: Chat completion
        OpenAI-->>AIEngine: AI response
        AIEngine->>WA: Send AI message
    else Manual Response
        Cmd->>DB: Mark conversation pending
        Cmd->>RabbitMQ: Publish event
    end
```

### Outbound Message Flow

```mermaid
sequenceDiagram
    participant API as ConversationsController
    participant Cmd as SendMessageHandler
    participant Domain as Conversation Aggregate
    participant WA as WhatsAppCloudApiClient
    participant DB as Database
    
    API->>Cmd: SendMessageCommand
    Cmd->>DB: Get Conversation
    Cmd->>Domain: CheckExpiry()
    
    alt Within 24h Window
        Domain-->>Cmd: Window valid
        Cmd->>WA: SendMessageAsync()
        WA-->>Cmd: WhatsApp message ID
        Cmd->>Domain: AddMessage()
        Cmd->>DB: Save
    else Outside 24h Window
        Domain-->>Cmd: Window expired
        Cmd->>WA: SendTemplateMessageAsync()
        WA-->>Cmd: Message ID (new window)
        Cmd->>Domain: AddMessage()
        Cmd->>DB: Save
    end
```

## Data Model

### Database Schema

See [Database Schema Documentation](DATABASE_SCHEMA.md) for detailed table structures and indexes.

Key tables:
- `whatsapp_accounts` - Business account connections
- `conversations` - Customer conversations
- `messages` - Individual messages (owned by conversation)
- `customers` - Customer profiles
- `automation_flows` - Automation flow definitions
- `flow_steps` - Flow step configurations
- `ai_agents` - AI agent configurations

### Important Indexes

```sql
-- High-traffic queries
CREATE INDEX idx_conversations_shop_status ON conversations(shop_id, status);
CREATE INDEX idx_messages_conversation_timestamp ON messages(conversation_id, timestamp DESC);
CREATE INDEX idx_customers_shop_waid ON customers(shop_id, wa_id);

-- Automation lookups
CREATE INDEX idx_flows_shop_active ON automation_flows(shop_id, is_active);
```

## Integration Events

The service publishes events to RabbitMQ for consumption by other services:

### Published Events

**WhatsAppMessageReceivedEvent**
- Emitted when: Customer sends message to shop
- Consumers: analytics-service (metrics), merchant-service (notifications)

**ConversationClosedEvent**
- Emitted when: Conversation is closed or expires
- Consumers: analytics-service (conversation duration), merchant-service

**AITokenUsageEvent**
- Emitted when: AI agent generates response
- Consumers: wallet-service (billing), analytics-service (cost tracking)

**CustomerOptInChangedEvent**
- Emitted when: Customer opt-in status changes
- Consumers: marketing services (permission updates)

## Security Considerations

### Webhook Signature Verification

All incoming webhooks from WhatsApp are verified using HMAC-SHA256:

```csharp
var signature = Request.Headers["X-Hub-Signature-256"];
var payload = await ReadBodyAsStringAsync();
var computedSignature = ComputeHmacSha256(payload, _appSecret);

if (!SecureCompare(signature, computedSignature))
    return Unauthorized();
```

### Access Token Encryption

WhatsApp access tokens are encrypted at rest using AES-256-GCM:

```csharp
// Stored in database as encrypted bytes
public string AccessToken 
{ 
    get => _encryption.Decrypt(_encryptedToken);
    private set => _encryptedToken = _encryption.Encrypt(value);
}
```

### Rate Limiting

Redis-based distributed rate limiter:
- 60 requests/minute per shop
- 1000 requests/minute per service instance

### GDPR Compliance

- Customer data can be exported via API
- Right to be forgotten: soft delete with data anonymization
- Opt-in consent tracking with timestamps
- Data retention policies enforced

## Performance Optimization

### Caching Strategy

**Redis Cache Usage:**
1. **Conversation Context** - Last 10 messages (TTL: 1 hour)
2. **Customer Profiles** - Frequently accessed customers (TTL: 30 minutes)
3. **Active Flows** - Automation flows (TTL: 5 minutes)
4. **Rate Limit Counters** - Per-shop request counts (TTL: 1 minute)

### Query Optimization

- Use Dapper for read-heavy queries (bypass EF Core)
- Implement pagination for all list endpoints
- Index on foreign keys and commonly filtered columns
- No N+1 queries (use `Include()` or projections)

### Background Processing

- Webhook processing returns 200 immediately
- Message sending queued to background job
- Flow execution runs asynchronously

## Monitoring & Observability

### Health Checks

```csharp
builder.Services.AddHealthChecks()
    .AddNpgSql(connectionString, name: "postgres")
    .AddRedis(redisConnection, name: "redis")
    .AddRabbitMQ(rabbitConnection, name: "rabbitmq")
    .AddCheck<WhatsAppApiHealthCheck>("whatsapp-api")
    .AddCheck<OpenAIHealthCheck>("openai-api");
```

### Metrics (Prometheus)

- `whatsapp_messages_received_total` - Counter
- `whatsapp_messages_sent_total` - Counter  
- `whatsapp_conversation_duration_seconds` - Histogram
- `whatsapp_ai_tokens_used_total` - Counter
- `whatsapp_webhook_processing_duration_ms` - Histogram

### Logging (Loki)

Structured logging with Serilog:
- Request/response correlation IDs
- Enriched with `ShopId`, `ConversationId`
- Sensitive data (tokens, messages) redacted

## Deployment Architecture

See [Deployment Guide](DEPLOYMENT.md) for Kubernetes manifests and scaling strategies.

**Scaling Triggers:**
- CPU > 70% → Scale up pods
- Webhook queue > 1000 messages → Scale up
- Memory > 80% → Investigate + scale

**Resource Limits:**
- Requests: 256Mi memory, 250m CPU
- Limits: 512Mi memory, 500m CPU

## References

- [WhatsApp Cloud API Docs](https://developers.facebook.com/docs/whatsapp/cloud-api)
- [OpenAPI Specification](../openapi.yaml)
- [Domain Model Details](DOMAIN_MODELS.md)
