480 lines
12 KiB
Markdown
480 lines
12 KiB
Markdown
# Kiến Trúc Mining Service
|
||
|
||
## Tổng Quan
|
||
|
||
Mining Service cung cấp hệ thống đào điểm game hóa lấy cảm hứng từ Pi Network, cho phép người dùng tích lũy Mining Points thông qua hoạt động hàng ngày và xây dựng cộng đồng.
|
||
|
||
```mermaid
|
||
%%{init: {'theme':'dark'}}%%
|
||
graph TD
|
||
subgraph API["🌐 Tầng API"]
|
||
Controllers[Controllers]
|
||
Commands[Commands]
|
||
Queries[Queries]
|
||
end
|
||
|
||
subgraph Domain["⚙️ Tầng Domain"]
|
||
Miner[Miner Aggregate]
|
||
Circle[Circle Aggregate]
|
||
Referral[Referral 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
|
||
|
||
### Domain-Driven Design (DDD)
|
||
|
||
- **Aggregates**: Miner, Circle, Referral
|
||
- **Entities**: MiningSession, MiningHistory, CircleMember
|
||
- **Value Objects**: MiningRate, MiningPoints, MiningSession
|
||
- **Domain Events**: MiningSessionStarted, PointsMined, CircleCompleted, ReferralActivated
|
||
|
||
### CQRS Pattern
|
||
|
||
```mermaid
|
||
%%{init: {'theme':'dark'}}%%
|
||
flowchart LR
|
||
subgraph Write["📝 Commands (Ghi)"]
|
||
C1[StartMiningCommand]
|
||
C2[ClaimRewardCommand]
|
||
C3[CreateCircleCommand]
|
||
C4[InviteToCircleCommand]
|
||
C5[ApplyReferralCommand]
|
||
end
|
||
|
||
subgraph Read["📖 Queries (Đọc)"]
|
||
Q1[GetMinerStatusQuery]
|
||
Q2[GetMiningHistoryQuery]
|
||
Q3[GetCircleQuery]
|
||
Q4[GetReferralsQuery]
|
||
Q5[GetLeaderboardQuery]
|
||
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
|
||
|
||
### Miner Aggregate
|
||
|
||
```mermaid
|
||
%%{init: {'theme':'dark'}}%%
|
||
classDiagram
|
||
class Miner {
|
||
+Guid Id
|
||
+Guid UserId
|
||
+MinerRole Role
|
||
+decimal TotalMinedPoints
|
||
+MiningRate CurrentRate
|
||
+MiningSession ActiveSession
|
||
+MiningStreak Streak
|
||
+string ReferralCode
|
||
+Guid ReferredBy
|
||
+MinerStatus Status
|
||
+StartMiningSession()
|
||
+ClaimMiningReward()
|
||
+UpgradeRole()
|
||
+RecalculateMiningRate()
|
||
}
|
||
|
||
class MiningSession {
|
||
+Guid SessionId
|
||
+DateTime StartTime
|
||
+DateTime EndTime
|
||
+decimal AccumulatedPoints
|
||
+SessionStatus Status
|
||
}
|
||
|
||
class MiningRate {
|
||
+decimal BaseRate
|
||
+decimal CircleBonus
|
||
+decimal ReferralBonus
|
||
+decimal RoleBonus
|
||
+decimal StreakBonus
|
||
+decimal TotalRate
|
||
}
|
||
|
||
class MiningStreak {
|
||
+int CurrentStreak
|
||
+int LongestStreak
|
||
+DateTime LastMiningDate
|
||
+int FreezeTokens
|
||
+bool IsGracePeriod
|
||
+decimal BonusMultiplier
|
||
}
|
||
|
||
class MiningHistory {
|
||
+Guid Id
|
||
+decimal PointsEarned
|
||
+string Source
|
||
+DateTime EarnedAt
|
||
}
|
||
|
||
Miner "1" --> "0..1" MiningSession : có
|
||
Miner --> MiningRate : sử dụng
|
||
Miner --> MiningStreak : theo dõi
|
||
Miner "1" --> "*" MiningHistory : theo dõi
|
||
```
|
||
|
||
### Circle Aggregate
|
||
|
||
```mermaid
|
||
%%{init: {'theme':'dark'}}%%
|
||
classDiagram
|
||
class Circle {
|
||
+Guid Id
|
||
+Guid OwnerId
|
||
+string Name
|
||
+List~CircleMember~ Members
|
||
+decimal TrustScore
|
||
+decimal BonusMultiplier
|
||
+CircleStatus Status
|
||
+AddMember()
|
||
+RemoveMember()
|
||
+CalculateTrustScore()
|
||
+Validate()
|
||
}
|
||
|
||
class CircleMember {
|
||
+Guid Id
|
||
+Guid MinerId
|
||
+DateTime JoinedAt
|
||
+bool IsActive
|
||
}
|
||
|
||
Circle "1" --> "3..5" CircleMember : chứa
|
||
```
|
||
|
||
### Referral Aggregate
|
||
|
||
```mermaid
|
||
%%{init: {'theme':'dark'}}%%
|
||
classDiagram
|
||
class Referral {
|
||
+Guid Id
|
||
+Guid ReferrerId
|
||
+Guid ReferredId
|
||
+string ReferralCode
|
||
+decimal BonusRate
|
||
+bool IsActive
|
||
+int Level
|
||
+DateTime CreatedAt
|
||
+Activate()
|
||
+Deactivate()
|
||
+CalculateBonus()
|
||
}
|
||
```
|
||
|
||
## Công Thức Tỷ Lệ Đào
|
||
|
||
```mermaid
|
||
%%{init: {'theme':'dark'}}%%
|
||
flowchart LR
|
||
Base["🎯 Tỷ Lệ Cơ Bản<br/>0.25 MP/giờ"] --> Multiply1((×))
|
||
Role["👤 Thưởng Vai Trò<br/>+0-50%"] --> Multiply1
|
||
Multiply1 --> Multiply2((×))
|
||
Circle["🔵 Thưởng Vòng Tròn<br/>+25%"] --> Multiply2
|
||
Multiply2 --> Multiply3((×))
|
||
Referral["👥 Thưởng Giới Thiệu<br/>+25%/người"] --> Multiply3
|
||
Multiply3 --> Total["✅ Tỷ Lệ Tổng<br/>MP/giờ"]
|
||
|
||
style Base fill:#2C3E50,color:#ECF0F1,stroke:#34495E,stroke-width:2px
|
||
style Role fill:#8E44AD,color:#ECF0F1,stroke:#7D3C98,stroke-width:2px
|
||
style Circle fill:#3498DB,color:#ECF0F1,stroke:#2980B9,stroke-width:2px
|
||
style Referral fill:#E67E22,color:#ECF0F1,stroke:#D35400,stroke-width:2px
|
||
style Total fill:#27AE60,color:#ECF0F1,stroke:#229954,stroke-width:3px
|
||
```
|
||
|
||
**Ví Dụ Tính Toán:**
|
||
| Thành Phần | Giá Trị | Hệ Số |
|
||
|------------|---------|-------|
|
||
| Tỷ Lệ Cơ Bản | 0.25 MP/giờ | - |
|
||
| Vai Trò (Ambassador) | +25% | × 1.25 |
|
||
| Vòng Tròn Hợp Lệ | +25% | × 1.25 |
|
||
| 2 Giới Thiệu | +50% | × 1.50 |
|
||
| **Tổng** | **0.585 MP/giờ** | **14.04 MP/ngày** |
|
||
|
||
## Database Schema
|
||
|
||
### ER Diagram
|
||
|
||
```mermaid
|
||
%%{init: {'theme':'dark'}}%%
|
||
erDiagram
|
||
Miner ||--o{ MiningSession : "có"
|
||
Miner ||--o{ MiningHistory : "theo dõi"
|
||
Miner ||--o| Circle : "sở hữu"
|
||
Circle ||--|{ CircleMember : "chứa"
|
||
Miner ||--o{ Referral : "giới thiệu"
|
||
Miner ||--o| Referral : "được giới thiệu bởi"
|
||
|
||
Miner {
|
||
uuid Id PK
|
||
uuid UserId UK
|
||
string Role
|
||
decimal TotalMinedPoints
|
||
string ReferralCode UK
|
||
uuid ReferredBy FK
|
||
string Status
|
||
datetime CreatedAt
|
||
}
|
||
|
||
MiningSession {
|
||
uuid Id PK
|
||
uuid MinerId FK
|
||
datetime StartTime
|
||
datetime EndTime
|
||
decimal AccumulatedPoints
|
||
string Status
|
||
}
|
||
|
||
MiningHistory {
|
||
uuid Id PK
|
||
uuid MinerId FK
|
||
decimal PointsEarned
|
||
string Source
|
||
datetime EarnedAt
|
||
}
|
||
|
||
Circle {
|
||
uuid Id PK
|
||
uuid OwnerId FK
|
||
string Name
|
||
decimal TrustScore
|
||
decimal BonusMultiplier
|
||
string Status
|
||
}
|
||
|
||
CircleMember {
|
||
uuid Id PK
|
||
uuid CircleId FK
|
||
uuid MinerId FK
|
||
datetime JoinedAt
|
||
bool IsActive
|
||
}
|
||
|
||
Referral {
|
||
uuid Id PK
|
||
uuid ReferrerId FK
|
||
uuid ReferredId FK
|
||
string ReferralCode
|
||
decimal BonusRate
|
||
bool IsActive
|
||
int Level
|
||
}
|
||
```
|
||
|
||
### Các Index Quan Trọng
|
||
|
||
| Index | Cột | Mục Đích |
|
||
|-------|-----|----------|
|
||
| `IX_Miners_UserId` | UserId | Tra cứu nhanh theo user |
|
||
| `IX_Miners_ReferralCode` | ReferralCode | Tra cứu mã giới thiệu |
|
||
| `IX_MiningSessions_MinerId_Status` | MinerId, Status | Kiểm tra phiên hoạt động |
|
||
| `IX_Referrals_ReferrerId` | ReferrerId | Danh sách giới thiệu |
|
||
|
||
## Luồng API
|
||
|
||
### Bắt Đầu Phiên Đào
|
||
|
||
```mermaid
|
||
%%{init: {'theme':'dark'}}%%
|
||
sequenceDiagram
|
||
participant Client as 📱 Client
|
||
participant API as 🌐 Mining API
|
||
participant Handler as ⚙️ CommandHandler
|
||
participant Miner as 👤 MinerAggregate
|
||
participant Calc as 🧮 RateCalculator
|
||
participant DB as 💾 PostgreSQL
|
||
participant Cache as ⚡ Redis
|
||
|
||
Client->>API: POST /api/v1/mining/start
|
||
API->>Handler: StartMiningCommand
|
||
Handler->>Miner: ValidateNoActiveSession()
|
||
Handler->>Calc: CalculateMiningRate()
|
||
Calc-->>Handler: MiningRate
|
||
Handler->>Miner: CreateSession(24 giờ)
|
||
Miner->>DB: SaveSession()
|
||
Miner->>Cache: CacheSessionInfo(ttl: 24h)
|
||
API-->>Client: 200 OK { session_id, rate, end_time }
|
||
```
|
||
|
||
### Nhận Thưởng Đào
|
||
|
||
```mermaid
|
||
%%{init: {'theme':'dark'}}%%
|
||
sequenceDiagram
|
||
participant Client as 📱 Client
|
||
participant API as 🌐 Mining API
|
||
participant Handler as ⚙️ CommandHandler
|
||
participant Miner as 👤 MinerAggregate
|
||
participant DB as 💾 PostgreSQL
|
||
participant MQ as 📨 RabbitMQ
|
||
|
||
Client->>API: POST /api/v1/mining/claim
|
||
API->>Handler: ClaimRewardCommand
|
||
Handler->>Miner: GetActiveSession()
|
||
|
||
alt Phiên Đã Hoàn Thành
|
||
Miner->>Miner: CalculateEarnedPoints()
|
||
Miner->>Miner: AddToTotalPoints()
|
||
Miner->>DB: SaveMiningHistory()
|
||
Miner->>MQ: Publish PointsMinedEvent
|
||
API-->>Client: 200 OK { earned_points, total_points }
|
||
else Phiên Chưa Sẵn Sàng
|
||
API-->>Client: 400 Bad Request
|
||
end
|
||
```
|
||
|
||
## Giao Tiếp Liên Dịch Vụ
|
||
|
||
### Phụ Thuộc Dịch Vụ
|
||
|
||
```mermaid
|
||
%%{init: {'theme':'dark'}}%%
|
||
graph TD
|
||
subgraph External["🔐 Xác Thực"]
|
||
IAM[IAM Service]
|
||
end
|
||
|
||
subgraph Core["⛏️ Mining Service"]
|
||
Mining[Mining Service]
|
||
end
|
||
|
||
subgraph Integration["🔗 Tích Hợp"]
|
||
Social[Social Service]
|
||
Wallet[Wallet Service]
|
||
end
|
||
|
||
IAM -->|Xác thực JWT| Mining
|
||
Social <-->|Dữ liệu bạn bè| Mining
|
||
Mining -->|Chuyển đổi điểm| Wallet
|
||
|
||
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
|
||
```
|
||
|
||
### Integration Events (RabbitMQ)
|
||
|
||
```mermaid
|
||
%%{init: {'theme':'dark'}}%%
|
||
flowchart LR
|
||
subgraph Publishers["📤 Nhà Xuất Bản"]
|
||
IAM[IAM Service]
|
||
Social[Social Service]
|
||
Mining1[Mining Service]
|
||
end
|
||
|
||
subgraph Events["📨 Sự Kiện"]
|
||
E1[UserRegisteredEvent]
|
||
E2[FriendAddedEvent]
|
||
E3[PointsMinedEvent]
|
||
end
|
||
|
||
subgraph Consumers["📥 Người Tiêu Thụ"]
|
||
Mining2[Mining Service]
|
||
Wallet[Wallet Service]
|
||
end
|
||
|
||
IAM --> E1 --> Mining2
|
||
Social --> E2 --> Mining2
|
||
Mining1 --> E3 --> Wallet
|
||
|
||
style Events fill:#E67E22,color:#ECF0F1,stroke:#D35400,stroke-width:2px
|
||
```
|
||
|
||
## Triển Khai
|
||
|
||
### Docker Compose
|
||
|
||
```yaml
|
||
mining-service:
|
||
build:
|
||
context: ../..
|
||
dockerfile: services/mining-service-net/Dockerfile
|
||
environment:
|
||
- DATABASE_URL=${MINING_DATABASE_URL}
|
||
- REDIS_URL=${REDIS_URL}
|
||
- RABBITMQ_URL=${RABBITMQ_URL}
|
||
- JWT_AUTHORITY=${IAM_SERVICE_URL}
|
||
labels:
|
||
- traefik.http.routers.mining.rule=PathPrefix(`/api/v1/mining`)
|
||
```
|
||
|
||
### Health Checks
|
||
|
||
| Endpoint | Kiểm Tra |
|
||
|----------|----------|
|
||
| `/health/live` | ✅ Service đang chạy |
|
||
| `/health/ready` | ✅ DB + Redis đã kết nối |
|
||
| `/health` | ✅ Trạng thái đầy đủ |
|
||
|
||
## Bảo Mật
|
||
|
||
### Giới Hạn Tốc Độ
|
||
- 1 phiên đào mỗi 24 giờ
|
||
- 10 lời mời vòng tròn mỗi ngày
|
||
|
||
### Chống Gian Lận
|
||
|
||
```mermaid
|
||
%%{init: {'theme':'dark'}}%%
|
||
flowchart TD
|
||
Request([🚀 Yêu Cầu]) --> Device{🔍 Kiểm Tra Thiết Bị}
|
||
Device -->|Thiết Bị Mới| Flag[⚠️ Đánh Dấu Xem Xét]
|
||
Device -->|Đã Biết| IP{🌐 Kiểm Tra IP}
|
||
IP -->|Đáng Ngờ| Block[❌ Chặn]
|
||
IP -->|Bình Thường| KYC{🔐 Đã KYC?}
|
||
KYC -->|Chưa| Limited[⚠️ Tính Năng Hạn Chế]
|
||
KYC -->|Rồi| Full[✅ Truy Cập Đầy Đủ]
|
||
|
||
style Request fill:#2C3E50,color:#ECF0F1,stroke:#34495E,stroke-width:3px
|
||
style Block fill:#C0392B,color:#ECF0F1,stroke:#A93226,stroke-width:2px
|
||
style Full fill:#27AE60,color:#ECF0F1,stroke:#229954,stroke-width:2px
|
||
style Device fill:#E67E22,color:#ECF0F1,stroke:#D35400,stroke-width:2px
|
||
style IP fill:#E67E22,color:#ECF0F1,stroke:#D35400,stroke-width:2px
|
||
style KYC fill:#E67E22,color:#ECF0F1,stroke:#D35400,stroke-width:2px
|
||
```
|
||
|
||
## Chiến Lược Cache (Redis)
|
||
|
||
| Mẫu Key | TTL | Mục Đích |
|
||
|---------|-----|----------|
|
||
| `session:{minerId}` | 24h | Cache phiên hoạt động |
|
||
| `rate:{minerId}` | 1h | Cache tỷ lệ đào |
|
||
| `leaderboard:daily` | 5m | Cache bảng xếp hạng |
|
||
|
||
## Giám Sát
|
||
|
||
### Metrics
|
||
- Số phiên đào bắt đầu/ngày
|
||
- Tổng điểm đã đào
|
||
- Số thợ đào hoạt động
|
||
- Tỷ lệ chuyển đổi giới thiệu
|
||
|
||
### Logging
|
||
- Serilog structured logging
|
||
- Correlation IDs để tracing
|
||
- Tích hợp Prometheus + Grafana
|