# Wallet Service Architecture

## Overview

The Wallet Service manages digital wallets and loyalty point accounts for the GoodGo Platform.

```mermaid
flowchart TB
    subgraph API["🌐 API Layer"]
        Controllers["Controllers"]
        Commands["Commands"]
        Queries["Queries"]
    end
    
    subgraph Domain["💎 Domain Layer"]
        Wallet["Wallet Aggregate"]
        PointAccount["PointAccount Aggregate"]
    end
    
    subgraph Infra["⚙️ Infrastructure Layer"]
        Repos["Repositories"]
        EF["EF Core"]
    end
    
    subgraph DB["💾 PostgreSQL"]
        Tables["Tables"]
    end
    
    API --> Domain
    Domain --> Infra
    Infra --> DB
    
    style API fill:#3498DB,color:#ECF0F1,stroke:#2980B9,stroke-width:3px
    style Domain fill:#8E44AD,color:#ECF0F1,stroke:#7D3C98,stroke-width:2px
    style Infra fill:#E67E22,color:#ECF0F1,stroke:#D35400,stroke-width:2px
    style DB fill:#34495E,color:#ECF0F1,stroke:#2C3E50,stroke-width:2px
```

## Architecture Patterns

### Domain-Driven Design (DDD)

- **Aggregates**: Wallet, PointAccount
- **Entities**: WalletTransaction, PointTransaction, HoldItem, WalletItem
- **Value Objects**: Money, CurrencyType
- **Domain Events**: WalletCreated, BalanceChanged, PointsEarned, EscrowHeld, EscrowExecuted

### CQRS Pattern

```mermaid
flowchart LR
    subgraph Commands["Commands (Write)"]
        C1["CreateWallet"]
        C2["Deposit/Withdraw"]
        C3["Exchange"]
        C4["Hold/Execute/Release"]
        C5["EarnPoints/SpendPoints"]
        C6["Admin Commands"]
    end
    
    subgraph Queries["Queries (Read)"]
        Q1["GetWallet"]
        Q2["GetTransactions"]
        Q3["GetPointAccount"]
        Q4["GetStatistics"]
        Q5["Admin Queries"]
    end
    
    style Commands fill:#27AE60,color:#ECF0F1,stroke:#229954,stroke-width:2px
    style Queries fill:#3498DB,color:#ECF0F1,stroke:#2980B9,stroke-width:2px
```

## Domain Model

### Wallet Aggregate

```mermaid
classDiagram
    class Wallet {
        +Guid Id
        +Guid UserId
        +WalletStatus Status
        +CurrencyType DefaultCurrency
        +List~WalletItem~ Items
        +List~HoldItem~ Holds
        +Deposit(amount, currency, desc, ref)
        +Withdraw(amount, currency, desc, ref)
        +Exchange(fromAmount, fromCurrency, toCurrency)
        +Hold(amount, currency, refType, refId, desc)
        +ExecuteHold(holdId, amount, ref)
        +ReleaseHold(holdId, amount)
        +Freeze()
        +Unfreeze()
    }
    
    class WalletItem {
        +Guid Id
        +CurrencyType Currency
        +decimal Balance
        +decimal HeldBalance
        +decimal AvailableBalance
    }
    
    class HoldItem {
        +Guid Id
        +decimal OriginalAmount
        +decimal RemainingAmount
        +decimal ExecutedAmount
        +decimal ReleasedAmount
        +HoldStatus Status
        +string ReferenceType
        +Guid ReferenceId
        +Execute(amount, ref)
        +Release(amount)
        +Cancel()
    }
    
    class WalletTransaction {
        +Guid Id
        +TransactionType Type
        +decimal Amount
        +CurrencyType Currency
        +decimal BalanceAfter
        +string Description
        +DateTime CreatedAt
    }
    
    class CurrencyType {
        +int Id
        +string Name
        +decimal BaseExchangeRate
        +VND
        +USD
        +PPoint
        +GetExchangeRateTo(currency)
        +ConvertTo(amount, currency)
    }
    
    Wallet "1" --> "*" WalletItem
    Wallet "1" --> "*" HoldItem
    Wallet "1" --> "*" WalletTransaction
    WalletItem --> CurrencyType
    HoldItem --> CurrencyType
```

### PointAccount Aggregate

```mermaid
classDiagram
    class PointAccount {
        +Guid Id
        +Guid UserId
        +long TotalPoints
        +long AvailablePoints
        +long PendingPoints
        +EarnPoints(points, source, desc, expires)
        +SpendPoints(points, source, desc)
        +AdjustPoints(points, source, desc)
    }
    
    class PointTransaction {
        +Guid Id
        +PointTransactionType Type
        +long Points
        +long BalanceAfter
        +string Source
        +DateTime? ExpiresAt
    }
    
    PointAccount "1" --> "*" PointTransaction
```

## Database Schema

### Tables

| Table | Description |
|-------|-------------|
| `Wallets` | User wallet accounts |
| `WalletItems` | Currency balances per wallet |
| `WalletTransactions` | Wallet transaction history |
| `HoldItems` | Escrow holds |
| `PointAccounts` | User point accounts |
| `PointTransactions` | Point transaction history |

