docs: Add Mission Service architecture documentation in English and Vietnamese.

This commit is contained in:
Ho Ngoc Hai
2026-01-17 17:58:21 +07:00
parent 07367b192e
commit e285f3d3c6
2 changed files with 954 additions and 0 deletions

View File

@@ -0,0 +1,477 @@
# Mission Service Architecture
Technical architecture documentation for the Mission Service.
## High-Level Architecture
```mermaid
%%{init: {'theme':'dark'}}%%
graph TD
subgraph API["🌐 API Layer"]
Controllers[Controllers]
Commands[Commands]
Queries[Queries]
end
subgraph Domain["⚙️ Domain Layer"]
Mission[Mission Aggregate]
Task[Task Aggregate]
CheckIn[CheckIn Aggregate]
end
subgraph Infra["💾 Infrastructure Layer"]
EF[EF Core]
Redis[(Redis Cache)]
RabbitMQ[RabbitMQ]
end
subgraph Data["🗄️ Data Storage"]
DB[(PostgreSQL)]
end
API --> Domain
Domain --> Infra
EF --> 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:#34495E,color:#ECF0F1,stroke:#2C3E50,stroke-width:2px
style Data fill:#27AE60,color:#ECF0F1,stroke:#229954,stroke-width:2px
```
## Architecture Patterns
### CQRS Pattern
```mermaid
%%{init: {'theme':'dark'}}%%
flowchart LR
subgraph Write["📝 Commands"]
C1[StartTaskCommand]
C2[CompleteTaskCommand]
C3[ClaimRewardCommand]
C4[CheckInCommand]
C5[CreateMissionCommand]
end
subgraph Read["📖 Queries"]
Q1[GetMissionsQuery]
Q2[GetUserTasksQuery]
Q3[GetCheckInStatusQuery]
Q4[GetAnalyticsQuery]
end
style Write fill:#E67E22,color:#ECF0F1,stroke:#D35400,stroke-width:2px
style Read fill:#3498DB,color:#ECF0F1,stroke:#2980B9,stroke-width:2px
```
## Domain Model
### Mission Aggregate
```mermaid
%%{init: {'theme':'dark'}}%%
classDiagram
class Mission {
+Guid Id
+string Code
+LocalizedString Title
+LocalizedString Description
+MissionType Type
+MissionCategory Category
+MissionReward Reward
+FrequencyType Frequency
+int MaxCompletions
+DateTime StartDate
+DateTime EndDate
+MissionStatus Status
+int Priority
+Activate()
+Pause()
+ValidateCompletion()
}
class MissionRule {
+Guid Id
+string RuleType
+string Operator
+string Value
+string Metadata
}
class MissionReward {
+decimal Points
+decimal MiningBoost
+int ExperiencePoints
+string BadgeId
}
Mission "1" --> "*" MissionRule : has
Mission --> MissionReward : uses
```
### Task Aggregate
```mermaid
%%{init: {'theme':'dark'}}%%
classDiagram
class UserTask {
+Guid Id
+Guid UserId
+Guid MissionId
+TaskStatus Status
+TaskProgress Progress
+TaskEvidence Evidence
+VerificationResult Verification
+bool RewardClaimed
+DateTime StartedAt
+DateTime CompletedAt
+Start()
+UpdateProgress()
+SubmitEvidence()
+Complete()
+ClaimReward()
}
class TaskProgress {
+int CurrentValue
+int TargetValue
+decimal PercentComplete
+DateTime LastUpdated
}
class TaskEvidence {
+string EvidenceType
+string Data
+string ScreenshotUrl
+DateTime CapturedAt
}
class VerificationResult {
+bool IsValid
+string FailureReason
+VerificationMethod Method
+Guid VerifiedBy
+DateTime VerifiedAt
}
UserTask --> TaskProgress : tracks
UserTask --> TaskEvidence : has
UserTask --> VerificationResult : verified by
```
### CheckIn Aggregate
```mermaid
%%{init: {'theme':'dark'}}%%
classDiagram
class UserCheckIn {
+Guid Id
+Guid UserId
+int CurrentStreak
+int LongestStreak
+int TotalCheckIns
+DateOnly LastCheckInDate
+CheckIn()
+CanCheckInToday()
+GetStreakBonus()
+GetMonthlyReward()
}
class CheckInDay {
+Guid Id
+DateOnly Date
+decimal PointsEarned
+bool IsMilestone
}
class StreakBonus {
+int MinDays
+int MaxDays
+decimal BonusPercent
+decimal MilestoneBonus
}
UserCheckIn "1" --> "*" CheckInDay : records
UserCheckIn --> StreakBonus : applies
```
## Database Schema
### ER Diagram
```mermaid
%%{init: {'theme':'dark'}}%%
erDiagram
Mission ||--o{ MissionRule : has
Mission ||--o{ UserTask : generates
UserTask }o--|| User : belongs
User ||--o| UserCheckIn : has
UserCheckIn ||--o{ CheckInDay : records
Mission {
uuid Id PK
string Code UK
json Title
json Description
string Type
string Category
json Reward
string Frequency
int MaxCompletions
datetime StartDate
datetime EndDate
string Status
int Priority
datetime CreatedAt
}
MissionRule {
uuid Id PK
uuid MissionId FK
string RuleType
string Operator
string Value
json Metadata
}
UserTask {
uuid Id PK
uuid UserId FK
uuid MissionId FK
string Status
json Progress
json Evidence
json Verification
bool RewardClaimed
datetime StartedAt
datetime CompletedAt
}
UserCheckIn {
uuid Id PK
uuid UserId FK
int CurrentStreak
int LongestStreak
int TotalCheckIns
date LastCheckInDate
}
CheckInDay {
uuid Id PK
uuid UserCheckInId FK
date Date
decimal PointsEarned
bool IsMilestone
}
```
## Reward Flow with Wallet Service
### Claim Reward Sequence
```mermaid
%%{init: {'theme':'dark'}}%%
sequenceDiagram
participant Client as 📱 Client
participant API as 🌐 Mission API
participant Task as ⚙️ TaskAggregate
participant DB as 💾 PostgreSQL
participant MQ as 📨 RabbitMQ
participant Wallet as 💰 Wallet Service
Client->>API: POST /api/v1/tasks/{id}/claim
API->>Task: ClaimRewardCommand
Task->>Task: ValidateTaskCompleted()
Task->>Task: ValidateNotAlreadyClaimed()
alt Task Valid
Task->>Task: MarkRewardClaimed()
Task->>DB: SaveChanges()
Task->>MQ: Publish MissionCompletedEvent
MQ->>Wallet: Consume MissionCompletedEvent
Wallet->>Wallet: GrantPoints(userId, amount)
API-->>Client: 200 OK { points_earned }
else Already Claimed
API-->>Client: 400 Bad Request
end
```
### CheckIn Reward Flow
```mermaid
%%{init: {'theme':'dark'}}%%
sequenceDiagram
participant Client as 📱 Client
participant API as 🌐 Mission API
participant CheckIn as 📅 CheckInAggregate
participant DB as 💾 PostgreSQL
participant MQ as 📨 RabbitMQ
participant Wallet as 💰 Wallet Service
Client->>API: POST /api/v1/checkin
API->>CheckIn: CheckInCommand
CheckIn->>CheckIn: CanCheckInToday()
alt Can Check In
CheckIn->>CheckIn: IncrementStreak()
CheckIn->>CheckIn: CalculateStreakBonus()
CheckIn->>CheckIn: CheckMilestone()
CheckIn->>DB: SaveCheckInDay()
CheckIn->>MQ: Publish CheckInCompletedEvent
MQ->>Wallet: Consume CheckInCompletedEvent
Wallet->>Wallet: GrantPoints(userId, dailyPoints + bonus)
API-->>Client: 200 OK { streak, points, milestone }
else Already Checked In
API-->>Client: 400 Already checked in today
end
```
## Integration Events
### Events Published
```mermaid
%%{init: {'theme':'dark'}}%%
flowchart LR
subgraph Mission["📋 Mission Service"]
M[Events Publisher]
end
subgraph Events["📨 Integration Events"]
E1[MissionCompletedEvent]
E2[CheckInCompletedEvent]
E3[TaskStartedEvent]
E4[RewardClaimedEvent]
end
subgraph Consumers["📥 Consumers"]
Wallet[Wallet Service]
Mining[Mining Service]
end
M --> E1 --> Wallet
M --> E2 --> Wallet
M --> E3
M --> E4 --> Wallet
E1 -.-> Mining
style Events fill:#E67E22,color:#ECF0F1,stroke:#D35400,stroke-width:2px
style Wallet fill:#27AE60,color:#ECF0F1,stroke:#229954,stroke-width:2px
```
### Event Payloads
```csharp
public record MissionCompletedEvent(
Guid TaskId,
Guid UserId,
Guid MissionId,
string MissionType,
decimal PointsEarned,
DateTime CompletedAt
);
public record CheckInCompletedEvent(
Guid UserId,
int StreakDays,
decimal BasePoints,
decimal StreakBonus,
decimal MilestoneBonus,
decimal TotalPoints,
DateTime CheckedInAt
);
public record RewardClaimedEvent(
Guid TaskId,
Guid UserId,
decimal PointsAmount,
string RewardType,
DateTime ClaimedAt
);
```
## Service Dependencies
```mermaid
%%{init: {'theme':'dark'}}%%
graph TD
subgraph External["🔐 Authentication"]
IAM[IAM Service]
end
subgraph Core["📋 Mission Service"]
Mission[Mission Service]
end
subgraph Integration["🔗 Integrations"]
Wallet[Wallet Service]
Mining[Mining Service]
Social[Social Service]
Storage[Storage Service]
end
IAM -->|JWT Validation| Mission
Mission -->|Grant Points| Wallet
Mission <-->|Referral Sync| Mining
Mission <-->|Friend Data| Social
Mission <-->|Media Upload| Storage
style External fill:#C0392B,color:#ECF0F1,stroke:#A93226,stroke-width:2px
style Core fill:#8E44AD,color:#ECF0F1,stroke:#7D3C98,stroke-width:3px
style Integration fill:#3498DB,color:#ECF0F1,stroke:#2980B9,stroke-width:2px
```
## Caching Strategy
| Key Pattern | TTL | Purpose |
|-------------|-----|---------|
| `mission:{id}` | 1h | Cache mission details |
| `missions:active` | 5m | Active missions list |
| `user:{id}:tasks` | 10m | User's active tasks |
| `user:{id}:checkin` | 24h | Check-in status |
| `config:missions` | 30m | Mission configurations |
## Security
### Anti-Fraud Flow
```mermaid
%%{init: {'theme':'dark'}}%%
flowchart TD
Request([🚀 Request]) --> RateLimit{⏱️ Rate Limit}
RateLimit -->|Exceeded| Block[❌ Block]
RateLimit -->|OK| Cooldown{⏳ Cooldown}
Cooldown -->|Too Fast| Wait[⏸️ Wait]
Cooldown -->|OK| Device{🔍 Device Check}
Device -->|New/Suspicious| Flag[⚠️ Flag for Review]
Device -->|OK| Evidence{📝 Evidence Valid?}
Evidence -->|No| Reject[❌ Reject]
Evidence -->|Yes| Approve[✅ Approve & Reward]
style Block fill:#C0392B,color:#ECF0F1,stroke:#A93226,stroke-width:2px
style Reject fill:#E74C3C,color:#ECF0F1,stroke:#C0392B,stroke-width:2px
style Approve fill:#27AE60,color:#ECF0F1,stroke:#229954,stroke-width:2px
```
## Health Checks
| Endpoint | Check |
|----------|-------|
| `/health/live` | ✅ Service running |
| `/health/ready` | ✅ DB + Redis + RabbitMQ connected |
| `/health` | ✅ Full status |
## Observability
### Metrics
- Tasks started per minute
- Tasks completed per minute
- Check-in rate
- Reward claims
- Verification success rate
### Logging
- Structured JSON logs (Serilog)
- Correlation IDs for tracing
- Sensitive data masking

