# Architecture Documentation

**Service**: mkt-facebook-service-net  
**Last Updated**: 2026-01-18

## Overview

The Facebook Marketing Service provides a comprehensive solution for businesses to engage with customers on Facebook Messenger through automated chatbots and AI-powered conversations.

## System Architecture

### High-Level Architecture

```mermaid
graph TB
    subgraph "Facebook Messenger Platform"
        EndUser[End User]
        MessengerApp[Messenger App]
    end
    
    subgraph "GoodGo Platform"
        direction TB
        
        subgraph "mkt-facebook-service-net"
            Webhook[Webhooks Controller]
            API[REST API]
            
            subgraph "Application Layer"
                Commands[Commands]
                Queries[Queries]
                Handlers[MediatR Handlers]
            end
            
            subgraph "Domain Layer"
                Conversation[Conversation Aggregate]
                Customer[Customer Aggregate]
                ChatbotFlow[ChatbotFlow Aggregate]
                AIChatbot[AIChatbotConfig Aggregate]
            end
            
            subgraph "Infrastructure Layer"
                FBClient[FacebookMessengerClient]
                AIClient[OpenAI Client]
                Repos[Repositories]
                DbContext[EF Core DbContext]
            end
        end
        
        subgraph "Data & Messaging"
            PostgreSQL[(PostgreSQL)]
            Redis[(Redis)]
            RabbitMQ[RabbitMQ]
        end
    end
    
    subgraph "External Services"
        FacebookAPI[Facebook Graph API]
        OpenAI[OpenAI / Azure OpenAI]
    end
    
    EndUser -->|Send Message| MessengerApp
    MessengerApp -->|Webhook Event| Webhook
    Webhook -->|Dispatch Command| Commands
    Commands --> Handlers
    Handlers --> Domain Layer
    Handlers --> Repos
    Repos --> DbContext
    DbContext --> PostgreSQL
    Handlers -->|Cache| Redis
    Handlers -->|Publish Events| RabbitMQ
    
    API -->|Commands/Queries| Handlers
    
    FBClient -->|HTTP| FacebookAPI
    AIClient -->|HTTP| OpenAI
    
    Handlers -->|Send Message| FBClient
    Handlers -->|AI Completion| AIClient
    
    style EndUser fill:#2C3E50,color:#ECF0F1,stroke:#34495E,stroke-width:2px
    style MessengerApp fill:#3498DB,color:#ECF0F1,stroke:#2980B9,stroke-width:2px
    style Webhook fill:#3498DB,color:#ECF0F1,stroke:#2980B9,stroke-width:3px
    style API fill:#3498DB,color:#ECF0F1,stroke:#2980B9,stroke-width:3px
    style Commands fill:#8E44AD,color:#ECF0F1,stroke:#7D3C98,stroke-width:2px
    style Queries fill:#8E44AD,color:#ECF0F1,stroke:#7D3C98,stroke-width:2px
    style Handlers fill:#8E44AD,color:#ECF0F1,stroke:#7D3C98,stroke-width:2px
    style Conversation fill:#E67E22,color:#ECF0F1,stroke:#D35400,stroke-width:2px
    style Customer fill:#E67E22,color:#ECF0F1,stroke:#D35400,stroke-width:2px
    style ChatbotFlow fill:#E67E22,color:#ECF0F1,stroke:#D35400,stroke-width:2px
    style AIChatbot fill:#E67E22,color:#ECF0F1,stroke:#D35400,stroke-width:2px
    style FBClient fill:#8E44AD,color:#ECF0F1,stroke:#7D3C98,stroke-width:2px
    style AIClient fill:#8E44AD,color:#ECF0F1,stroke:#7D3C98,stroke-width:2px
    style Repos fill:#8E44AD,color:#ECF0F1,stroke:#7D3C98,stroke-width:2px
    style DbContext fill:#8E44AD,color:#ECF0F1,stroke:#7D3C98,stroke-width:2px
    style PostgreSQL fill:#34495E,color:#ECF0F1,stroke:#2C3E50,stroke-width:2px
    style Redis fill:#34495E,color:#ECF0F1,stroke:#2C3E50,stroke-width:2px
    style RabbitMQ fill:#34495E,color:#ECF0F1,stroke:#2C3E50,stroke-width:2px
    style FacebookAPI fill:#7F8C8D,color:#ECF0F1,stroke:#5D6D7E,stroke-width:2px
    style OpenAI fill:#7F8C8D,color:#ECF0F1,stroke:#5D6D7E,stroke-width:2px
```

