# Wallet Service .NET

Dịch vụ quản lý Ví và Tài khoản Điểm cho GoodGo Platform.

## Tổng Quan

Wallet Service cung cấp quản lý ví và điểm thưởng toàn diện:

- **Quản Lý Ví** - Tạo, nạp tiền, rút tiền, chuyển khoản
- **Escrow Module** - Ký quỹ, cam kết và giải phóng tiền (cho Promotion Service)
- **Tài Khoản Điểm** - Tích, tiêu và theo dõi điểm thưởng
- **Lịch Sử Giao Dịch** - Audit trail đầy đủ các giao dịch
- **Hỗ Trợ Đa Tiền Tệ** - VND, USD, PPoint với khả năng quy đổi
- **Quy Đổi Tiền Tệ** - Chuyển đổi giữa các loại tiền với tỷ giá cấu hình
- **Admin Backoffice** - API quản trị đầy đủ cho ví/điểm
- **Domain-Driven Design** - Clean Architecture với CQRS pattern

## Tech Stack

| Thành Phần | Công Nghệ |
|------------|-----------|
| Framework | .NET 10 |
| Database | PostgreSQL (EF Core) |
| CQRS | MediatR |
| Validation | FluentValidation |
| API Docs | Swagger/OpenAPI |
| Logging | Serilog |

## Yêu Cầu Hệ Thống

```bash
# Kiểm tra phiên bản .NET
dotnet --version  # Phải là 10.0.x
```

## Bắt Đầu Nhanh

### 1. Cấu Hình Môi Trường

```bash
cp .env.example .env
# Chỉnh sửa .env với connection database của bạn
```

### 2. Chạy với Docker

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

### 3. Chạy Local

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

## API Endpoints

### Wallet APIs

| Method | Endpoint | Mô Tả |
|--------|----------|-------|
| `POST` | `/api/v1/wallets` | Tạo ví mới |
| `GET` | `/api/v1/wallets/{userId}` | Lấy ví theo user ID |
| `POST` | `/api/v1/wallets/{userId}/deposit` | Nạp tiền vào ví |
| `POST` | `/api/v1/wallets/{userId}/withdraw` | Rút tiền từ ví |
| `GET` | `/api/v1/wallets/{userId}/transactions` | Lấy lịch sử giao dịch |

### Escrow/Hold APIs

| Method | Endpoint | Mô Tả |
|--------|----------|-------|
| `POST` | `/api/v1/wallets/{walletId}/holds` | Tạo lệnh ký quỹ |
| `GET` | `/api/v1/wallets/{walletId}/holds/{holdId}` | Lấy thông tin ký quỹ |
| `POST` | `/api/v1/wallets/{walletId}/holds/{holdId}/execute` | Thực thi (trừ tiền) |
| `POST` | `/api/v1/wallets/{walletId}/holds/{holdId}/release` | Giải phóng (trả lại) |
| `POST` | `/api/v1/wallets/{walletId}/holds/{holdId}/cancel` | Hủy ký quỹ |

### Points APIs

| Method | Endpoint | Mô Tả |
|--------|----------|-------|
| `POST` | `/api/v1/points` | Tạo tài khoản điểm |
| `GET` | `/api/v1/points/{userId}` | Lấy tài khoản điểm |
| `POST` | `/api/v1/points/{userId}/earn` | Tích điểm |
| `POST` | `/api/v1/points/{userId}/spend` | Tiêu điểm |
| `GET` | `/api/v1/points/{userId}/transactions` | Lấy lịch sử điểm |

### Admin Wallet APIs

| Method | Endpoint | Mô Tả |
|--------|----------|-------|
| `GET` | `/api/v1/admin/wallets` | Lấy tất cả ví (phân trang) |
| `GET` | `/api/v1/admin/wallets/{walletId}` | Lấy chi tiết ví |
| `POST` | `/api/v1/admin/wallets/{walletId}/freeze` | Đóng băng ví |
| `POST` | `/api/v1/admin/wallets/{walletId}/unfreeze` | Mở băng ví |
| `POST` | `/api/v1/admin/wallets/{walletId}/adjust` | Điều chỉnh số dư |
| `GET` | `/api/v1/admin/wallets/statistics` | Thống kê ví |
| `GET` | `/api/v1/admin/wallets/search` | Tìm kiếm ví |

### Admin Points APIs

| Method | Endpoint | Mô Tả |
|--------|----------|-------|
| `GET` | `/api/v1/admin/points` | Lấy tất cả tài khoản điểm |
| `GET` | `/api/v1/admin/points/{accountId}` | Lấy chi tiết tài khoản |
| `POST` | `/api/v1/admin/points/{accountId}/adjust` | Điều chỉnh điểm |
| `POST` | `/api/v1/admin/points/{accountId}/bonus` | Tặng điểm thưởng |
| `GET` | `/api/v1/admin/points/statistics` | Thống kê điểm |
| `GET` | `/api/v1/admin/points/search` | Tìm kiếm tài khoản |

### Health Endpoints

| Endpoint | Mục Đích |
|----------|----------|
| `/health` | Trạng thái sức khỏe đầy đủ |
| `/health/live` | Liveness probe (K8s) |
| `/health/ready` | Readiness probe (K8s) |

## Hỗ Trợ Đa Tiền Tệ

Ví hỗ trợ nhiều loại tiền tệ với khả năng quy đổi:

