# X/Twitter Marketing Service - Architecture Documentation

## Table of Contents

1. [Overview](#overview)
2. [System Architecture](#system-architecture)
3. [Domain Model](#domain-model)
4. [Component Design](#component-design)
5. [Data Architecture](#data-architecture)
6. [Integration Architecture](#integration-architecture)
7. [Security Architecture](#security-architecture)
8. [Deployment Architecture](#deployment-architecture)

---

## Overview

### Service Purpose

The X/Twitter Marketing Service (`mkt-x-service-net`) is a comprehensive social media marketing platform built on .NET 8, providing three core capabilities:

1. **CHATBOT Automation Messenger** - Template-based automated messaging with workflow orchestration
2. **CHATBOT AI Messenger** - AI-powered conversational interface using OpenAI integration
3. **Customer Management** - Complete CRM for Twitter contacts with segmentation and analytics

### Key Features

- ✅ Multi-account Twitter integration with OAuth 1.0a
- ✅ Visual workflow designer for message automation
- ✅ AI-powered natural language conversations
- ✅ Advanced customer segmentation
- ✅ Campaign management with A/B testing
- ✅ Real-time analytics and reporting
- ✅ Webhook-based event processing
- ✅ Rate limiting and quota management

---

## System Architecture

### High-Level Architecture

```
┌─────────────────────────────────────────────────────────┐
│                    Load Balancer (Traefik)              │
└─────────────┬───────────────────────────┬───────────────┘
              │                           │
    ┌─────────▼─────────┐       ┌────────▼────────┐
    │   API Instance 1   │       │  API Instance 2  │
    │  (Web API + Jobs)  │       │ (Web API + Jobs) │
    └─────────┬─────────┘       └────────┬────────┘
              │                           │
              └──────────┬────────────────┘
                         │
        ┌────────────────┼────────────────┐
        │                │                │
  ┌─────▼─────┐    ┌────▼────┐    ┌─────▼─────┐
  │PostgreSQL │    │  Redis   │    │ RabbitMQ  │
  │(Primary)  │    │ (Cache)  │    │(Event Bus)│
  └───────────┘    └──────────┘    └───────────┘
        │
  ┌─────▼─────────────┐
  │ External Services │
  │ - Twitter API     │
  │ - OpenAI API      │
  └───────────────────┘
```

### Clean Architecture Layers

```
┌──────────────────────────────────────────────┐
│         API Layer (Presentation)             │
│  - Controllers                               │
│  - Middleware (Auth, Exception, Logging)     │
│  - Swagger/OpenAPI                           │
└──────────────────┬───────────────────────────┘
                   │
┌──────────────────▼───────────────────────────┐
│      Application Layer (Use Cases)           │
│  - Commands (MediatR)                        │
│  - Queries (MediatR)                         │
│  - DTOs                                      │
│  - Validators (FluentValidation)             │
│  - Pipeline Behaviors                        │
└──────────────────┬───────────────────────────┘
                   │
┌──────────────────▼───────────────────────────┐
│         Domain Layer (Business Logic)        │
│  - Aggregates (TwitterAccount, Contact...)   │
│  - Entities                                  │
│  - Value Objects                             │
│  - Domain Events                             │
│  - Domain Services                           │
└──────────────────┬───────────────────────────┘
                   │
┌──────────────────▼───────────────────────────┐
│    Infrastructure Layer (External Concerns)  │
│  - EF Core DbContext                         │
│  - Repositories                              │
│  - External API Clients (Twitter, OpenAI)    │
│  - Background Jobs                           │
│  - Event Bus Integration                     │
└──────────────────────────────────────────────┘
```

---

## Domain Model

### Aggregate Roots

#### 1. TwitterAccount Aggregate

**Purpose**: Manages connected Twitter accounts with OAuth credentials

```csharp
public class TwitterAccount : Entity, IAggregateRoot
{
    public Guid MerchantId { get; private set; }
    public string TwitterUserId { get; private set; }
    public string Username { get; private set; }
    public TwitterAccountStatus Status { get; private set; }
    
    public void ConnectAccount(string oauthToken, string oauthSecret);
    public void Disconnect();
    public void UpdateCredentials(string token, string secret);
}
```

**Business Rules**:
- One merchant can have multiple Twitter accounts
- OAuth tokens must be encrypted at rest
- Account must pass Twitter verification before activation

#### 2. Contact Aggregate

**Purpose**: Represents Twitter users who interact with merchant accounts

```csharp
public class Contact : Entity, IAggregateRoot
{
    public Guid AccountId { get; private set; }
    public string TwitterUserId { get; private set; }
    public List<ContactTag> Tags { get; private set; }
    public Dictionary<string, object> Attributes { get; private set; }
    
    public void AddTag(string tagName);
    public void RemoveTag(string tagName);
    public void UpdateAttribute(string key, object value);
}
```

**Business Rules**:
- Each Twitter user is unique per merchant account
- Tags must be unique per contact
- Custom attributes support flexible data types (string, number, boolean, date)

#### 3. Conversation Aggregate

**Purpose**: Manages message threads between contacts and merchants

```csharp
public class Conversation : Entity, IAggregateRoot
{
    public Guid ContactId { get; private set; }
    public Guid AccountId { get; private set; }
    public ConversationStatus Status { get; private set; }
    public List<Message> Messages { get; private set; }
    
    public void AddMessage(Message message);
    public void Close();
    public void AssignToAgent(Guid userId);
}
```

**Business Rules**:
- Conversations auto-close after 24 hours of inactivity
- Messages cannot be deleted, only archived
- Bot messages are clearly marked

#### 4. Template Aggregate

**Purpose**: Reusable message templates with variable substitution

```csharp
public class Template : Entity, IAggregateRoot
{
    public Guid MerchantId { get; private set; }
    public string Name { get; private set; }
    public string Content { get; private set; }
    public List<string> Variables { get; private set; }
    
    public string Render(Dictionary<string, object> values);
    public void Validate();
}
```

**Business Rules**:
- Template content must not exceed Twitter DM limits (10,000 chars)
- Variables use {{variable_name}} syntax
- All declared variables must be provided during rendering

#### 5. Campaign Aggregate

**Purpose**: Orchestrates bulk messaging campaigns with scheduling

```csharp
public class Campaign : Entity, IAggregateRoot
{
    public Guid MerchantId { get; private set; }
    public Guid TemplateId { get; private set; }
    public List<Guid> SegmentIds { get; private set; }
    public Schedule Schedule { get; private set; }
    public CampaignMetrics Metrics { get; private set; }
    
    public void Start();
    public void Pause();
    public void Resume();
    public void Complete();
}
```

**Business Rules**:
- Campaign cannot start without at least one segment
- Respects Twitter rate limits (500 DMs/24 hours)
- Cannot modify campaign after it has started
- Scheduled campaigns auto-execute at specified time

#### 6. Segment Aggregate

**Purpose**: Dynamic customer segmentation with condition-based filtering

```csharp
public class Segment : Entity, IAggregateRoot
{
    public Guid MerchantId { get; private set; }
    public string Name { get; private set; }
    public List<SegmentCondition> Conditions { get; private set; }
    public int ContactCount { get; private set; }
    
    public void AddCondition(SegmentCondition condition);
    public void RemoveCondition(Guid conditionId);
    public List<Contact> Evaluate();
}
```

**Business Rules**:
- Conditions are evaluated with AND logic
- Contact count is cached and refreshed periodically
- Supports filters: tags, attributes, engagement level, date ranges

#### 7. AutomationFlow Aggregate

**Purpose**: Visual workflow automation with triggers and actions

```csharp
public class AutomationFlow : Entity, IAggregateRoot
{
    public Guid MerchantId { get; private set; }
    public FlowStatus Status { get; private set; }
    public List<FlowNode> Nodes { get; private set; }
    public List<FlowConnection> Connections { get; private set; }
    public FlowTrigger Trigger { get; private set; }
    
    public void AddNode(FlowNode node);
    public void Connect(Guid fromNodeId, Guid toNodeId);
    public void Activate();
    public void Deactivate();
}
```

**Business Rules**:
- Flows must have exactly one trigger node
- No circular connections allowed
- Flow must be validated before activation
- Deactivating a flow stops all running executions

#### 8. AIConversationSession Aggregate

**Purpose**: Maintains AI conversation context and state

```csharp
public class AIConversationSession : Entity, IAggregateRoot
{
    public Guid ConversationId { get; private set; }
    public List<ContextItem> Context { get; private set; }
    public string CurrentIntent { get; private set; }
    public Dictionary<string, object> Slots { get; private set; }
    
    public void UpdateContext(ContextItem item);
    public void ClearContext();
    public void DetectIntent(string message);
}
```

**Business Rules**:
- Context limited to last 10 messages for performance
- Session expires after 30 minutes of inactivity
- Auto-escalates to human if confidence < 0.6

### Value Objects

```csharp
// Twitter user information
public record TwitterUserInfo(
    string TwitterUserId,
    string Username,
    string DisplayName,
    string ProfileImageUrl);

// Campaign scheduling
public record Schedule(
    DateTime? StartAt,
    DateTime? EndAt,
    RecurrencePattern? Recurrence);

// Campaign metrics
public record CampaignMetrics(
    int TotalSent,
    int Delivered,
    int Opened,
    int Clicked,
    int Replied,
    int Failed);

// Automation trigger
public record FlowTrigger(
    TriggerType Type,
    Dictionary<string, object> Config);
```

### Domain Events

```csharp
// Account Events
public record TwitterAccountConnectedEvent(Guid AccountId, Guid MerchantId);
public record TwitterAccountDisconnectedEvent(Guid AccountId);

// Contact Events
public record ContactCreatedEvent(Guid ContactId, string TwitterUserId);
public record ContactTaggedEvent(Guid ContactId, string TagName);

// Conversation Events
public record ConversationStartedEvent(Guid ConversationId, Guid ContactId);
public record MessageReceivedEvent(Guid MessageId, string Content);
public record MessageSentEvent(Guid MessageId, bool IsFromBot);

// Campaign Events
public record CampaignStartedEvent(Guid CampaignId, int TargetCount);
public record CampaignCompletedEvent(Guid CampaignId, CampaignMetrics Metrics);

// AI Events
public record IntentDetectedEvent(Guid SessionId, string Intent, double Confidence);
public record AIEscalationRequestedEvent(Guid SessionId, string Reason);
```

---

## Component Design

### Application Layer Components

#### Commands (Write Operations)

**Account Management**
- `ConnectTwitterAccountCommand` - Connect new Twitter account
- `DisconnectAccountCommand` - Disconnect account
- `UpdateAccountSettingsCommand` - Update account configuration

**Contact Management**
- `CreateContactCommand` - Create new contact
- `UpdateContactCommand` - Update contact details
- `AddContactTagCommand` - Add tag to contact
- `RemoveContactTagCommand` - Remove tag
- `UpdateContactAttributesCommand` - Bulk update attributes

**Conversation Management**
- `StartConversationCommand` - Start new conversation
- `SendMessageCommand` - Send message in conversation
- `CloseConversationCommand` - Close conversation
- `AssignConversationCommand` - Assign to agent

**Campaign Management**
- `CreateCampaignCommand` - Create campaign
- `StartCampaignCommand` - Start campaign execution
- `PauseCampaignCommand` - Pause running campaign
- `ResumeCampaignCommand` - Resume paused campaign

**Automation**
- `CreateAutomationFlowCommand` - Create automation workflow
- `ActivateFlowCommand` - Activate flow
- `DeactivateFlowCommand` - Deactivate flow

#### Queries (Read Operations)

**Analytics Queries**
- `GetOverviewAnalyticsQuery` - Dashboard metrics
- `GetContactAnalyticsQuery` - Contact statistics
- `GetConversationAnalyticsQuery` - Conversation metrics
- `GetCampaignAnalyticsQuery` - Campaign performance

**Data Retrieval**
- `GetContactsQuery` - List contacts with filtering/pagination
- `GetConversationsQuery` - List conversations
- `GetCampaignsQuery` - List campaigns
- `GetSegmentsQuery` - List segments

### Infrastructure Components

#### External API Clients

**TwitterApiClient**
```csharp
public interface ITwitterApiClient
{
    Task<TwitterUserInfo> GetUserInfoAsync(string userId);
    Task<string> SendDirectMessageAsync(string recipientId, string text);
    Task<bool> SubscribeToWebhooksAsync(string webhookUrl);
    Task<bool> VerifyCredentialsAsync(string token, string secret);
}
```

**AIServiceClient**
```csharp
public interface IAIServiceClient
{
    Task<IntentDetectionResult> DetectIntentAsync(string message, List<string> context);
    Task<string> GenerateResponseAsync(string intent, Dictionary<string, object> slots);
    Task<double> AnalyzeSentimentAsync(string message);
}
```

#### Background Jobs

**CampaignSchedulerJob**
- Runs: Every 1 minute
- Purpose: Check for scheduled campaigns and enqueue execution
- Concurrency: Single instance with distributed lock

**MessageProcessorJob**
- Runs: Continuously with polling
- Purpose: Process outbound message queue
- Rate Limiting: Respects Twitter limits (500/24h per account)

**WebhookEventProcessorJob**
- Runs: Continuously with polling
- Purpose: Process incoming Twitter webhook events
- Creates: Contacts, Conversations, Messages

---

## Data Architecture

### Database Schema

#### Core Tables

**twitter_accounts**
```sql
CREATE TABLE twitter_accounts (
    id UUID PRIMARY KEY,
    merchant_id UUID NOT NULL,
    twitter_user_id VARCHAR(100) NOT NULL UNIQUE,
    username VARCHAR(100) NOT NULL,
    display_name VARCHAR(200),
    status VARCHAR(20) NOT NULL,
    oauth_token TEXT NOT NULL, -- encrypted
    oauth_token_secret TEXT NOT NULL, -- encrypted
    webhook_id VARCHAR(100),
    connected_at TIMESTAMP NOT NULL,
    created_at TIMESTAMP NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMP
);
```

**contacts**
```sql
CREATE TABLE contacts (
    id UUID PRIMARY KEY,
    account_id UUID NOT NULL REFERENCES twitter_accounts(id),
    twitter_user_id VARCHAR(100) NOT NULL,
    username VARCHAR(100) NOT NULL,
    display_name VARCHAR(200),
    profile_image_url TEXT,
    source VARCHAR(50) NOT NULL,
    attributes JSONB DEFAULT '{}',
    first_interaction_at TIMESTAMP NOT NULL,
    last_interaction_at TIMESTAMP,
    created_at TIMESTAMP NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMP,
    UNIQUE(account_id, twitter_user_id)
);

CREATE INDEX idx_contacts_account ON contacts(account_id);
CREATE INDEX idx_contacts_twitter_user ON contacts(twitter_user_id);
CREATE INDEX idx_contacts_attributes ON contacts USING GIN(attributes);
```

**conversations**
```sql
CREATE TABLE conversations (
    id UUID PRIMARY KEY,
    contact_id UUID NOT NULL REFERENCES contacts(id),
    account_id UUID NOT NULL REFERENCES twitter_accounts(id),
    status VARCHAR(20) NOT NULL,
    channel VARCHAR(20) NOT NULL,
    assigned_to_user_id UUID,
    started_at TIMESTAMP NOT NULL,
    closed_at TIMESTAMP,
    created_at TIMESTAMP NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMP
);

CREATE INDEX idx_conversations_contact ON conversations(contact_id);
CREATE INDEX idx_conversations_status ON conversations(status);
```

**messages**
```sql
CREATE TABLE messages (
    id UUID PRIMARY KEY,
    conversation_id UUID NOT NULL REFERENCES conversations(id),
    twitter_message_id VARCHAR(100),
    direction VARCHAR(20) NOT NULL,
    type VARCHAR(20) NOT NULL,
    content TEXT NOT NULL,
    attachments JSONB,
    is_from_bot BOOLEAN NOT NULL DEFAULT FALSE,
    sent_at TIMESTAMP NOT NULL,
    created_at TIMESTAMP NOT NULL DEFAULT NOW()
);

CREATE INDEX idx_messages_conversation ON messages(conversation_id);
CREATE INDEX idx_messages_sent_at ON messages(sent_at DESC);
```

### Caching Strategy

**Redis Cache Structure**

```
Contact Profiles: "contact:{contactId}" - TTL: 1 hour
Templates: "template:{templateId}" - TTL: 10 minutes
Segments: "segment:{segmentId}:contacts" - TTL: 5 minutes
Campaign Metrics: "campaign:{campaignId}:metrics" - TTL: 1 minute
Rate Limits: "ratelimit:twitter:{accountId}" - TTL: 24 hours
```

---

## Integration Architecture

### Twitter API Integration

#### OAuth 1.0a Flow

```
1. Merchant initiates connection
2. Service requests request token from Twitter
3. Redirect merchant to Twitter authorization URL
4. Twitter redirects back with verifier
5. Service exchanges verifier for access token
6. Store encrypted tokens in database
7. Subscribe to webhooks for the account
```

#### Webhook Events

**Supported Events**:
- `direct_message_events` - New DM received
- `direct_message_indicate_typing_events` - User typing
- `direct_message_mark_read_events` - Message read
- `follow_events` - New follower
- `favorite_events` - Tweet liked

**Event Processing Flow**:
```
Twitter → Webhook Endpoint → Event Queue → Event Processor → Domain Logic
```

### OpenAI Integration

#### AI Conversation Flow

```
1. User sends message
2. Extract conversation context (last 10 messages)
3. Call OpenAI API with context and message
4. Parse intent and entities
5. If intent requires data, call internal services
6. Generate response using OpenAI
7. Send response to user
8. Store conversation context
```

#### Error Handling

- **API Timeout**: Retry up to 3 times with exponential backoff
- **Rate Limit**: Queue request and retry after cooldown
- **Low Confidence**: Auto-escalate to human agent

### Event Bus Integration

#### Published Events

```csharp
public record TwitterContactCreatedEvent(
    Guid ContactId,
    Guid MerchantId,
    string TwitterUserId) : IIntegrationEvent;

public record TwitterConversationStartedEvent(
    Guid ConversationId,
    Guid ContactId) : IIntegrationEvent;

public record TwitterCampaignCompletedEvent(
    Guid CampaignId,
    CampaignMetrics Metrics) : IIntegrationEvent;
```

#### Consumed Events

```csharp
// From Order Service
public record OrderCreatedEvent(Guid OrderId, string UserId);

// From Product Service  
public record ProductStockChangedEvent(Guid ProductId, int NewStock);
```

---

## Security Architecture

### Authentication & Authorization

**API Authentication**
- JWT Bearer tokens for API access
- OAuth 1.0a for Twitter account connection
- Refresh token rotation

**Authorization**
- Role-Based Access Control (RBAC)
- Merchant-level data isolation
- Permission checks at API and domain level

### Data Protection

**Encryption at Rest**
- OAuth tokens encrypted using AES-256
- Encryption keys stored in Azure Key Vault / AWS KMS
- Database encryption for sensitive fields

**Encryption in Transit**
- TLS 1.3 for all HTTP communication
- Certificate pinning for Twitter API calls

### Input Validation

- FluentValidation for all commands
- SQL injection prevention via EF Core parameterization
- XSS protection via output encoding
- Rate limiting on all public endpoints

---

## Deployment Architecture

### Container Configuration

**Dockerfile**
```dockerfile
FROM mcr.microsoft.com/dotnet/sdk:8.0-alpine AS build
WORKDIR /src
COPY . .
RUN dotnet restore
RUN dotnet publish -c Release -o /app

FROM mcr.microsoft.com/dotnet/aspnet:8.0-alpine
WORKDIR /app
COPY --from=build /app .
RUN adduser -D appuser && chown -R appuser /app
USER appuser
EXPOSE 8080
ENTRYPOINT ["dotnet", "MktXService.API.dll"]
```

### Kubernetes Deployment

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mkt-x-service
spec:
  replicas: 3
  template:
    spec:
      containers:
      - name: api
        image: mkt-x-service:latest
        resources:
          requests:
            memory: "256Mi"
            cpu: "250m"
          limits:
            memory: "512Mi"
            cpu: "500m"
        env:
        - name: ASPNETCORE_ENVIRONMENT
          value: "Production"
        livenessProbe:
          httpGet:
            path: /health
            port: 8080
          initialDelaySeconds: 30
          periodSeconds: 10
```

### Horizontal Pod Autoscaling

```yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: mkt-x-service-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: mkt-x-service
  minReplicas: 2
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70
```

---

## Performance Targets

| Metric | Target | Notes |
|--------|--------|-------|
| API Response Time (P95) | < 500ms | Excluding external API calls |
| Message Processing | 100 msg/sec | Per Twitter account |
| Campaign Throughput | 10,000 contacts/min | With rate limiting |
| Database Query (P95) | < 100ms | Single-table queries |
| Webhook Processing | < 2s | Time to store event |
| Cache Hit Ratio | > 80% | For contact lookups |

---

## Monitoring & Observability

### Metrics (Prometheus)

```
# API Metrics
http_requests_total{method, endpoint, status}
http_request_duration_seconds{method, endpoint}

# Business Metrics
twitter_messages_sent_total{account_id}
twitter_campaigns_active{merchant_id}
twitter_conversations_active{account_id}

# Infrastructure Metrics
db_connections_active
redis_cache_hit_ratio
rabbitmq_messages_pending
```

### Logging (Structured)

```json
{
  "timestamp": "2026-01-18T10:00:00Z",
  "level": "Information",
  "message": "Campaign started",
  "properties": {
    "campaignId": "uuid",
    "merchantId": "uuid",
    "targetContactCount": 1000
  }
}
```

### Distributed Tracing

- OpenTelemetry integration
- Trace all external API calls
- Correlation IDs across microservices

---

## References

- [Twitter API v2 Documentation](https://developer.twitter.com/en/docs/twitter-api)
- [OpenAI API Documentation](https://platform.openai.com/docs)
- [.NET Microservices Architecture](https://docs.microsoft.com/en-us/dotnet/architecture/microservices/)
- [Domain-Driven Design by Eric Evans](https://domainlanguage.com/ddd/)
