Files
pos-system/services/mining-service-net/docs/en/ARCHITECTURE.md

479 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Mining Service Architecture
## Overview
The Mining Service provides a gamified point mining system inspired by Pi Network, enabling users to accumulate Mining Points through daily engagement and community building.
```mermaid
%%{init: {'theme':'dark'}}%%
graph TD
subgraph API["🌐 API Layer"]
Controllers[Controllers]
Commands[Commands]
Queries[Queries]
end
subgraph Domain["⚙️ Domain Layer"]
Miner[Miner Aggregate]
Circle[Circle Aggregate]
Referral[Referral 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
### 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"]
C1[StartMiningCommand]
C2[ClaimRewardCommand]
C3[CreateCircleCommand]
C4[InviteToCircleCommand]
C5[ApplyReferralCommand]
end
subgraph Read["📖 Queries"]
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 : has
Miner --> MiningRate : uses
Miner --> MiningStreak : tracks
Miner "1" --> "*" MiningHistory : tracks
```
### 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 : contains
```
### 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()
}
```
## Mining Rate Formula
```mermaid
%%{init: {'theme':'dark'}}%%
flowchart LR
Base["🎯 Base Rate<br/>0.25 MP/hour"] --> Multiply1((×))
Role["👤 Role Bonus<br/>+0-50%"] --> Multiply1
Multiply1 --> Multiply2((×))
Circle["🔵 Circle Bonus<br/>+25%"] --> Multiply2
Multiply2 --> Multiply3((×))
Referral["👥 Referral Bonus<br/>+25%/each"] --> Multiply3
Multiply3 --> Total["✅ Total Rate<br/>MP/hour"]
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
```
**Example Calculation:**
| Component | Value | Multiplier |
|-----------|-------|------------|
| Base Rate | 0.25 MP/hour | - |
| Role (Ambassador) | +25% | × 1.25 |
| Valid Circle | +25% | × 1.25 |
| 2 Referrals | +50% | × 1.50 |
| **Total** | **0.585 MP/hour** | **14.04 MP/day** |
## Database Schema
### ER Diagram
```mermaid
%%{init: {'theme':'dark'}}%%
erDiagram
Miner ||--o{ MiningSession : has
Miner ||--o{ MiningHistory : tracks
Miner ||--o| Circle : owns
Circle ||--|{ CircleMember : contains
Miner ||--o{ Referral : refers
Miner ||--o| Referral : referredBy
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
}
```
### Key Indexes
| Index | Columns | Purpose |
|-------|---------|---------|
| `IX_Miners_UserId` | UserId | Fast lookup by user |
| `IX_Miners_ReferralCode` | ReferralCode | Referral code lookup |
| `IX_MiningSessions_MinerId_Status` | MinerId, Status | Active session check |
| `IX_Referrals_ReferrerId` | ReferrerId | Referral list |
## API Flow
### Start Mining Session
```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(24h)
Miner->>DB: SaveSession()
Miner->>Cache: CacheSessionInfo(ttl: 24h)
API-->>Client: 200 OK { session_id, rate, end_time }
```
### Claim Mining Reward
```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 Session Completed
Miner->>Miner: CalculateEarnedPoints()
Miner->>Miner: AddToTotalPoints()
Miner->>DB: SaveMiningHistory()
Miner->>MQ: Publish PointsMinedEvent
API-->>Client: 200 OK { earned_points, total_points }
else Session Not Ready
API-->>Client: 400 Bad Request
end
```
## Inter-Service Communication
### Service Dependencies
```mermaid
%%{init: {'theme':'dark'}}%%
graph TD
subgraph External["🔐 Authentication"]
IAM[IAM Service]
end
subgraph Core["⛏️ Mining Service"]
Mining[Mining Service]
end
subgraph Integration["🔗 Integrations"]
Social[Social Service]
Wallet[Wallet Service]
end
IAM -->|JWT Validation| Mining
Social <-->|Friend Data| Mining
Mining -->|Point Conversion| 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["📤 Publishers"]
IAM[IAM Service]
Social[Social Service]
Mining1[Mining Service]
end
subgraph Events["📨 Events"]
E1[UserRegisteredEvent]
E2[FriendAddedEvent]
E3[PointsMinedEvent]
end
subgraph Consumers["📥 Consumers"]
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
```
## Deployment
### 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 | Check |
|----------|-------|
| `/health/live` | ✅ Service running |
| `/health/ready` | ✅ DB + Redis connected |
| `/health` | ✅ Full status |
## Security
### Rate Limiting
- 1 mining session start per 24 hours
- 10 circle invites per day
### Anti-Fraud
```mermaid
%%{init: {'theme':'dark'}}%%
flowchart TD
Request([🚀 Request]) --> Device{🔍 Device Check}
Device -->|New Device| Flag[⚠️ Flag for Review]
Device -->|Known| IP{🌐 IP Check}
IP -->|Suspicious| Block[❌ Block]
IP -->|Normal| KYC{🔐 KYC Verified?}
KYC -->|No| Limited[⚠️ Limited Features]
KYC -->|Yes| Full[✅ Full Access]
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
```
## Caching Strategy (Redis)
| Key Pattern | TTL | Purpose |
|-------------|-----|---------|
| `session:{minerId}` | 24h | Active session cache |
| `rate:{minerId}` | 1h | Mining rate cache |
| `leaderboard:daily` | 5m | Leaderboard cache |
## Monitoring
### Metrics
- Mining sessions started/day
- Points mined total
- Active miners count
- Referral conversion rate
### Logging
- Serilog structured logging
- Correlation IDs for tracing
- Prometheus + Grafana integration