### Key Indexes

- `IX_Wallets_UserId` - Fast lookup by user
- `IX_WalletItems_WalletId_CurrencyTypeId` - Balance by currency
- `IX_WalletTransactions_WalletId` - Transaction history
- `IX_HoldItems_WalletId_Status` - Active holds
- `IX_PointAccounts_UserId` - Fast lookup by user

## API Flow

### Deposit Flow

```mermaid
sequenceDiagram
    participant C as Client
    participant API as Controller
    participant H as Handler
    participant W as Wallet
    participant DB as Database
    
    C->>API: POST /wallets/{userId}/deposit
    API->>H: DepositCommand
    H->>W: wallet.Deposit(amount)
    W->>W: Create Transaction
    W->>W: Raise DomainEvent
    H->>DB: SaveChanges
    DB-->>API: Success
    API-->>C: Updated Balance
```

### Escrow Flow

```mermaid
sequenceDiagram
    participant C as Client
    participant API as Controller
    participant W as Wallet
    participant H as HoldItem
    
    C->>API: POST /holds (Create)
    API->>W: wallet.Hold(amount)
    W->>H: Create HoldItem
    W-->>C: HoldId
    
    C->>API: POST /holds/{id}/execute
    API->>W: wallet.ExecuteHold(id, amount)
    W->>H: hold.Execute(amount)
    H-->>C: Executed Amount
    
    C->>API: POST /holds/{id}/release
    API->>W: wallet.ReleaseHold(id, amount)
    W->>H: hold.Release(amount)
    H-->>C: Released Amount
```

### Currency Exchange Flow

```mermaid
sequenceDiagram
    participant C as Client
    participant API as Controller
    participant W as Wallet
    participant CT as CurrencyType
    
    C->>API: POST /exchange
    API->>W: wallet.Exchange(100 USD, VND)
    W->>CT: GetExchangeRate(USD → VND)
    CT-->>W: Rate = 25000
    W->>W: Withdraw 100 USD
    W->>W: Deposit 2,500,000 VND
    W->>W: Raise WalletExchangedEvent
    W-->>C: Exchange Result
```

## Domain Events

| Event | Trigger | Data |
|-------|---------|------|
| `WalletCreatedDomainEvent` | Wallet creation | WalletId, UserId |
| `WalletBalanceChangedDomainEvent` | Deposit/Withdraw | WalletId, Amount, Type |
| `WalletExchangedDomainEvent` | Currency exchange | FromCurrency, ToCurrency, Rate |
| `EscrowHeldDomainEvent` | Hold creation | HoldId, Amount, RefType |
| `EscrowExecutedDomainEvent` | Hold execution | HoldId, Amount |
| `EscrowReleasedDomainEvent` | Hold release | HoldId, Amount |
| `PointsEarnedDomainEvent` | Points earned | AccountId, Points |
| `PointsSpentDomainEvent` | Points spent | AccountId, Points |

## Inter-Service Communication

### IAM Service Integration

```mermaid
flowchart LR
    WS["🔐 Wallet Service"] --> IAM["👤 IAM Service"]
    IAM --> UV["User Validation"]
    IAM --> JV["JWT Verification"]
    
    style WS fill:#3498DB,color:#ECF0F1,stroke:#2980B9,stroke-width:2px
    style IAM fill:#8E44AD,color:#ECF0F1,stroke:#7D3C98,stroke-width:2px
    style UV fill:#27AE60,color:#ECF0F1,stroke:#229954,stroke-width:2px
    style JV fill:#27AE60,color:#ECF0F1,stroke:#229954,stroke-width:2px
```

### Authentication Flow

1. Client sends JWT token in Authorization header
2. Wallet Service validates JWT with IAM Service
3. Extract userId from JWT claims
4. Process wallet operation for user

## Deployment

### Docker Compose Configuration

```yaml
wallet-service:
  build:
    context: ../..
    dockerfile: services/wallet-service-net/Dockerfile
  environment:
    - DATABASE_URL=${WALLET_DATABASE_URL}
    - JWT_AUTHORITY=${IAM_SERVICE_URL}
  labels:
    - traefik.http.routers.wallet.rule=PathPrefix(`/api/v1/wallets`)
```

### Health Checks

| Endpoint | Check |
|----------|-------|
| `/health/live` | Service is running |
| `/health/ready` | Database connected |
| `/health` | Full status |

## Security

### Authentication
- JWT Bearer token validation
- IAM Service integration

### Authorization
- User can only access own wallet
- Admin endpoints require Admin/SuperAdmin role

### Data Protection
- All amounts stored with precision
- Transaction audit trail
- Soft delete for wallets

## Performance

### Optimizations
- Connection pooling (EF Core)
- Index on frequent queries
- Pagination for transaction history

### Scaling
- Horizontal scaling with load balancer
- Read replicas for queries
- Redis caching (future)

## Monitoring

### Metrics
- Request duration
- Transaction counts
- Error rates

### Logging
- Serilog structured logging
- Correlation IDs for tracing
- Seq/Loki integration