View File

@@ -0,0 +1,477 @@
# Kiến Trúc Mission Service
Tài liệu kiến trúc kỹ thuật cho Mission Service.
## Kiến Trúc Tổng Quan
```mermaid
%%{init: {'theme':'dark'}}%%
graph TD
subgraph API["🌐 Tầng API"]
Controllers[Controllers]
Commands[Commands]
Queries[Queries]
end
subgraph Domain["⚙️ Tầng Domain"]
Mission[Mission Aggregate]
Task[Task Aggregate]
CheckIn[CheckIn Aggregate]
end
subgraph Infra["💾 Tầng Infrastructure"]
EF[EF Core]
Redis[(Redis Cache)]
RabbitMQ[RabbitMQ]
end
subgraph Data["🗄️ Lưu Trữ Dữ Liệu"]
DB[(PostgreSQL)]
end
API --> Domain
Domain --> Infra
EF --> 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:#34495E,color:#ECF0F1,stroke:#2C3E50,stroke-width:2px
style Data fill:#27AE60,color:#ECF0F1,stroke:#229954,stroke-width:2px
```
## Các Mẫu Kiến Trúc
### CQRS Pattern
```mermaid
%%{init: {'theme':'dark'}}%%
flowchart LR
subgraph Write["📝 Commands (Ghi)"]
C1[StartTaskCommand]
C2[CompleteTaskCommand]
C3[ClaimRewardCommand]
C4[CheckInCommand]
C5[CreateMissionCommand]
end
subgraph Read["📖 Queries (Đọc)"]
Q1[GetMissionsQuery]
Q2[GetUserTasksQuery]
Q3[GetCheckInStatusQuery]
Q4[GetAnalyticsQuery]
end
style Write fill:#E67E22,color:#ECF0F1,stroke:#D35400,stroke-width:2px
style Read fill:#3498DB,color:#ECF0F1,stroke:#2980B9,stroke-width:2px
```
## Domain Model
### Mission Aggregate
```mermaid
%%{init: {'theme':'dark'}}%%
classDiagram
class Mission {
+Guid Id
+string Code
+LocalizedString Title
+LocalizedString Description
+MissionType Type
+MissionCategory Category
+MissionReward Reward
+FrequencyType Frequency
+int MaxCompletions
+DateTime StartDate
+DateTime EndDate
+MissionStatus Status
+int Priority
+Activate()
+Pause()
+ValidateCompletion()
}
class MissionRule {
+Guid Id
+string RuleType
+string Operator
+string Value
+string Metadata
}
class MissionReward {
+decimal Points
+decimal MiningBoost
+int ExperiencePoints
+string BadgeId
}
Mission "1" --> "*" MissionRule : chứa
Mission --> MissionReward : sử dụng
```
### Task Aggregate
```mermaid
%%{init: {'theme':'dark'}}%%
classDiagram
class UserTask {
+Guid Id
+Guid UserId
+Guid MissionId
+TaskStatus Status
+TaskProgress Progress
+TaskEvidence Evidence
+VerificationResult Verification
+bool RewardClaimed
+DateTime StartedAt
+DateTime CompletedAt
+Start()
+UpdateProgress()
+SubmitEvidence()
+Complete()
+ClaimReward()
}
class TaskProgress {
+int CurrentValue
+int TargetValue
+decimal PercentComplete
+DateTime LastUpdated
}
class TaskEvidence {
+string EvidenceType
+string Data
+string ScreenshotUrl
+DateTime CapturedAt
}
class VerificationResult {
+bool IsValid
+string FailureReason
+VerificationMethod Method
+Guid VerifiedBy
+DateTime VerifiedAt
}
UserTask --> TaskProgress : theo dõi
UserTask --> TaskEvidence : có
UserTask --> VerificationResult : xác thực bởi
```
### CheckIn Aggregate
```mermaid
%%{init: {'theme':'dark'}}%%
classDiagram
class UserCheckIn {
+Guid Id
+Guid UserId
+int CurrentStreak
+int LongestStreak
+int TotalCheckIns
+DateOnly LastCheckInDate
+CheckIn()
+CanCheckInToday()
+GetStreakBonus()
+GetMonthlyReward()
}
class CheckInDay {
+Guid Id
+DateOnly Date
+decimal PointsEarned
+bool IsMilestone
}
class StreakBonus {
+int MinDays
+int MaxDays
+decimal BonusPercent
+decimal MilestoneBonus
}
UserCheckIn "1" --> "*" CheckInDay : ghi nhận
UserCheckIn --> StreakBonus : áp dụng
```
## Database Schema
### ER Diagram
```mermaid
%%{init: {'theme':'dark'}}%%
erDiagram
Mission ||--o{ MissionRule : có
Mission ||--o{ UserTask : tạo ra
UserTask }o--|| User : thuộc về
User ||--o| UserCheckIn : có
UserCheckIn ||--o{ CheckInDay : ghi nhận
Mission {
uuid Id PK
string Code UK
json Title
json Description
string Type
string Category
json Reward
string Frequency
int MaxCompletions
datetime StartDate
datetime EndDate
string Status
int Priority
datetime CreatedAt
}
MissionRule {
uuid Id PK
uuid MissionId FK
string RuleType
string Operator
string Value
json Metadata
}
UserTask {
uuid Id PK
uuid UserId FK
uuid MissionId FK
string Status
json Progress
json Evidence
json Verification
bool RewardClaimed
datetime StartedAt
datetime CompletedAt
}
UserCheckIn {
uuid Id PK
uuid UserId FK
int CurrentStreak
int LongestStreak
int TotalCheckIns
date LastCheckInDate
}
CheckInDay {
uuid Id PK
uuid UserCheckInId FK
date Date
decimal PointsEarned
bool IsMilestone
}
```
## Luồng Nhận Thưởng với Wallet Service
### Luồng Nhận Thưởng Task
```mermaid
%%{init: {'theme':'dark'}}%%
sequenceDiagram
participant Client as 📱 Client
participant API as 🌐 Mission API
participant Task as ⚙️ TaskAggregate
participant DB as 💾 PostgreSQL
participant MQ as 📨 RabbitMQ
participant Wallet as 💰 Wallet Service
Client->>API: POST /api/v1/tasks/{id}/claim
API->>Task: ClaimRewardCommand
Task->>Task: ValidateTaskCompleted()
Task->>Task: ValidateNotAlreadyClaimed()
alt Task Hợp Lệ
Task->>Task: MarkRewardClaimed()
Task->>DB: SaveChanges()
Task->>MQ: Publish MissionCompletedEvent
MQ->>Wallet: Consume MissionCompletedEvent
Wallet->>Wallet: GrantPoints(userId, amount)
API-->>Client: 200 OK { points_earned }
else Đã Nhận Thưởng
API-->>Client: 400 Bad Request
end
```
### Luồng Thưởng Check-in
```mermaid
%%{init: {'theme':'dark'}}%%
sequenceDiagram
participant Client as 📱 Client
participant API as 🌐 Mission API
participant CheckIn as 📅 CheckInAggregate
participant DB as 💾 PostgreSQL
participant MQ as 📨 RabbitMQ
participant Wallet as 💰 Wallet Service
Client->>API: POST /api/v1/checkin
API->>CheckIn: CheckInCommand
CheckIn->>CheckIn: CanCheckInToday()
alt Có Thể Check-in
CheckIn->>CheckIn: IncrementStreak()
CheckIn->>CheckIn: CalculateStreakBonus()
CheckIn->>CheckIn: CheckMilestone()
CheckIn->>DB: SaveCheckInDay()
CheckIn->>MQ: Publish CheckInCompletedEvent
MQ->>Wallet: Consume CheckInCompletedEvent
Wallet->>Wallet: GrantPoints(userId, dailyPoints + bonus)
API-->>Client: 200 OK { streak, points, milestone }
else Đã Check-in Hôm Nay
API-->>Client: 400 Đã điểm danh hôm nay
end
```
## Integration Events
### Các Event Được Xuất Bản
```mermaid
%%{init: {'theme':'dark'}}%%
flowchart LR
subgraph Mission["📋 Mission Service"]
M[Events Publisher]
end
subgraph Events["📨 Integration Events"]
E1[MissionCompletedEvent]
E2[CheckInCompletedEvent]
E3[TaskStartedEvent]
E4[RewardClaimedEvent]
end
subgraph Consumers["📥 Người Tiêu Thụ"]
Wallet[Wallet Service]
Mining[Mining Service]
end
M --> E1 --> Wallet
M --> E2 --> Wallet
M --> E3
M --> E4 --> Wallet
E1 -.-> Mining
style Events fill:#E67E22,color:#ECF0F1,stroke:#D35400,stroke-width:2px
style Wallet fill:#27AE60,color:#ECF0F1,stroke:#229954,stroke-width:2px
```
### Event Payloads
```csharp
public record MissionCompletedEvent(
Guid TaskId,
Guid UserId,
Guid MissionId,
string MissionType,
decimal PointsEarned, // Điểm kiếm được
DateTime CompletedAt
);
public record CheckInCompletedEvent(
Guid UserId,
int StreakDays, // Số ngày streak
decimal BasePoints, // Điểm cơ bản
decimal StreakBonus, // Thưởng streak
decimal MilestoneBonus, // Thưởng mốc
decimal TotalPoints, // Tổng điểm
DateTime CheckedInAt
);
public record RewardClaimedEvent(
Guid TaskId,
Guid UserId,
decimal PointsAmount,
string RewardType,
DateTime ClaimedAt
);
```
## Phụ Thuộc Dịch Vụ
```mermaid
%%{init: {'theme':'dark'}}%%
graph TD
subgraph External["🔐 Xác Thực"]
IAM[IAM Service]
end
subgraph Core["📋 Mission Service"]
Mission[Mission Service]
end
subgraph Integration["🔗 Tích Hợp"]
Wallet[Wallet Service]
Mining[Mining Service]
Social[Social Service]
Storage[Storage Service]
end
IAM -->|Xác thực JWT| Mission
Mission -->|Cấp Điểm| Wallet
Mission <-->|Đồng bộ Referral| Mining
Mission <-->|Dữ liệu Bạn bè| Social
Mission <-->|Upload Media| Storage
style External fill:#C0392B,color:#ECF0F1,stroke:#A93226,stroke-width:2px
style Core fill:#8E44AD,color:#ECF0F1,stroke:#7D3C98,stroke-width:3px
style Integration fill:#3498DB,color:#ECF0F1,stroke:#2980B9,stroke-width:2px
```
## Chiến Lược Cache
| Key Pattern | TTL | Mục Đích |
|-------------|-----|----------|
| `mission:{id}` | 1h | Cache chi tiết mission |
| `missions:active` | 5m | Danh sách missions hoạt động |
| `user:{id}:tasks` | 10m | Tasks đang làm của user |
| `user:{id}:checkin` | 24h | Trạng thái check-in |
| `config:missions` | 30m | Cấu hình mission |
## Bảo Mật
### Luồng Chống Gian Lận
```mermaid
%%{init: {'theme':'dark'}}%%
flowchart TD
Request([🚀 Yêu Cầu]) --> RateLimit{⏱️ Rate Limit}
RateLimit -->|Vượt Quá| Block[❌ Chặn]
RateLimit -->|OK| Cooldown{⏳ Cooldown}
Cooldown -->|Quá Nhanh| Wait[⏸️ Chờ]
Cooldown -->|OK| Device{🔍 Kiểm Tra Thiết Bị}
Device -->|Mới/Đáng Ngờ| Flag[⚠️ Đánh Dấu Xem Xét]
Device -->|OK| Evidence{📝 Bằng Chứng Hợp Lệ?}
Evidence -->|Không| Reject[❌ Từ Chối]
Evidence -->|Có| Approve[✅ Duyệt & Thưởng]
style Block fill:#C0392B,color:#ECF0F1,stroke:#A93226,stroke-width:2px
style Reject fill:#E74C3C,color:#ECF0F1,stroke:#C0392B,stroke-width:2px
style Approve fill:#27AE60,color:#ECF0F1,stroke:#229954,stroke-width:2px
```
## Health Checks
| Endpoint | Kiểm Tra |
|----------|----------|
| `/health/live` | ✅ Service đang chạy |
| `/health/ready` | ✅ DB + Redis + RabbitMQ đã kết nối |
| `/health` | ✅ Trạng thái đầy đủ |
## Observability
### Metrics
- Số tasks bắt đầu mỗi phút
- Số tasks hoàn thành mỗi phút
- Tỷ lệ check-in
- Số lần nhận thưởng
- Tỷ lệ xác thực thành công
### Logging
- Logs JSON có cấu trúc (Serilog)
- Correlation IDs để tracing
- Ẩn dữ liệu nhạy cảm