# Promotion Service .NET

> **EN**: Campaign, Voucher and Gift Card management service for GoodGo Platform.  
> **VI**: Dịch vụ quản lý Chiến dịch, Voucher và Gift Card cho GoodGo Platform.

## Overview

Promotion Service manages marketing campaigns with Vouchers and Gift Cards:

- **Campaign Management** - Create and manage campaigns with multiple models
- **Voucher/Gift Card** - Generate codes, distribute, redeem and expire
- **Unified Asset Model** - Support both Currency and Point as backing assets
- **Escrow Integration** - Integrate escrow with Wallet Service
- **Refund Surplus** - Mechanism to refund unused amount to Merchant

## Tech Stack

| Component | Technology |
|-----------|------------|
| Framework | .NET 10 |
| Database | PostgreSQL (EF Core) |
| CQRS | MediatR |
| Validation | FluentValidation |
| API Docs | Swagger/OpenAPI |
| Logging | Serilog |
| Message Bus | RabbitMQ (Events) |

## Requirements

```bash
# Check .NET version
dotnet --version  # Must be 10.0.x
```

## Quick Start

### 1. Environment Configuration

```bash
cp .env.example .env
# Edit .env with your database connection
```

### 2. Run with Docker

```bash
cd deployments/local
docker-compose up promotion-service -d
```

### 3. Run Locally

```bash
cd services/promotion-service-net
dotnet restore
dotnet build
dotnet run --project src/PromotionService.API
```

## API Endpoints

### Campaign APIs (Merchant)

| Method | Endpoint | Description |
|--------|----------|-------------|
| `POST` | `/api/v1/campaigns` | Create new campaign |
| `GET` | `/api/v1/campaigns` | List merchant's campaigns |
| `GET` | `/api/v1/campaigns/{id}` | Get campaign details |
| `PUT` | `/api/v1/campaigns/{id}` | Update campaign |
| `POST` | `/api/v1/campaigns/{id}/activate` | Activate campaign |
| `POST` | `/api/v1/campaigns/{id}/pause` | Pause campaign |
| `POST` | `/api/v1/campaigns/{id}/cancel` | Cancel campaign (refund escrow) |

### Voucher APIs (User)

| Method | Endpoint | Description |
|--------|----------|-------------|
| `POST` | `/api/v1/vouchers/claim` | Claim free voucher |
| `POST` | `/api/v1/vouchers/exchange` | Exchange points for voucher |
| `POST` | `/api/v1/vouchers/purchase` | Purchase gift card |
| `GET` | `/api/v1/vouchers/validate/{code}` | Validate voucher code |
| `POST` | `/api/v1/vouchers/redeem` | Redeem voucher |
| `GET` | `/api/v1/users/{userId}/vouchers` | Get user's vouchers |

### Admin APIs

| Method | Endpoint | Description |
|--------|----------|-------------|
| `GET` | `/api/v1/admin/campaigns` | List all campaigns |
| `GET` | `/api/v1/admin/campaigns/{id}/statistics` | Campaign statistics |
| `POST` | `/api/v1/admin/vouchers/{id}/revoke` | Revoke voucher |

### Health Endpoints

| Endpoint | Purpose |
|----------|---------|
| `/health` | Full health status |
| `/health/live` | Liveness probe (K8s) |
| `/health/ready` | Readiness probe (K8s) |

## Project Structure

```
promotion-service-net/
├── src/
│   ├── PromotionService.API/           # API Layer
│   │   ├── Controllers/                # REST endpoints
│   │   └── Application/                # Commands & Queries
│   │       ├── Commands/               # Write operations
│   │       ├── Queries/                # Read operations
│   │       └── IntegrationEvents/      # Event handlers
│   │
│   ├── PromotionService.Domain/        # Domain Layer 
│   │   ├── AggregatesModel/
│   │   │   ├── CampaignAggregate/      # Campaign, Voucher
│   │   │   └── RedemptionAggregate/    # Redemption history
│   │   ├── Events/                     # Domain events
│   │   └── Exceptions/                 # Domain exceptions
│   │
│   └── PromotionService.Infrastructure/  # Infrastructure Layer
│       ├── EntityConfigurations/       # EF Core mappings
│       ├── Repositories/               # Data access
│       └── PromotionContext.cs         # DbContext
│
├── tests/
│   ├── PromotionService.UnitTests/     # Domain & Logic tests
│   └── PromotionService.FunctionalTests/  # API integration tests
│
├── docs/
│   ├── en/                             # English documentation
│   └── vi/                             # Vietnamese documentation
│
└── Dockerfile
```

## 4 Marketing Scenarios

### A. Free Cash Voucher

```yaml
Campaign:
  backing_asset_type: CURRENCY
  backing_asset_code: VND
  face_value: 50000
  acquisition_type: FREE
  acquisition_price: 0
```

### B. Exchange Points for Cash Voucher

```yaml
Campaign:
  backing_asset_type: CURRENCY
  backing_asset_code: VND
  face_value: 50000
  acquisition_type: EXCHANGE_POINTS
  acquisition_price: 500  # 500 points
```

### C. Purchase Gift Card

```yaml
Campaign:
  backing_asset_type: CURRENCY
  backing_asset_code: VND
  face_value: 100000
  acquisition_type: PURCHASE
  acquisition_price: 100000  # VND
```

### D. Free Bonus Points Voucher

```yaml
Campaign:
  backing_asset_type: POINT
  backing_asset_code: PPoint
  face_value: 100  # 100 points
  acquisition_type: FREE
  acquisition_price: 0
```

## Testing

```bash
# Run all tests
dotnet test

# Run with coverage
dotnet test /p:CollectCoverage=true

# Unit tests only
dotnet test tests/PromotionService.UnitTests

# Functional tests only
dotnet test tests/PromotionService.FunctionalTests
```

## Configuration

### Environment Variables

| Variable | Description | Required |
|----------|-------------|----------|
| `DATABASE_URL` | PostgreSQL connection | Yes |
| `WALLET_SERVICE_URL` | Wallet Service URL | Yes |
| `RABBITMQ_URL` | RabbitMQ connection | Yes |
| `JWT_AUTHORITY` | JWT issuer URL | Yes |

### appsettings.json

```json
{
  "ConnectionStrings": {
    "DefaultConnection": "Host=localhost;Database=promotion_db;Username=postgres;Password=postgres"
  },
  "WalletService": {
    "BaseUrl": "http://wallet-service:5000"
  },
  "RabbitMQ": {
    "Host": "localhost",
    "Username": "guest",
    "Password": "guest"
  }
}
```

## Database Migrations

```bash
# Create migration
dotnet ef migrations add InitialCreate \
  --project src/PromotionService.Infrastructure \
  --startup-project src/PromotionService.API

# Apply migration
dotnet ef database update \
  --project src/PromotionService.Infrastructure \
  --startup-project src/PromotionService.API
```

## Deployment

### Docker Build

```bash
docker build -t goodgo/promotion-service:latest .
```

### Docker Compose

Service is registered in `deployments/local/docker-compose.yml` with Traefik routing.

## Resources

- [Architecture Documentation](./ARCHITECTURE.md)
- [Wallet Service](../../../wallet-service-net/docs/en/README.md)
- [Merchant Service](../../../merchant-service-net/docs/en/README.md)

## License

Proprietary - GoodGo Platform