## Domain Model

### Aggregates

#### 1. Conversation Aggregate

```mermaid
classDiagram
    class Conversation {
        +Guid Id
        +Guid CustomerId
        +string PageId
        +ConversationStatus Status
        +Channel Channel
        +DateTime LastMessageAt
        +DateTime CreatedAt
        -List~Message~ _messages
        +IReadOnlyCollection~Message~ Messages
        
        +AddMessage(Message) void
        +MarkAsRead() void
        +Assign(string agentId) void
        +Close() void
    }
    
    class Message {
        +Guid Id
        +string SenderId
        +string Content
        +MessageType Type
        +MessageDirection Direction
        +DateTime SentAt
        +Dictionary Metadata
    }
    
    class ConversationStatus {
        <<enumeration>>
        Active
        Closed
        Archived
    }
    
    class MessageDirection {
        <<enumeration>>
        Incoming
        Outgoing
    }
    
    Conversation "1" *-- "many" Message
    Conversation --> ConversationStatus
    Message --> MessageDirection
    
    style Conversation fill:#8E44AD,color:#ECF0F1,stroke:#7D3C98,stroke-width:2px
    style Message fill:#3498DB,color:#ECF0F1,stroke:#2980B9,stroke-width:2px
    style ConversationStatus fill:#E67E22,color:#ECF0F1,stroke:#D35400,stroke-width:2px
    style MessageDirection fill:#E67E22,color:#ECF0F1,stroke:#D35400,stroke-width:2px
```

The Conversation aggregate manages the lifecycle of a customer conversation, including all messages exchanged.

**Business Rules**:
- Can only add messages to Active conversations
- A conversation must have at least 1 message
- Messages cannot be deleted, only archive conversation

#### 2. Customer Aggregate

```mermaid
classDiagram
    class Customer {
        +Guid Id
        +string FacebookUserId
        +string Name
        +string Email
        +string Phone
        +string ProfilePicUrl
        +string Locale
        +string Timezone
        +List~string~ Tags
        +Dictionary~string,string~ CustomFields
        +DateTime FirstSeenAt
        +DateTime LastInteractionAt
        
        +UpdateProfile(CustomerProfile) void
        +AddTag(string tag) void
        +RemoveTag(string tag) void
        +SetCustomField(string key, string value) void
    }
    
    style Customer fill:#8E44AD,color:#ECF0F1,stroke:#7D3C98,stroke-width:2px
```

The Customer aggregate represents a Facebook user who interacts with the chatbot.

**Business Rules**:
- `FacebookUserId` is unique identifier
- Tags must be valid non-empty strings
- Custom fields limited to 50 fields per customer
- Profile synced from Facebook Messenger Platform

#### 3. ChatbotFlow Aggregate (Automation)

```mermaid
classDiagram
    class ChatbotFlow {
        +Guid Id
        +string Name
        +Guid ShopId
        +FlowTriggerType TriggerType
        +string TriggerValue
        +bool IsActive
        -List~FlowNode~ _nodes
        +IReadOnlyCollection~FlowNode~ Nodes
        
        +AddNode(FlowNode) void
        +ConnectNodes(Guid from, Guid to) void
        +Activate() void
        +Deactivate() void
    }
    
    class FlowNode {
        +Guid Id
        +NodeType Type
        +string Content
        +Dictionary Config
        +List~Guid~ NextNodeIds
    }
    
    class NodeType {
        <<enumeration>>
        Start
        Message
        Question
        Condition
        Action
        End
    }
    
    ChatbotFlow "1" *-- "many" FlowNode
    FlowNode --> NodeType
    
    style ChatbotFlow fill:#8E44AD,color:#ECF0F1,stroke:#7D3C98,stroke-width:2px
    style FlowNode fill:#3498DB,color:#ECF0F1,stroke:#2980B9,stroke-width:2px
    style NodeType fill:#E67E22,color:#ECF0F1,stroke:#D35400,stroke-width:2px
```

