823 lines
35 KiB
Markdown
823 lines
35 KiB
Markdown
# Mining Service .NET
|
||
|
||
> Mining Point management service with Pi Network-inspired mechanism for GoodGo Platform.
|
||
|
||
## Overview
|
||
|
||
The Mining Service provides a **gamified loyalty point mining system** inspired by Pi Network, allowing users to accumulate Mining Points (MP) through daily engagement, social referrals, and community building activities.
|
||
|
||
### Key Features
|
||
|
||
| Feature | Description |
|
||
|---------|-------------|
|
||
| **Daily Mining** | Tap-to-mine mechanism - users activate daily mining sessions |
|
||
| **Mining Rate** | Base rate increases through referrals and circle building |
|
||
| **🔥 Streak Bonus** | TikTok-style consecutive daily mining rewards |
|
||
| **Security Circles** | Trusted groups that boost mining rate and network security |
|
||
| **Referral System** | Multi-level referral bonuses for network growth |
|
||
| **User Roles** | Pioneer, Contributor, Ambassador, Node Operator tiers |
|
||
| **Point Conversion** | Convert Mining Points to platform loyalty points |
|
||
|
||
---
|
||
|
||
## Architecture Design
|
||
|
||
### System Architecture
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────────────────────┐
|
||
│ API Gateway (Traefik) │
|
||
└────────────────────────────────┬────────────────────────────────────┘
|
||
│
|
||
┌────────────────────────────────▼────────────────────────────────────┐
|
||
│ Mining Service .NET │
|
||
├─────────────────────────────────────────────────────────────────────┤
|
||
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
|
||
│ │ Mining │ │ Circle │ │ Referral │ │ Rate │ │
|
||
│ │ Session │ │ Manager │ │ Tracker │ │ Calculator │ │
|
||
│ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ │
|
||
├─────────────────────────────────────────────────────────────────────┤
|
||
│ Domain Layer │
|
||
│ ┌─────────────────────┐ ┌─────────────────────┐ │
|
||
│ │ MinerAggregate │ │ CircleAggregate │ │
|
||
│ │ - MiningSession │ │ - CircleMember │ │
|
||
│ │ - MiningHistory │ │ - TrustLevel │ │
|
||
│ │ - MiningRate │ │ - CircleBonus │ │
|
||
│ └─────────────────────┘ └─────────────────────┘ │
|
||
├─────────────────────────────────────────────────────────────────────┤
|
||
│ Infrastructure Layer │
|
||
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
|
||
│ │ PostgreSQL │ │ Redis │ │ RabbitMQ │ │
|
||
│ │ (EF Core) │ │ (Cache) │ │ (Events) │ │
|
||
│ └──────────────┘ └──────────────┘ └──────────────┘ │
|
||
└─────────────────────────────────────────────────────────────────────┘
|
||
│
|
||
┌────────────────────────┼────────────────────────┐
|
||
▼ ▼ ▼
|
||
┌───────────────┐ ┌─────────────────┐ ┌─────────────────┐
|
||
│ IAM Service │ │ Wallet Service │ │ Social Service │
|
||
│ (Auth/Users) │ │ (Point Convert) │ │ (Friends) │
|
||
└───────────────┘ └─────────────────┘ └─────────────────┘
|
||
```
|
||
|
||
### Clean Architecture Structure
|
||
|
||
```
|
||
mining-service-net/
|
||
├── src/
|
||
│ ├── MiningService.API/ # API Layer
|
||
│ │ ├── Controllers/
|
||
│ │ │ ├── MiningController.cs # Mining session APIs
|
||
│ │ │ ├── CirclesController.cs # Security circle APIs
|
||
│ │ │ └── ReferralsController.cs # Referral APIs
|
||
│ │ └── Application/
|
||
│ │ ├── Commands/ # Write operations
|
||
│ │ └── Queries/ # Read operations
|
||
│ │
|
||
│ ├── MiningService.Domain/ # Domain Layer
|
||
│ │ ├── AggregatesModel/
|
||
│ │ │ ├── MinerAggregate/ # User mining profile
|
||
│ │ │ ├── CircleAggregate/ # Security circles
|
||
│ │ │ └── ReferralAggregate/ # Referral tracking
|
||
│ │ ├── Events/ # Domain events
|
||
│ │ ├── Exceptions/ # Domain exceptions
|
||
│ │ └── Services/ # Domain services
|
||
│ │
|
||
│ └── MiningService.Infrastructure/ # Infrastructure Layer
|
||
│ ├── EntityConfigurations/ # EF Core mappings
|
||
│ ├── Repositories/ # Data access
|
||
│ └── MiningServiceContext.cs # DbContext
|
||
│
|
||
├── tests/
|
||
│ ├── MiningService.UnitTests/
|
||
│ └── MiningService.FunctionalTests/
|
||
│
|
||
├── docs/
|
||
│ ├── en/
|
||
│ └── vi/
|
||
│
|
||
└── Dockerfile
|
||
```
|
||
|
||
---
|
||
|
||
## Domain Model
|
||
|
||
### Core Aggregates
|
||
|
||
#### 1. Miner Aggregate (User Mining Profile)
|
||
|
||
```
|
||
┌────────────────────────────────────────────────────────────────────┐
|
||
│ Miner (Entity) │
|
||
├────────────────────────────────────────────────────────────────────┤
|
||
│ Properties: │
|
||
│ - Id: Guid │
|
||
│ - UserId: Guid (from IAM Service) │
|
||
│ - Role: MinerRole (Pioneer/Contributor/Ambassador/NodeOperator) │
|
||
│ - TotalMinedPoints: decimal │
|
||
│ - CurrentMiningRate: MiningRate (Value Object) │
|
||
│ - CurrentSession: MiningSession? │
|
||
│ - SecurityCircle: Circle? │
|
||
│ - ReferralCode: string │
|
||
│ - ReferredBy: Guid? │
|
||
│ - Status: MinerStatus (Active/Suspended/Banned) │
|
||
│ - CreatedAt: DateTime │
|
||
├────────────────────────────────────────────────────────────────────┤
|
||
│ Behaviors: │
|
||
│ - StartMiningSession() → MiningSession │
|
||
│ - ClaimMiningReward() → MiningPoints │
|
||
│ - UpgradeRole(role) → void │
|
||
│ - JoinCircle(circle) → void │
|
||
│ - RecalculateMiningRate() → MiningRate │
|
||
└────────────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
#### 2. Circle Aggregate (Security Circle)
|
||
|
||
```
|
||
┌────────────────────────────────────────────────────────────────────┐
|
||
│ Circle (Entity) │
|
||
├────────────────────────────────────────────────────────────────────┤
|
||
│ Properties: │
|
||
│ - Id: Guid │
|
||
│ - OwnerId: Guid (Miner who created the circle) │
|
||
│ - Members: List<CircleMember> (max 5) │
|
||
│ - Name: string │
|
||
│ - TrustScore: decimal (0-100) │
|
||
│ - BonusMultiplier: decimal │
|
||
│ - Status: CircleStatus (Active/Incomplete/Disbanded) │
|
||
│ - CreatedAt: DateTime │
|
||
├────────────────────────────────────────────────────────────────────┤
|
||
│ Behaviors: │
|
||
│ - AddMember(miner) → void │
|
||
│ - RemoveMember(minerId) → void │
|
||
│ - CalculateTrustScore() → decimal │
|
||
│ - CalculateBonusMultiplier() → decimal │
|
||
│ - Validate() → bool (min 3 members required) │
|
||
└────────────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
#### 3. Referral Aggregate
|
||
|
||
```
|
||
┌────────────────────────────────────────────────────────────────────┐
|
||
│ Referral (Entity) │
|
||
├────────────────────────────────────────────────────────────────────┤
|
||
│ Properties: │
|
||
│ - Id: Guid │
|
||
│ - ReferrerId: Guid (who invited) │
|
||
│ - ReferredId: Guid (who was invited) │
|
||
│ - ReferralCode: string │
|
||
│ - BonusRate: decimal │
|
||
│ - IsActive: bool │
|
||
│ - Level: int (1 = direct, 2 = indirect) │
|
||
│ - CreatedAt: DateTime │
|
||
├────────────────────────────────────────────────────────────────────┤
|
||
│ Behaviors: │
|
||
│ - Activate() → void │
|
||
│ - Deactivate() → void │
|
||
│ - CalculateBonus(baseRate) → decimal │
|
||
└────────────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
### Value Objects
|
||
|
||
```csharp
|
||
/// Mining Rate calculation
|
||
public record MiningRate(
|
||
decimal BaseRate, // Default: 0.25 MP/hour
|
||
decimal CircleBonus, // +0.25x for valid circle
|
||
decimal ReferralBonus, // +25% per active referral
|
||
decimal RoleBonus, // Based on role tier
|
||
decimal TotalRate // Combined rate
|
||
);
|
||
|
||
/// Mining Session tracking
|
||
public record MiningSession(
|
||
Guid SessionId,
|
||
DateTime StartTime,
|
||
DateTime EndTime, // StartTime + 24 hours
|
||
decimal AccumulatedPoints,
|
||
MiningSessionStatus Status // Active/Completed/Expired
|
||
);
|
||
|
||
/// Mining Points
|
||
public record MiningPoints(
|
||
decimal Amount,
|
||
DateTime EarnedAt,
|
||
string Source // Mining/Referral/CircleBonus/RoleBonus
|
||
);
|
||
```
|
||
|
||
---
|
||
|
||
## Mining Mechanism
|
||
|
||
### 🔥 Streak Bonus System (TikTok-style)
|
||
|
||
Consecutive daily mining rewards users with escalating bonuses:
|
||
|
||
```mermaid
|
||
%%{init: {'theme':'dark'}}%%
|
||
flowchart LR
|
||
subgraph Streak["🔥 Streak Tiers"]
|
||
D1["Day 1-2<br/>+0%"] --> D3["Day 3-6<br/>+10%"]
|
||
D3 --> D7["Day 7-13<br/>+25%"]
|
||
D7 --> D14["Day 14-29<br/>+50%"]
|
||
D14 --> D30["Day 30+<br/>+100%"]
|
||
end
|
||
|
||
style D1 fill:#7F8C8D,color:#ECF0F1,stroke:#5D6D7E,stroke-width:2px
|
||
style D3 fill:#3498DB,color:#ECF0F1,stroke:#2980B9,stroke-width:2px
|
||
style D7 fill:#8E44AD,color:#ECF0F1,stroke:#7D3C98,stroke-width:2px
|
||
style D14 fill:#E67E22,color:#ECF0F1,stroke:#D35400,stroke-width:2px
|
||
style D30 fill:#C0392B,color:#ECF0F1,stroke:#A93226,stroke-width:3px
|
||
```
|
||
|
||
#### Streak Mechanics
|
||
|
||
| Streak Days | Bonus | Milestone Reward |
|
||
|-------------|-------|------------------|
|
||
| Day 1-2 | +0% | - |
|
||
| Day 3-6 | +10% | 🎁 3-day badge |
|
||
| Day 7-13 | +25% | 🎁 7-day badge + 50 MP bonus |
|
||
| Day 14-29 | +50% | 🎁 14-day badge + 100 MP bonus |
|
||
| Day 30-59 | +100% | 🔥 30-day badge + 300 MP bonus |
|
||
| Day 60-89 | +125% | 🏆 60-day badge + 500 MP bonus |
|
||
| Day 90+ | +150% | 👑 90-day badge + 1000 MP bonus |
|
||
|
||
#### Streak Protection Rules
|
||
|
||
- **Grace Period**: Miss 1 day → streak pauses (not reset)
|
||
- **Streak Freeze**: Use 1 Freeze Token to protect streak (earn 1 token per 7-day streak)
|
||
- **Streak Recovery**: Within 24h of missing → pay 50 MP to restore streak
|
||
- **Maximum Streak**: Unlimited (displayed on leaderboard)
|
||
|
||
#### Streak Value Object
|
||
|
||
```csharp
|
||
/// Streak tracking for consecutive mining
|
||
public record MiningStreak(
|
||
int CurrentStreak, // Current consecutive days
|
||
int LongestStreak, // Personal best
|
||
DateTime LastMiningDate, // Last successful claim
|
||
int FreezeTokens, // Available streak protections
|
||
bool IsGracePeriod, // Currently in grace period
|
||
decimal BonusMultiplier // Current streak bonus
|
||
);
|
||
```
|
||
|
||
---
|
||
|
||
### Mining Rate Formula
|
||
|
||
```
|
||
Total Mining Rate = Base Rate × (1 + Role) × (1 + Circle) × (1 + Referral) × (1 + Streak)
|
||
|
||
Where:
|
||
- Base Rate: 0.25 MP/hour (configurable)
|
||
- Role Multiplier: Pioneer=0%, Contributor=10%, Ambassador=25%, Node=50%
|
||
- Circle Bonus: 25% if valid circle (3-5 trusted members)
|
||
- Referral Bonus: 25% per active direct referral (capped at 100%)
|
||
- Streak Bonus: 0-150% based on consecutive daily mining
|
||
```
|
||
|
||
**Example with Streak:**
|
||
| Component | Value | Multiplier |
|
||
|-----------|-------|------------|
|
||
| Base Rate | 0.25 MP/hour | - |
|
||
| Role (Ambassador) | +25% | × 1.25 |
|
||
| Valid Circle | +25% | × 1.25 |
|
||
| 2 Referrals | +50% | × 1.50 |
|
||
| 30-Day Streak | +100% | × 2.00 |
|
||
| **Total** | **1.17 MP/hour** | **28.12 MP/day** |
|
||
|
||
### Mining Session Flow
|
||
|
||
```mermaid
|
||
%%{init: {'theme':'dark'}}%%
|
||
sequenceDiagram
|
||
participant U as 📱 User
|
||
participant A as 🌐 Mining API
|
||
participant M as ⚙️ MinerAggregate
|
||
participant R as 🧮 RateCalculator
|
||
participant DB as 💾 PostgreSQL
|
||
participant C as ⚡ Redis Cache
|
||
|
||
U->>A: POST /api/v1/mining/start
|
||
A->>M: StartMiningSession()
|
||
M->>R: CalculateMiningRate()
|
||
R-->>M: MiningRate
|
||
M->>M: CreateSession(24h duration)
|
||
M->>DB: SaveSession()
|
||
M->>C: CacheSessionInfo()
|
||
A-->>U: 200 OK { session_id, rate, end_time }
|
||
|
||
Note over U: 24 hours later...
|
||
|
||
U->>A: POST /api/v1/mining/claim
|
||
A->>M: ClaimMiningReward()
|
||
M->>M: CalculateEarnedPoints()
|
||
M->>M: AddToTotalPoints()
|
||
M->>DB: SaveMiningHistory()
|
||
A-->>U: 200 OK { earned_points, total_points }
|
||
```
|
||
|
||
### User Roles & Benefits
|
||
|
||
| Role | Requirements | Mining Bonus | Benefits |
|
||
|------|--------------|--------------|----------|
|
||
| **Pioneer** | Sign up | 0% | Basic mining |
|
||
| **Contributor** | Valid security circle (3+ members) | +10% | Circle bonus active |
|
||
| **Ambassador** | 5+ active referrals | +25% | Referral bonus cap increased |
|
||
| **Node Operator** | Run node software (future) | +50% | Network rewards |
|
||
|
||
---
|
||
|
||
## API Endpoints
|
||
|
||
### Mining APIs
|
||
|
||
| Method | Endpoint | Description |
|
||
|--------|----------|-------------|
|
||
| `GET` | `/api/v1/mining/me` | Get current mining status |
|
||
| `POST` | `/api/v1/mining/start` | Start 24-hour mining session |
|
||
| `POST` | `/api/v1/mining/claim` | Claim mining rewards |
|
||
| `GET` | `/api/v1/mining/history` | Get mining history |
|
||
| `GET` | `/api/v1/mining/rate` | Get current mining rate breakdown |
|
||
| `GET` | `/api/v1/mining/leaderboard` | Get top miners leaderboard |
|
||
|
||
### Security Circle APIs
|
||
|
||
| Method | Endpoint | Description |
|
||
|--------|----------|-------------|
|
||
| `GET` | `/api/v1/circles/me` | Get my security circle |
|
||
| `POST` | `/api/v1/circles` | Create security circle |
|
||
| `POST` | `/api/v1/circles/invite` | Invite member to circle |
|
||
| `POST` | `/api/v1/circles/accept/{inviteId}` | Accept circle invitation |
|
||
| `DELETE` | `/api/v1/circles/members/{memberId}` | Remove circle member |
|
||
| `GET` | `/api/v1/circles/trust-score` | Get circle trust score |
|
||
|
||
### Referral APIs
|
||
|
||
| Method | Endpoint | Description |
|
||
|--------|----------|-------------|
|
||
| `GET` | `/api/v1/referrals/code` | Get my referral code |
|
||
| `GET` | `/api/v1/referrals` | List my referrals |
|
||
| `GET` | `/api/v1/referrals/stats` | Get referral statistics |
|
||
| `POST` | `/api/v1/referrals/apply` | Apply referral code (during signup) |
|
||
|
||
### Admin Backoffice APIs
|
||
|
||
#### 🔧 Configuration Management
|
||
|
||
| Method | Endpoint | Description |
|
||
|--------|----------|-------------|
|
||
| `GET` | `/api/v1/admin/config` | Get all system configuration |
|
||
| `PUT` | `/api/v1/admin/config` | Update system configuration |
|
||
| `GET` | `/api/v1/admin/config/mining` | Get mining configuration |
|
||
| `PUT` | `/api/v1/admin/config/mining` | Update mining rates |
|
||
| `GET` | `/api/v1/admin/config/streak` | Get streak configuration |
|
||
| `PUT` | `/api/v1/admin/config/streak` | Update streak bonuses |
|
||
| `GET` | `/api/v1/admin/config/referral` | Get referral configuration |
|
||
| `PUT` | `/api/v1/admin/config/referral` | Update referral bonuses |
|
||
|
||
#### 👥 User Management
|
||
|
||
| Method | Endpoint | Description |
|
||
|--------|----------|-------------|
|
||
| `GET` | `/api/v1/admin/miners` | List all miners (paginated) |
|
||
| `GET` | `/api/v1/admin/miners/{id}` | Get miner details |
|
||
| `PUT` | `/api/v1/admin/miners/{id}/suspend` | Suspend miner |
|
||
| `PUT` | `/api/v1/admin/miners/{id}/ban` | Ban miner |
|
||
| `PUT` | `/api/v1/admin/miners/{id}/restore` | Restore suspended miner |
|
||
| `PUT` | `/api/v1/admin/miners/{id}/adjust-points` | Adjust miner points |
|
||
| `PUT` | `/api/v1/admin/miners/{id}/reset-streak` | Reset miner streak |
|
||
|
||
#### 📊 Analytics & Reports
|
||
|
||
| Method | Endpoint | Description |
|
||
|--------|----------|-------------|
|
||
| `GET` | `/api/v1/admin/analytics/overview` | Dashboard overview stats |
|
||
| `GET` | `/api/v1/admin/analytics/miners` | Miner statistics |
|
||
| `GET` | `/api/v1/admin/analytics/circles` | Circle statistics |
|
||
| `GET` | `/api/v1/admin/analytics/referrals` | Referral network stats |
|
||
| `GET` | `/api/v1/admin/analytics/points` | Points statistics |
|
||
| `GET` | `/api/v1/admin/analytics/streaks` | Streak distribution |
|
||
| `GET` | `/api/v1/admin/audit-logs` | View configuration change logs |
|
||
|
||
---
|
||
|
||
## Admin Configuration Entity
|
||
|
||
### MiningConfiguration Aggregate
|
||
|
||
```mermaid
|
||
%%{init: {'theme':'dark'}}%%
|
||
classDiagram
|
||
class MiningConfiguration {
|
||
+Guid Id
|
||
+decimal BaseRate
|
||
+int SessionDurationHours
|
||
+bool IsGloballyEnabled
|
||
+DateTime UpdatedAt
|
||
+Guid UpdatedBy
|
||
}
|
||
|
||
class StreakConfiguration {
|
||
+Guid Id
|
||
+List~StreakTier~ Tiers
|
||
+bool GracePeriodEnabled
|
||
+int GracePeriodHours
|
||
+decimal RecoveryCost
|
||
+int FreezeTokenDays
|
||
}
|
||
|
||
class StreakTier {
|
||
+int MinDays
|
||
+int MaxDays
|
||
+decimal BonusPercent
|
||
+string BadgeName
|
||
+decimal MilestoneMpBonus
|
||
}
|
||
|
||
class ReferralConfiguration {
|
||
+Guid Id
|
||
+decimal BonusPercentPerReferral
|
||
+decimal MaxBonusPercent
|
||
+bool KycRequired
|
||
+int MaxReferralLevels
|
||
}
|
||
|
||
class CircleConfiguration {
|
||
+Guid Id
|
||
+int MinMembers
|
||
+int MaxMembers
|
||
+decimal ValidCircleBonus
|
||
}
|
||
|
||
MiningConfiguration --> StreakConfiguration
|
||
MiningConfiguration --> ReferralConfiguration
|
||
MiningConfiguration --> CircleConfiguration
|
||
StreakConfiguration --> "*" StreakTier
|
||
```
|
||
|
||
### Configuration Value Objects
|
||
|
||
```csharp
|
||
/// System-wide mining configuration (admin-editable)
|
||
public record MiningConfig(
|
||
decimal BaseRate, // Default: 0.25 MP/hour
|
||
int SessionDurationHours, // Default: 24
|
||
bool IsGloballyEnabled // Emergency kill switch
|
||
);
|
||
|
||
/// Streak tiers configuration (admin-editable)
|
||
public record StreakConfig(
|
||
List<StreakTierConfig> Tiers,
|
||
bool GracePeriodEnabled, // Default: true
|
||
int GracePeriodHours, // Default: 24
|
||
decimal RecoveryCostMp, // Default: 50
|
||
int FreezeTokenEarnDays // Default: 7
|
||
);
|
||
|
||
public record StreakTierConfig(
|
||
int MinDays,
|
||
int MaxDays,
|
||
decimal BonusPercent,
|
||
string BadgeName,
|
||
decimal MilestoneMpBonus
|
||
);
|
||
|
||
/// Referral configuration (admin-editable)
|
||
public record ReferralConfig(
|
||
decimal BonusPercentPerReferral, // Default: 25%
|
||
decimal MaxBonusPercent, // Default: 100%
|
||
bool KycRequired, // Default: true
|
||
int MaxReferralLevels // Default: 1
|
||
);
|
||
|
||
/// Circle configuration (admin-editable)
|
||
public record CircleConfig(
|
||
int MinMembers, // Default: 3
|
||
int MaxMembers, // Default: 5
|
||
decimal ValidCircleBonus // Default: 25%
|
||
);
|
||
```
|
||
|
||
### Admin Configuration Flow
|
||
|
||
```mermaid
|
||
%%{init: {'theme':'dark'}}%%
|
||
sequenceDiagram
|
||
participant Admin as 🔐 Admin Backoffice
|
||
participant API as 🌐 Mining API
|
||
participant Config as ⚙️ ConfigService
|
||
participant Cache as ⚡ Redis
|
||
participant DB as 💾 PostgreSQL
|
||
participant MQ as 📨 RabbitMQ
|
||
|
||
Admin->>API: PUT /api/v1/admin/config/streak
|
||
API->>Config: UpdateStreakConfig(newConfig)
|
||
Config->>DB: SaveConfiguration()
|
||
Config->>Cache: InvalidateConfigCache()
|
||
Config->>MQ: Publish ConfigUpdatedEvent
|
||
Config->>DB: SaveAuditLog(adminId, changes)
|
||
API-->>Admin: 200 OK { updated_config }
|
||
|
||
Note over Cache: All miners will use<br/>new config on next claim
|
||
```
|
||
|
||
### Default Configuration Values
|
||
|
||
| Category | Parameter | Default | Description |
|
||
|----------|-----------|---------|-------------|
|
||
| **Mining** | Base Rate | 0.25 MP/hour | Points earned per hour |
|
||
| **Mining** | Session Duration | 24 hours | Mining session length |
|
||
| **Mining** | Global Enabled | true | Emergency kill switch |
|
||
| **Streak** | Day 3-6 Bonus | 10% | Early streak bonus |
|
||
| **Streak** | Day 7-13 Bonus | 25% | Week streak bonus |
|
||
| **Streak** | Day 14-29 Bonus | 50% | 2-week streak bonus |
|
||
| **Streak** | Day 30-59 Bonus | 100% | Month streak bonus |
|
||
| **Streak** | Day 60-89 Bonus | 125% | 2-month streak bonus |
|
||
| **Streak** | Day 90+ Bonus | 150% | Max streak bonus |
|
||
| **Streak** | Grace Period | 24 hours | Time before streak loss |
|
||
| **Streak** | Recovery Cost | 50 MP | Cost to restore streak |
|
||
| **Streak** | Freeze Token Days | 7 | Days to earn freeze token |
|
||
| **Referral** | Bonus Per Referral | 25% | Rate increase per referral |
|
||
| **Referral** | Max Bonus | 100% | Maximum referral bonus |
|
||
| **Referral** | KYC Required | true | Require KYC for bonus |
|
||
| **Circle** | Min Members | 3 | Minimum for valid circle |
|
||
| **Circle** | Max Members | 5 | Maximum circle size |
|
||
| **Circle** | Valid Circle Bonus | 25% | Bonus for valid circle |
|
||
|
||
### Audit Logging
|
||
|
||
All admin configuration changes are logged:
|
||
|
||
```csharp
|
||
public record ConfigAuditLog(
|
||
Guid Id,
|
||
Guid AdminUserId,
|
||
string ConfigType, // "Mining" | "Streak" | "Referral" | "Circle"
|
||
string PreviousValue, // JSON of old config
|
||
string NewValue, // JSON of new config
|
||
string Reason, // Admin's reason for change
|
||
DateTime CreatedAt,
|
||
string IpAddress
|
||
);
|
||
```
|
||
|
||
---
|
||
|
||
## Integration Points
|
||
|
||
### Service Dependencies
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────────────────────┐
|
||
│ Mining Service │
|
||
├─────────────────────────────────────────────────────────────────────┤
|
||
│ │
|
||
│ ┌──────────────┐ Authenticates ┌──────────────────────┐ │
|
||
│ │ │◄────────────────────────│ IAM Service │ │
|
||
│ │ │ │ - User validation │ │
|
||
│ │ │ │ - JWT tokens │ │
|
||
│ │ │ └──────────────────────┘ │
|
||
│ │ │ │
|
||
│ │ Mining │ Point Conversion ┌──────────────────────┐ │
|
||
│ │ Service │────────────────────────►│ Wallet Service │ │
|
||
│ │ │ │ - Convert MP to LP │ │
|
||
│ │ │ │ - Transaction │ │
|
||
│ │ │ └──────────────────────┘ │
|
||
│ │ │ │
|
||
│ │ │ Social Graph ┌──────────────────────┐ │
|
||
│ │ │◄───────────────────────►│ Social Service │ │
|
||
│ │ │ │ - Friend list │ │
|
||
│ │ │ │ - Trust validation │ │
|
||
│ └──────────────┘ └──────────────────────┘ │
|
||
│ │
|
||
└─────────────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
### Integration Events (RabbitMQ)
|
||
|
||
| Event | Publisher | Consumer(s) | Description |
|
||
|-------|-----------|-------------|-------------|
|
||
| `MinerCreatedEvent` | Mining Service | IAM Service | New miner profile created |
|
||
| `MiningSessionStartedEvent` | Mining Service | - | Mining session started |
|
||
| `PointsMinedEvent` | Mining Service | Wallet Service | Points claimed, sync to wallet |
|
||
| `CircleCompletedEvent` | Mining Service | - | Security circle became valid |
|
||
| `ReferralActivatedEvent` | Mining Service | - | Referral became active |
|
||
| `UserRegisteredEvent` | IAM Service | Mining Service | Create miner profile |
|
||
| `FriendAddedEvent` | Social Service | Mining Service | Update circle suggestions |
|
||
|
||
---
|
||
|
||
## Tech Stack
|
||
|
||
| Component | Technology | Purpose |
|
||
|-----------|------------|---------|
|
||
| **Framework** | .NET 10 | Latest LTS framework |
|
||
| **API Layer** | Controllers + MediatR | REST endpoints with CQRS pattern |
|
||
| **Database** | PostgreSQL + EF Core 10 | Persistent storage with migrations |
|
||
| **Caching** | Redis + HybridCache | L1+L2 caching with stampede protection |
|
||
| **Real-time** | SignalR | Live MP updates, session notifications |
|
||
| **Message Queue** | RabbitMQ (MassTransit) | Integration events between services |
|
||
| **Validation** | FluentValidation | Request validation pipeline |
|
||
| **API Docs** | Swagger/OpenAPI | API documentation |
|
||
| **Logging** | Serilog | Structured logging |
|
||
| **Observability** | Prometheus + Grafana | Metrics and dashboards |
|
||
|
||
---
|
||
|
||
## Implementation Notes
|
||
|
||
### 1. HybridCache cho Mining Rate (Stampede Protection)
|
||
|
||
```mermaid
|
||
%%{init: {'theme':'dark'}}%%
|
||
sequenceDiagram
|
||
participant R1 as 📱 Request 1
|
||
participant R2 as 📱 Request 2
|
||
participant R3 as 📱 Request 3
|
||
participant HC as 🔄 HybridCache
|
||
participant DB as 💾 PostgreSQL
|
||
|
||
Note over R1,R3: Stampede Protection
|
||
R1->>HC: GetMiningRate(userId)
|
||
R2->>HC: GetMiningRate(userId)
|
||
R3->>HC: GetMiningRate(userId)
|
||
HC->>DB: Single DB query
|
||
DB-->>HC: MiningRate data
|
||
HC-->>R1: cached result
|
||
HC-->>R2: cached result
|
||
HC-->>R3: cached result
|
||
```
|
||
|
||
**Lợi ích:** Ngăn quá tải DB khi hàng nghìn user claim cùng lúc.
|
||
|
||
```csharp
|
||
// Configure HybridCache in Program.cs
|
||
builder.Services.AddHybridCache(options =>
|
||
{
|
||
options.DefaultEntryOptions = new HybridCacheEntryOptions
|
||
{
|
||
LocalCacheExpiration = TimeSpan.FromMinutes(5),
|
||
Expiration = TimeSpan.FromMinutes(30)
|
||
};
|
||
});
|
||
```
|
||
|
||
### 2. SignalR cho Real-time Updates
|
||
|
||
```csharp
|
||
// Mining Hub for real-time MP updates
|
||
public class MiningHub : Hub
|
||
{
|
||
public async Task JoinMinerGroup(Guid minerId)
|
||
{
|
||
await Groups.AddToGroupAsync(Context.ConnectionId, $"miner:{minerId}");
|
||
}
|
||
}
|
||
|
||
// Notify user of MP update
|
||
await _hubContext.Clients.Group($"miner:{minerId}")
|
||
.SendAsync("PointsUpdated", new { earnedPoints, totalPoints, streakDays });
|
||
```
|
||
|
||
**Stateful Reconnect:** Giúp trải nghiệm mượt mà khi mạng chập chờn.
|
||
|
||
### 3. EF Core Concurrency Handling
|
||
|
||
**Quan trọng cho cập nhật số dư điểm:**
|
||
|
||
```csharp
|
||
public class Miner : Entity
|
||
{
|
||
public decimal TotalMinedPoints { get; private set; }
|
||
|
||
// Concurrency token
|
||
[Timestamp]
|
||
public byte[] RowVersion { get; set; }
|
||
}
|
||
|
||
// Handle concurrent point additions
|
||
try
|
||
{
|
||
miner.AddPoints(earnedPoints);
|
||
await _unitOfWork.SaveChangesAsync();
|
||
}
|
||
catch (DbUpdateConcurrencyException)
|
||
{
|
||
await _context.Entry(miner).ReloadAsync();
|
||
miner.AddPoints(earnedPoints);
|
||
await _unitOfWork.SaveChangesAsync();
|
||
}
|
||
```
|
||
|
||
### 4. Background Tasks
|
||
|
||
```csharp
|
||
// Daily streak processing
|
||
public class StreakProcessingService : BackgroundService
|
||
{
|
||
protected override async Task ExecuteAsync(CancellationToken ct)
|
||
{
|
||
while (!ct.IsCancellationRequested)
|
||
{
|
||
await ProcessExpiredStreaksAsync();
|
||
await AwardMilestoneRewardsAsync();
|
||
await Task.Delay(TimeSpan.FromHours(1), ct);
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
### 5. Architecture Checklist
|
||
|
||
- [x] Controllers + MediatR for CQRS pattern
|
||
- [x] FluentValidation with ValidatorBehavior
|
||
- [x] HybridCache với stampede protection
|
||
- [x] SignalR với Stateful Reconnect cho real-time updates
|
||
- [x] EF Core concurrency handling cho point balance
|
||
- [x] BackgroundService cho streak/session processing
|
||
- [x] Domain Events + MassTransit cho integration events
|
||
|
||
---
|
||
|
||
## Configuration
|
||
|
||
### Environment Variables
|
||
|
||
| Variable | Description | Required | Default |
|
||
|----------|-------------|----------|---------|
|
||
| `DATABASE_URL` | PostgreSQL connection | Yes | - |
|
||
| `REDIS_URL` | Redis connection | Yes | - |
|
||
| `RABBITMQ_URL` | RabbitMQ connection | Yes | - |
|
||
| `JWT_AUTHORITY` | JWT issuer URL | Yes | - |
|
||
| `MINING_BASE_RATE` | Base mining rate (MP/hour) | No | 0.25 |
|
||
| `MINING_SESSION_HOURS` | Session duration | No | 24 |
|
||
| `CIRCLE_MIN_MEMBERS` | Minimum circle members | No | 3 |
|
||
| `CIRCLE_MAX_MEMBERS` | Maximum circle members | No | 5 |
|
||
| `REFERRAL_BONUS_PERCENT` | Bonus per referral | No | 25 |
|
||
| `REFERRAL_BONUS_CAP` | Max referral bonus | No | 100 |
|
||
|
||
---
|
||
|
||
## Security Considerations
|
||
|
||
### Anti-Fraud Measures
|
||
|
||
1. **Rate Limiting** - Max 1 mining session start per 24 hours
|
||
2. **Device Fingerprint** - Track device changes, flag suspicious activity
|
||
3. **IP Monitoring** - Detect multiple accounts from same IP
|
||
4. **Circle Validation** - Members must be real, active users
|
||
5. **Referral Verification** - Referrals must pass KYC to activate bonus
|
||
6. **Activity Scoring** - Penalize inactive or bot-like patterns
|
||
|
||
### Data Protection
|
||
|
||
- Mining history encrypted at rest
|
||
- Personal data follows GDPR compliance
|
||
- Audit logs for all admin actions
|
||
|
||
---
|
||
|
||
## Roadmap
|
||
|
||
### Phase 1: Core Mining (MVP)
|
||
- [x] Miner profile creation
|
||
- [x] Daily tap-to-mine sessions
|
||
- [x] Basic mining rate calculation
|
||
- [x] Mining history
|
||
|
||
### Phase 2: Social Features
|
||
- [ ] Security circles
|
||
- [ ] Referral system
|
||
- [ ] Circle bonus calculation
|
||
|
||
### Phase 3: Advanced Features
|
||
- [ ] User role progression
|
||
- [ ] Point conversion to wallet
|
||
- [ ] Leaderboards
|
||
|
||
### Phase 4: Node Network (Future)
|
||
- [ ] Node operator role
|
||
- [ ] Decentralized validation
|
||
- [ ] Network rewards
|
||
|
||
---
|
||
|
||
## Resources
|
||
|
||
- [Architecture Documentation](./ARCHITECTURE.md)
|
||
- [GoodGo Platform Docs](../../docs/)
|
||
- [Pi Network Whitepaper](https://minepi.com/white-paper) (Inspiration)
|
||
- [Wallet Service Integration](../wallet-service-net/)
|
||
|
||
## License
|
||
|
||
Proprietary - GoodGo Platform
|