# Ads Serving Service - Dịch vụ Phân phối Quảng cáo

> Microservice xử lý đấu giá thời gian thực (RTB) và phân phối quảng cáo với độ trễ < 100ms.

## Tổng Quan

Ads Serving Service là "trái tim" của hệ thống quảng cáo, xử lý hàng triệu yêu cầu mỗi giây:

- **Real-Time Bidding (RTB)** - Đấu giá thời gian thực
- **Ad Selection** - Chọn quảng cáo phù hợp nhất
- **Pacing Algorithm** - Điều tiết ngân sách
- **Frequency Capping** - Kiểm soát tần suất hiển thị

## Yêu Cầu

| Yêu cầu | Phiên bản |
|---------|-----------|
| .NET SDK | 10.0.101+ |
| Docker | 24.0+ |
| Redis | 7.0+ (bắt buộc) |
| PostgreSQL | 15+ |

## Bắt Đầu Nhanh

```bash
cd services/ads-serving-service-net
docker-compose up -d
```

## Cấu Trúc Dự Án

```
ads-serving-service-net/
├── src/
│   ├── AdsServingService.API/
│   │   ├── Controllers/
│   │   │   └── AdServeController.cs     # Endpoint phục vụ ads
│   │   └── Application/
│   │
│   ├── AdsServingService.Domain/
│   │   └── AggregatesModel/
│   │       ├── AdRequestAggregate/      # Yêu cầu quảng cáo
│   │       ├── AuctionAggregate/        # Đấu giá
│   │       ├── PacingAggregate/         # Điều tiết ngân sách
│   │       └── FrequencyAggregate/      # Kiểm soát tần suất
│   │
│   └── AdsServingService.Infrastructure/
│
└── AdsServingService.slnx
```

## Quy Trình Phân Phối (< 100ms)

```
Request → Gateway → Check Cache → Run Auction → Return Ad → Fire Events (async)
   │                    │              │              │
   │                    ▼              ▼              ▼
   │              Redis Cache    eCPM Ranking    RabbitMQ
   │              (< 5ms)        (in-memory)     (tracking)
```

### Công Thức eCPM

```
eCPM = (Bid × Predicted CTR × 1000) + Quality Score
```

## API Endpoints

| Method | Endpoint | Mô tả |
|--------|----------|-------|
| `POST` | `/api/v1/ads/serve` | Lấy quảng cáo cho placement |
| `POST` | `/api/v1/ads/events/impression` | Ghi nhận hiển thị |
| `POST` | `/api/v1/ads/events/click` | Ghi nhận click |

### Request/Response Example

```json
// POST /api/v1/ads/serve
{
  "placementType": "feed",
  "userId": "user-123",
  "context": {
    "deviceType": "mobile",
    "location": "HCM"
  }
}

// Response
{
  "adId": "ad-456",
  "creativeUrl": "https://storage.goodgo.com/...",
  "headline": "Khuyến mãi 50%",
  "destinationUrl": "https://...",
  "trackingUrls": {
    "impression": "...",
    "click": "..."
  }
}
```

## Admin Backoffice APIs

### Auction Management

| Method | Endpoint | Mô tả |
|--------|----------|-------|
| `GET` | `/api/v1/admin/auctions` | Danh sách auctions (phân trang, có bộ lọc) |
| `GET` | `/api/v1/admin/auctions/statistics` | Thống kê đấu giá (win rate, eCPM, etc.) |

### Budget Management

| Method | Endpoint | Mô tả |
|--------|----------|-------|
| `GET` | `/api/v1/admin/budget/pacers` | Danh sách budget pacers |
| `GET` | `/api/v1/admin/budget/campaigns/{id}` | Trạng thái ngân sách campaign |
| `PUT` | `/api/v1/admin/budget/campaigns/{id}/reset` | Reset chi tiêu hàng ngày (manual) |
| `GET` | `/api/v1/admin/budget/statistics` | Thống kê ngân sách tổng thể |

### Frequency Cap Management

| Method | Endpoint | Mô tả |
|--------|----------|-------|
| `GET` | `/api/v1/admin/frequency/caps` | Danh sách frequency caps |
| `GET` | `/api/v1/admin/frequency/caps/{id}` | Chi tiết frequency cap |
| `POST` | `/api/v1/admin/frequency/caps` | Tạo frequency cap |
| `DELETE` | `/api/v1/admin/frequency/caps/{id}` | Xóa frequency cap |

## Database Schema

```sql
-- Auctions table
CREATE TABLE auctions (
    id UUID PRIMARY KEY,
    user_id UUID NOT NULL,
    placement_type VARCHAR(50) NOT NULL,
    auction_time TIMESTAMP NOT NULL,
    bids JSONB,
    winning_ad_id UUID,
    winning_campaign_id UUID,
    final_price DECIMAL(18,4),
    winning_ecpm DECIMAL(18,4)
);

-- Budget Pacers table
CREATE TABLE budget_pacers (
    id UUID PRIMARY KEY,
    campaign_id UUID NOT NULL UNIQUE,
    daily_budget DECIMAL(18,4) NOT NULL,
    spent_today DECIMAL(18,4) NOT NULL,
    strategy VARCHAR(20) NOT NULL,
    last_updated TIMESTAMP NOT NULL
);

-- Frequency Caps table
CREATE TABLE frequency_caps (
    id UUID PRIMARY KEY,
    ad_id UUID NOT NULL,
    max_impressions_per_user INT NOT NULL,
    window VARCHAR(20) NOT NULL
);
```

## Migrations

```bash
# Tạo migration
dotnet ef migrations add MigrationName --project src/AdsServingService.Infrastructure --startup-project src/AdsServingService.API

# Apply migrations
dotnet ef database update --project src/AdsServingService.Infrastructure --startup-project src/AdsServingService.API


## Redis Caching Strategy

| Key Pattern | TTL | Mục đích |
|-------------|-----|----------|
| `ads:active:{placement}` | 5 min | Danh sách ads active |
| `freq:{userId}:{date}` | 24h | Frequency per user |
| `budget:{campaignId}:{date}` | 24h | Budget tracker |
| `target:{criteria}` | 1h | Targeting index |

## Tích Hợp

| Service | Tích hợp |
|---------|---------|
| **ads-manager-service** | Consume active ads |
| **ads-billing-service** | Publish charge events |
| **ads-tracking-service** | Publish impression/click events |

## Cấu Hình

| Biến | Mô tả |
|------|-------|
| `REDIS_URL` | Redis connection (bắt buộc) |
| `DATABASE_URL` | PostgreSQL connection |
| `RABBITMQ_URL` | RabbitMQ connection |

## Giấy Phép

Độc quyền - GoodGo Platform