The ChatbotFlow aggregate defines automation rules and conversation flows.

**Business Rules**:
- Each flow must have exactly 1 Start node
- Each flow must have at least 1 End node
- No circular references (infinite loops)
- `TriggerValue` must be unique within ShopId

#### 4. AIChatbotConfig Aggregate

```mermaid
classDiagram
    class AIChatbotConfig {
        +Guid Id
        +Guid ShopId
        +AIProvider Provider
        +string Model
        +string SystemPrompt
        +float Temperature
        +int MaxTokens
        +bool IsEnabled
        +DateTime CreatedAt
        +DateTime UpdatedAt
        
        +UpdateConfig(ConfigUpdate) void
        +Enable() void
        +Disable() void
    }
    
    class AIProvider {
        <<enumeration>>
        OpenAI
        AzureOpenAI
    }
    
    AIChatbotConfig --> AIProvider
    
    style AIChatbotConfig fill:#8E44AD,color:#ECF0F1,stroke:#7D3C98,stroke-width:2px
    style AIProvider fill:#E67E22,color:#ECF0F1,stroke:#D35400,stroke-width:2px
```

The AIChatbotConfig aggregate configures AI-powered chatbot behavior.

**Business Rules**:
- Temperature must be in range [0.0, 2.0]
- MaxTokens must be > 0 and <= 4096
- SystemPrompt cannot be empty
- Only 1 active config per ShopId

## Message Processing Flow

```mermaid
sequenceDiagram
    participant User as End User
    participant FB as Facebook Messenger
    participant Webhook as Webhooks Controller
    participant Handler as ProcessIncomingMessage Handler
    participant Domain as Domain Layer
    participant Strategy as Response Strategy
    participant AI as OpenAI Client
    participant FBClient as Facebook Client
    participant DB as PostgreSQL
    
    User->>FB: Send message
    FB->>Webhook: POST /webhooks/facebook
    Webhook->>Webhook: Verify signature
    Webhook-->>FB: 200 OK (immediately)
    
    Webhook->>Handler: Dispatch ProcessIncomingMessageCommand
    
    Handler->>DB: Get or Create Customer
    Handler->>DB: Get or Create Conversation
    Handler->>Domain: conversation.AddMessage(incoming)
    Handler->>DB: Save changes
    
    Handler->>Strategy: DetermineStrategy(conversation)
    
    alt AI Chatbot Enabled
        Strategy-->>Handler: Use AI
        Handler->>AI: GetChatCompletion(context)
        AI-->>Handler: AI Response
    else Automation Flow
        Strategy-->>Handler: Use Automation
        Handler->>DB: Find matching FlowNode
        Handler->>Handler: Execute flow logic
    end
    
    Handler->>FBClient: SendMessage(response)
    FBClient->>FB: POST /messages
    FB-->>FBClient: Success
    
    Handler->>Domain: conversation.AddMessage(outgoing)
    Handler->>DB: Save changes
```

**Key Steps**:

1. **Webhook Reception**: Facebook sends event to service
2. **Signature Verification**: Verify Facebook request signature
3. **Customer & Conversation Management**: Get or create
4. **Strategy Selection**: Automation vs AI
5. **Response Generation**: Based on strategy
6. **Send Message**: Via Facebook Messenger API
7. **Persistence**: Save message history

## Integration Patterns

### Facebook Messenger Platform Integration

The service integrates with Facebook Messenger Platform via:
- **Webhooks**: Receive messages, postbacks, read receipts
- **Send API**: Send messages, quick replies, templates
- **User Profile API**: Fetch user information

### OpenAI Integration

AI chatbot uses OpenAI Chat Completions API with:
- **Streaming**: Real-time response generation
- **Context Management**: Multi-turn conversations
- **Retry Logic**: Polly resilience policies
- **Cost Tracking**: Monitor token usage

## Data Model

### Database Schema