| Tiền Tệ | Mã | Tỷ Giá Cơ Sở (VND) |
|---------|----|--------------------|
| Đồng Việt Nam | `VND` | 1 |
| Đô La Mỹ | `USD` | 25.000 |
| Điểm Thưởng | `PPoint` | 1.000 |

### Quy Đổi Tiền Tệ

```csharp
// Quy đổi USD sang VND
wallet.Exchange(
    fromAmount: 100m, 
    fromCurrency: CurrencyType.USD,
    toCurrency: CurrencyType.VND
); // Trả về 2.500.000 VND

// Quy đổi PPoints sang VND
wallet.Exchange(
    fromAmount: 50m,
    fromCurrency: CurrencyType.PPoint,
    toCurrency: CurrencyType.VND
); // Trả về 50.000 VND
```

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

```
wallet-service-net/
├── src/
│   ├── WalletService.API/           # API Layer
│   │   ├── Controllers/             # REST endpoints
│   │   │   └── Admin/               # Admin endpoints
│   │   └── Application/             # Commands & Queries
│   │       ├── Commands/            # Thao tác ghi
│   │       └── Queries/             # Thao tác đọc
│   │
│   ├── WalletService.Domain/        # Domain Layer 
│   │   ├── AggregatesModel/
│   │   │   ├── WalletAggregate/     # Wallet, HoldItem, CurrencyType
│   │   │   └── PointAccountAggregate/  # Points, PointTransaction
│   │   ├── Events/                  # Domain events
│   │   └── Exceptions/              # Domain exceptions
│   │
│   └── WalletService.Infrastructure/  # Infrastructure Layer
│       ├── EntityConfigurations/    # EF Core mappings
│       ├── Repositories/            # Data access
│       └── WalletServiceContext.cs  # DbContext
│
├── tests/
│   ├── WalletService.UnitTests/     # Domain & Logic tests
│   └── WalletService.FunctionalTests/  # API integration tests
│
├── docs/
│   ├── en/                          # Tài liệu tiếng Anh
│   └── vi/                          # Tài liệu tiếng Việt
│
└── Dockerfile
```

## Domain Model

### Wallet Aggregate

```csharp
// Tạo ví
var wallet = new Wallet(userId, CurrencyType.VND);

// Nạp tiền
wallet.Deposit(1000000m, CurrencyType.VND, "Lương", "REF001");

// Rút tiền  
wallet.Withdraw(500000m, CurrencyType.VND, "Mua sắm", "REF002");

// Đóng băng/Mở băng
wallet.Freeze();
wallet.Unfreeze();

// Thao tác Escrow
var hold = wallet.Hold(100000m, CurrencyType.VND, "CAMPAIGN", campaignId, "Ký quỹ chiến dịch");
wallet.ExecuteHold(hold.Id, 50000m, "ORDER123"); // Thực thi 50k
wallet.ReleaseHold(hold.Id, 50000m); // Trả lại 50k
wallet.CancelHold(hold.Id); // Hủy phần còn lại

// Quy đổi tiền tệ
wallet.Exchange(100m, CurrencyType.USD, CurrencyType.VND);
```

### Point Account Aggregate

```csharp
// Tạo tài khoản điểm
var account = new PointAccount(userId);

// Tích điểm
account.EarnPoints(100, "ORDER001", "Thưởng mua hàng", expiresAt);

// Tiêu điểm
account.SpendPoints(50, "ORDER002", "Đổi giảm giá");

// Điều chỉnh điểm (admin)
account.AdjustPoints(10, "ADMIN", "Điều chỉnh thưởng");
```

## Testing

```bash
# Chạy tất cả tests
dotnet test

# Chạy với coverage
dotnet test /p:CollectCoverage=true

# Chỉ unit tests
dotnet test tests/WalletService.UnitTests

# Chỉ functional tests
dotnet test tests/WalletService.FunctionalTests
```

### Kết Quả Test
- **23 tests** tổng cộng
- 20 unit tests (Wallet, PointAccount domain)
- 3 functional tests (Health endpoints)

## Cấu Hình

### Biến Môi Trường

| Biến | Mô Tả | Bắt Buộc |
|------|-------|----------|
| `DATABASE_URL` | Connection PostgreSQL | Có |
| `ASPNETCORE_ENVIRONMENT` | Môi trường | Không (mặc định: Development) |
| `JWT_AUTHORITY` | URL JWT issuer | Có (cho auth) |

### appsettings.json

```json
{
  "ConnectionStrings": {
    "DefaultConnection": "Host=localhost;Database=wallet_db;Username=postgres;Password=postgres"
  },
  "Jwt": {
    "Authority": "http://localhost:5001",
    "Issuer": "http://localhost:5001"
  }
}
```

## Database Migrations

```bash
# Tạo migration
dotnet ef migrations add InitialCreate \
  --project src/WalletService.Infrastructure \
  --startup-project src/WalletService.API

# Áp dụng migration
dotnet ef database update \
  --project src/WalletService.Infrastructure \
  --startup-project src/WalletService.API
```

## Triển Khai

### Docker Build

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

### Docker Compose

Service được đăng ký trong `deployments/local/docker-compose.yml` với Traefik routing.

## Tài Nguyên

- [Tài liệu Kiến trúc](./ARCHITECTURE.md)
- [Tài liệu GoodGo Platform](../../docs/)
- [eShopOnContainers Reference](https://github.com/dotnet-architecture/eShopOnContainers)

## Giấy Phép

Proprietary - GoodGo Platform
