# MKT Zalo Service - Solution Architecture

## Table of Contents

1. [Business Context](#business-context)
2. [System Architecture](#system-architecture)
3. [Domain Model](#domain-model)
4. [CQRS Commands & Queries](#cqrs-commands--queries)
5. [Integration Patterns](#integration-patterns)
6. [Data Flow](#data-flow)
7. [Security & Authentication](#security--authentication)
8. [Performance & Scalability](#performance--scalability)
9. [Monitoring & Observability](#monitoring--observability)

---

## Business Context

### Problem Statement

Businesses need to engage with customers on Zalo, Vietnam's leading messaging platform with 80M+ users. This requires:
- Automated responses for common inquiries (24/7 availability)
- AI-powered conversations for complex customer needs
- Centralized customer data and interaction history
- Scalable messaging infrastructure for campaigns

### Business Goals

1. **Customer Engagement**: 90% response rate within 1 minute
2. **Automation**: 70% of inquiries handled without human intervention
3. **Personalization**: Context-aware responses based on customer history
4. **Scalability**: Support 10,000+ concurrent conversations

---

## System Architecture

### High-Level Architecture

```
┌─────────────────────────────────────────────────────────┐
│                    Zalo Official Account                 │
│               (Customer sends messages via Zalo)          │
└────────────────────┬────────────────────────────────────┘
                     │ Webhook Events
                     ▼
┌─────────────────────────────────────────────────────────┐
│                  mkt-zalo-service-net                    │
│                                                          │
│  ┌──────────────────────────────────────────────────┐  │
│  │         Webhook Handler (API Layer)              │  │
│  │  • Verify signature                              │  │
│  │  • Parse events (message, follow, buttons)       │  │
│  │  • Return 200 quickly                            │  │
│  └───────────────┬──────────────────────────────────┘  │
│                  │                                      │
│                  ▼                                      │
│  ┌──────────────────────────────────────────────────┐  │
│  │         Message Processing Engine                │  │
│  │  ┌────────────────┐  ┌────────────────┐         │  │
│  │  │ Rule Engine    │  │   AI Engine    │         │  │
│  │  │ (Automation)   │  │  (LLM Based)   │         │  │
│  │  └────────────────┘  └────────────────┘         │  │
│  └───────────────┬──────────────────────────────────┘  │
│                  │                                      │
│                  ▼                                      │
│  ┌──────────────────────────────────────────────────┐  │
│  │         Domain Layer                             │  │
│  │  • Conversation Aggregate                        │  │
│  │  • ZaloCustomer Aggregate                        │  │
│  │  • ChatbotRule Entity                            │  │
│  │  • MessageTemplate Entity                        │  │
│  └──────────────────────────────────────────────────┘  │
│                                                          │
│  ┌──────────────────────────────────────────────────┐  │
│  │         Integration Layer                        │  │
│  │  • Zalo OA API Client (Send messages)            │  │
│  │  • LLM Provider (OpenAI, Vertex AI)              │  │
│  └──────────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────────┘
                     │
                     ▼
              ┌──────────────┐
              │  PostgreSQL  │
              │  (Customer,  │
              │ Conversation,│
              │  Templates)  │
              └──────────────┘
```

### Clean Architecture Layers

```
┌────────────────────────────────────────────────────────────┐
│                        API Layer                            │
│  Controllers → MediatR → Commands/Queries                  │
│  • WebhooksController (public, no auth)                    │
│  • ConversationsController (authenticated)                 │
│  • CustomersController (CRM management)                    │
│  • ChatbotRulesController (automation config)              │
│  • Admin/* (analytics, broadcast)                          │
└────────────────────────┬───────────────────────────────────┘
                         │
┌────────────────────────▼───────────────────────────────────┐
│                    Application Layer                        │
│  Commands: ProcessWebhookCommand, SendMessageCommand       │
│  Queries: GetConversationHistoryQuery, GetCustomerQuery    │
│  Handlers: ProcessWebhookCommandHandler (routes to engines)│
│  Behaviors: ValidationBehavior, LoggingBehavior            │
└────────────────────────┬───────────────────────────────────┘
                         │
┌────────────────────────▼───────────────────────────────────┐
│                     Domain Layer                            │
│  Aggregates:                                                │
│  • Conversation (messages, status, context)                │
│  • ZaloCustomer (profile, tags, segment)                   │
│  • ChatbotRule (conditions, actions)                        │
│  • MessageTemplate (ZNS templates)                          │
│                                                              │
│  Business Rules:                                            │
│  • Conversation.AddMessage() - validate message type        │
│  • ZaloCustomer.UpdateProfile() - enforce data quality     │
│  • ChatbotRule.Evaluate() - match conditions               │
└────────────────────────┬───────────────────────────────────┘
                         │
┌────────────────────────▼───────────────────────────────────┐
│                 Infrastructure Layer                        │
│  • EF Core DbContext  (persistence)                        │
│  • Repositories (ConversationRepository, CustomerRepository)│
│  • ZaloOfficialAccountClient (HTTP client with Polly)     │
│  • RuleBasedChatbotEngine (keyword matching, regex)       │
│  • AiChatbotEngine (LLM integration)                       │
│  • Redis Caching (conversation context)                    │
└────────────────────────────────────────────────────────────┘
```

---

## Domain Model

### Aggregates Overview

**4 Aggregate Roots:**

1. **Conversation** - Manages conversation lifecycle and messages
2. **ZaloCustomer** - Customer profiles, tags, and segmentation
3. **ChatbotRule** - Automation rules (keyword/regex/intent)
4. **MessageTemplate** - ZNS template management

See [DOMAIN_MODELS.md](./DOMAIN_MODELS.md) for detailed implementation.

---

## CQRS Commands & Queries

### Commands (Write Operations)

```csharp
// Process incoming webhook from Zalo
public record ProcessWebhookCommand(
    string EventName,
    string ZaloUserId,
    string MessageText,
    string MessageType,
    DateTime Timestamp) : IRequest<ProcessWebhookResult>;

// Send message to Zalo customer
public record SendMessageCommand(
    Guid ConversationId,
    string ZaloUserId,
    string MessageText,
    MessageType Type = MessageType.Text) : IRequest<SendMessageResult>;

// Create chatbot automation rule
public record CreateChatbotRuleCommand(
    string Name,
    RuleType Type,
    List<RuleConditionDto> Conditions,
    RuleActionDto Action,
    int Priority) : IRequest<ChatbotRuleResult>;
```

### Queries (Read Operations)

```csharp
// Get conversation history
public record GetConversationHistoryQuery(
    Guid ConversationId,
    int Skip = 0,
    int Take = 50) : IRequest<ConversationHistoryResult>;

// Get customer details with interaction summary
public record GetCustomerQuery(
    Guid CustomerId) : IRequest<CustomerDetailDto>;

// Search conversations
public record SearchConversationsQuery(
    string? ZaloUserId = null,
    ConversationStatus? Status = null,
    DateTime? FromDate = null,
    DateTime? ToDate = null,
    int Skip = 0,
    int Take = 20) : IRequest<PagedResult<ConversationSummaryDto>>;
```

---

## Integration Patterns

### 1. Zalo Official Account Integration

**Webhook Processing Flow:**

```
Zalo → POST /webhooks → Verify signature → Parse event → Queue to RabbitMQ → Return 200
                                                                ↓
      RabbitMQ Consumer → Load customer → Route to Engine → Generate response → Send via Zalo API
```

**Critical Requirements:**
- Must return 200 within 2 seconds
- Signature verification (HMAC SHA256)
- Async processing via message queue

### 2. Rule-Based Chatbot Engine

```csharp
public class RuleBasedChatbotEngine : IChatbotEngine
{
    public async Task<ChatbotResponse> ProcessAsync(
        string userMessage,
        ConversationContext context,
        CancellationToken ct)
    {
        var rules = await _ruleRepository.GetActiveRulesOrderedByPriorityAsync(ct);
        
        foreach (var rule in rules)
        {
            if (rule.Evaluate(userMessage))
            {
                return new ChatbotResponse(
                    ResponseText: rule.Action.ResponseText,
                    MatchedRuleId: rule.Id,
                    Confidence: 1.0);
            }
        }
        
        return ChatbotResponse.NoMatch;
    }
}
```

### 3. AI Chatbot Engine (LLM)

```csharp
public class AiChatbotEngine : IChatbotEngine
{
    public async Task<ChatbotResponse> ProcessAsync(
        string userMessage,
        ConversationContext context,
        CancellationToken ct)
    {
        // Load conversation history for context
        var conversationHistory = await _cache.GetOrSetAsync(
            $"conversation:{context.ConversationId}",
            async () => await _conversationRepository.GetMessagesAsync(
                context.ConversationId, take: 10, ct),
            TimeSpan.FromMinutes(30),
            ct);
            
        // Build LLM prompt with context
        var prompt = BuildPrompt(userMessage, conversationHistory, context.CustomerProfile);
        
        // Call LLM provider
        var llmResponse = await _llmService.GenerateResponseAsync(prompt, ct);
        
        return new ChatbotResponse(
            ResponseText: llmResponse.Text,
            Confidence: llmResponse.Confidence);
    }
}
```

---

## Data Flow

### Webhook Processing Flow

```
1. Zalo sends webhook → WebhooksController
2. Verify signature (HMAC SHA256)
3. Parse event (user_send_text, follow, etc.)
4. Publish to RabbitMQ
5. Return 200 to Zalo (< 2s)

6. Consumer processes event
7. Load or create ZaloCustomer
8. Load or create Conversation
9. Route to Rule Engine or AI Engine
10. Generate response
11. Save to database
12. Send via Zalo API
13. Update Redis cache
```

---

## Security & Authentication

### 1. Webhook Signature Verification

```csharp
public class ZaloWebhookSignatureValidator
{
    private readonly string _webhookSecret;
    
    public bool ValidateSignature(string body, string signature)
    {
        var computedSignature = ComputeHmac256(body, _webhookSecret);
        return signature.Equals(computedSignature, StringComparison.OrdinalIgnoreCase);
    }
    
    private string ComputeHmac256(string message, string secret)
    {
        var encoding = new UTF8Encoding();
        var keyBytes = encoding.GetBytes(secret);
        using var hmac = new HMACSHA256(keyBytes);
        var hashBytes = hmac.ComputeHash(encoding.GetBytes(message));
        return BitConverter.ToString(hashBytes).Replace("-", "").ToLower();
    }
}
```

### 2. API Authentication

- **Public APIs** (Webhooks): Signature verification only
- **Customer APIs**: JWT Bearer tokens from IAM service
- **Admin APIs**: JWT + Admin role claim

---

## Performance & Scalability

### Performance Targets

| Metric | Target | Strategy |
|--------|--------|----------|
| Webhook response time | < 2s | Queue immediately, return 200 |
| Message processing time | < 5s | Async processing via RabbitMQ |
| AI response generation | < 3s | LLM caching, prompt optimization |
| Database query time | < 100ms | Indexed queries, read replicas |
| Concurrent conversations | 10,000+ | Stateless processing, Redis cache |

### Caching Strategy

```csharp
// Cache conversation context in Redis
Key: "conversation:{conversationId}"
TTL: 30 minutes
Data: Last 10 messages, customer profile, active rules

// Cache chatbot rules
Key: "chatbot:rules:active"
TTL: 5 minutes
Data: All active rules ordered by priority
```

---

## Monitoring & Observability

### Key Metrics

```
# Webhook metrics
zalo_webhook_events_total{event_type="user_send_text"} 
zalo_webhook_processing_duration_seconds

# Chatbot metrics
zalo_messages_processed_total{engine="rule_based|ai"}
zalo_chatbot_rule_matches_total{rule_id="..."}
zalo_ai_llm_latency_seconds

# Business metrics
zalo_active_conversations_total
zalo_customer_satisfaction_score
zalo_automation_rate
```

### Logging Strategy

```
INFO:  User message received, rule matched
WARN:  No rule matched, fallback to AI
ERROR: Failed to send Zalo message, retrying
```

---

## Deployment Considerations

### Environment Configuration

```yaml
# Production
- Webhook URL: https://api.goodgo.vn/api/v1/zalo/webhooks
- Database: Neon PostgreSQL (multi-region)
- Redis: ElastiCache cluster
- LLM: Vertex AI (gcp-asia-southeast1)

# Staging
- Webhook URL: https://staging-api.goodgo.vn/api/v1/zalo/webhooks
- Zalo OA: Test account
```

### Disaster Recovery

- **Database backups**: Daily snapshots, 30-day retention
- **Message queue**: Durable queues with replication
- **Webhook replay**: Store raw webhook events for 7 days

---

## Future Enhancements

1. **Multi-language support** - Vietnamese + English chatbot
2. **Voice message processing** - Speech-to-text integration
3. **Sentiment analysis** - Detect customer emotions
4. **A/B testing** - Test different chatbot responses
5. **Zalo Mini App integration** - Deep linking to mini apps

---

**Document Version**: 1.0  
**Last Updated**: 2026-01-18  
**Author**: GoodGo Platform Team