```mermaid
erDiagram
    CONVERSATIONS ||--o{ MESSAGES : contains
    CUSTOMERS ||--o{ CONVERSATIONS : has
    CHATBOT_FLOWS ||--o{ FLOW_NODES : contains
    AI_CHATBOT_CONFIGS ||--|| SHOPS : belongs_to
    
    CONVERSATIONS {
        uuid id PK
        uuid customer_id FK
        string page_id
        string status
        string channel
        timestamp last_message_at
        timestamp created_at
    }
    
    MESSAGES {
        uuid id PK
        uuid conversation_id FK
        string sender_id
        text content
        string message_type
        string direction
        jsonb metadata
        timestamp sent_at
    }
    
    CUSTOMERS {
        uuid id PK
        string facebook_user_id UK
        string name
        string email
        string profile_pic_url
        string locale
        string timezone
        text[] tags
        jsonb custom_fields
        timestamp first_seen_at
        timestamp last_interaction_at
    }
    
    CHATBOT_FLOWS {
        uuid id PK
        uuid shop_id FK
        string name
        string trigger_type
        string trigger_value UK
        boolean is_active
        timestamp created_at
    }
    
    FLOW_NODES {
        uuid id PK
        uuid flow_id FK
        string node_type
        text content
        jsonb config
        uuid[] next_node_ids
        int order_index
    }
    
    AI_CHATBOT_CONFIGS {
        uuid id PK
        uuid shop_id FK UK
        string provider
        string model
        text system_prompt
        float temperature
        int max_tokens
        boolean is_enabled
        timestamp updated_at
    }
```

### Indexes

**Performance Optimization**:
- `idx_conversations_customer_id` - Fast lookup by customer
- `idx_conversations_page_id_status` - Filter active conversations by page
- `idx_messages_conversation_id_sent_at` - Sort messages chronologically
- `idx_customers_facebook_user_id` - Unique lookup
- `idx_chatbot_flows_shop_id_trigger` - Match triggers
- `idx_ai_configs_shop_id` - One config per shop

## Security

### Facebook Webhook Verification

All incoming webhooks must:
1. Include `X-Hub-Signature-256` header
2. Signature verified using App Secret
3. Invalid signatures rejected with 403

### API Authentication

REST API endpoints require:
- JWT Bearer token from IAM service
- Role-based authorization (Admin, Agent, Viewer)

### Data Privacy

- **GDPR Compliance**: Customer data export and deletion
- **Data Encryption**: At rest (PostgreSQL) and in transit (HTTPS)
- **PII Protection**: Customer info not logged to files

## Scalability Considerations

### Horizontal Scaling

Service supports horizontal scaling with:
- **Stateless API**: No server-side sessions
- **Redis Cache**: Shared cache across instances
- **RabbitMQ**: Distributed message queue
- **Load Balancer**: Traefik distributes traffic

### Rate Limiting

Facebook Messenger API limits:
- **100 messages/second** per app
- **Burst tolerance**: Queue messages during spikes
- **Retry with exponential backoff**: For 429 responses

## Monitoring & Observability

### Key Metrics

| Metric | Description | Target |
|--------|-------------|--------|
| **Webhook Latency** | Time to return 200 to Facebook | < 500ms |
| **Message Processing Time** | Time to generate & send response | < 2s |
| **AI Response Time** | OpenAI API latency | < 5s |
| **Message Success Rate** | % messages sent successfully | > 99% |
| **Conversation Active Count** | Number of active conversations | - |
| **AI Cost per Conversation** | Average OpenAI cost | Monitor |

### Health Checks

- **Database**: PostgreSQL connection pooling
- **Redis**: Cache availability
- **RabbitMQ**: Message broker connection
- **Facebook API**: API availability check
- **OpenAI API**: Provider availability

## Design Decisions

### Why CQRS?

Separate read and write operations for:
- **Optimized Queries**: Use Dapper for fast reads
- **Complex Commands**: Use EF Core with Domain Model
- **Scalability**: Scale reads and writes independently

### Why DDD?

Complex business logic requires:
- **Rich Domain Model**: Conversation, Customer aggregates
- **Encapsulation**: Business rules in domain
- **Domain Events**: Decouple side effects

## Resources

- [API Documentation](./API.md)
- [Facebook Setup Guide](./FACEBOOK_SETUP.md)
- [AI Chatbot Guide](./AI_CHATBOT.md)
- [Domain-Driven Design Skill](../../../.agent/skills/domain-driven-design/SKILL.md)
- [CQRS MediatR Skill](../../../.agent/skills/cqrs-mediatr/SKILL.md)
