rwadurian/backend/services/contribution-service/prisma/schema.prisma

380 lines
13 KiB
Plaintext

generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
// ============================================
// CDC 同步数据表(从其他服务同步)
// ============================================
// 同步的用户数据
model SyncedUser {
id BigInt @id @default(autoincrement())
accountSequence String @unique @map("account_sequence") @db.VarChar(20)
originalUserId BigInt @map("original_user_id")
phone String? @db.VarChar(20)
status String? @db.VarChar(20)
// CDC 同步元数据
sourceSequenceNum BigInt @map("source_sequence_num")
syncedAt DateTime @default(now()) @map("synced_at")
// 算力计算状态
contributionCalculated Boolean @default(false) @map("contribution_calculated")
contributionCalculatedAt DateTime? @map("contribution_calculated_at")
createdAt DateTime @default(now()) @map("created_at")
@@map("synced_users")
@@index([originalUserId])
@@index([contributionCalculated])
}
// 同步的认种数据
model SyncedAdoption {
id BigInt @id @default(autoincrement())
originalAdoptionId BigInt @unique @map("original_adoption_id")
accountSequence String @map("account_sequence") @db.VarChar(20)
treeCount Int @map("tree_count")
adoptionDate DateTime @map("adoption_date") @db.Date
status String? @db.VarChar(20)
// 贡献值计算参数(从认种时的配置)
contributionPerTree Decimal @map("contribution_per_tree") @db.Decimal(20, 10)
// CDC 同步元数据
sourceSequenceNum BigInt @map("source_sequence_num")
syncedAt DateTime @default(now()) @map("synced_at")
// 算力分配状态
contributionDistributed Boolean @default(false) @map("contribution_distributed")
contributionDistributedAt DateTime? @map("contribution_distributed_at")
createdAt DateTime @default(now()) @map("created_at")
@@map("synced_adoptions")
@@index([accountSequence])
@@index([adoptionDate])
@@index([contributionDistributed])
}
// 同步的推荐关系数据
model SyncedReferral {
id BigInt @id @default(autoincrement())
accountSequence String @unique @map("account_sequence") @db.VarChar(20)
referrerAccountSequence String? @map("referrer_account_sequence") @db.VarChar(20)
// 预计算的层级路径(便于快速查询上下级)
ancestorPath String? @map("ancestor_path") @db.Text
depth Int @default(0)
// CDC 同步元数据
sourceSequenceNum BigInt @map("source_sequence_num")
syncedAt DateTime @default(now()) @map("synced_at")
createdAt DateTime @default(now()) @map("created_at")
@@map("synced_referrals")
@@index([referrerAccountSequence])
}
// ============================================
// 算力账户与明细表
// ============================================
// 算力账户表(汇总)
model ContributionAccount {
id BigInt @id @default(autoincrement())
accountSequence String @unique @map("account_sequence") @db.VarChar(20)
// 算力汇总
personalContribution Decimal @default(0) @map("personal_contribution") @db.Decimal(30, 10)
teamLevelContribution Decimal @default(0) @map("team_level_contribution") @db.Decimal(30, 10)
teamBonusContribution Decimal @default(0) @map("team_bonus_contribution") @db.Decimal(30, 10)
totalContribution Decimal @default(0) @map("total_contribution") @db.Decimal(30, 10)
effectiveContribution Decimal @default(0) @map("effective_contribution") @db.Decimal(30, 10)
// 用户条件(决定能获得多少团队算力)
hasAdopted Boolean @default(false) @map("has_adopted")
directReferralAdoptedCount Int @default(0) @map("direct_referral_adopted_count")
// 解锁状态
unlockedLevelDepth Int @default(0) @map("unlocked_level_depth")
unlockedBonusTiers Int @default(0) @map("unlocked_bonus_tiers")
// 乐观锁
version Int @default(1)
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
@@map("contribution_accounts")
@@index([totalContribution(sort: Desc)])
@@index([effectiveContribution(sort: Desc)])
}
// 算力明细表(分类账)
model ContributionRecord {
id BigInt @id @default(autoincrement())
accountSequence String @map("account_sequence") @db.VarChar(20)
// 来源信息(可追溯)
sourceType String @map("source_type") @db.VarChar(30) // PERSONAL / TEAM_LEVEL / TEAM_BONUS
sourceAdoptionId BigInt @map("source_adoption_id")
sourceAccountSequence String @map("source_account_sequence") @db.VarChar(20)
// 计算参数(审计用)
treeCount Int @map("tree_count")
baseContribution Decimal @map("base_contribution") @db.Decimal(20, 10)
distributionRate Decimal @map("distribution_rate") @db.Decimal(10, 6)
levelDepth Int? @map("level_depth")
bonusTier Int? @map("bonus_tier")
// 结果
amount Decimal @map("amount") @db.Decimal(30, 10)
// 有效期
effectiveDate DateTime @map("effective_date") @db.Date
expireDate DateTime @map("expire_date") @db.Date
isExpired Boolean @default(false) @map("is_expired")
expiredAt DateTime? @map("expired_at")
createdAt DateTime @default(now()) @map("created_at")
@@map("contribution_records")
@@index([accountSequence, createdAt(sort: Desc)])
@@index([sourceAdoptionId])
@@index([sourceAccountSequence])
@@index([sourceType])
@@index([expireDate])
@@index([isExpired])
}
// 未分配算力记录(归总部)
model UnallocatedContribution {
id BigInt @id @default(autoincrement())
sourceAdoptionId BigInt @map("source_adoption_id")
sourceAccountSequence String @map("source_account_sequence") @db.VarChar(20)
unallocType String @map("unalloc_type") @db.VarChar(30) // LEVEL_OVERFLOW / BONUS_TIER_1/2/3
wouldBeAccountSequence String? @map("would_be_account_sequence") @db.VarChar(20)
levelDepth Int? @map("level_depth")
amount Decimal @map("amount") @db.Decimal(30, 10)
reason String? @db.VarChar(200)
// 归总部后的处理
allocatedToHeadquarters Boolean @default(false) @map("allocated_to_headquarters")
allocatedAt DateTime? @map("allocated_at")
effectiveDate DateTime @map("effective_date") @db.Date
expireDate DateTime @map("expire_date") @db.Date
createdAt DateTime @default(now()) @map("created_at")
@@map("unallocated_contributions")
@@index([sourceAdoptionId])
@@index([unallocType])
@@index([allocatedToHeadquarters])
}
// 系统账户(运营/省/市/总部)
model SystemAccount {
id BigInt @id @default(autoincrement())
accountType String @unique @map("account_type") @db.VarChar(20) // OPERATION / PROVINCE / CITY / HEADQUARTERS
name String @db.VarChar(100)
contributionBalance Decimal @default(0) @map("contribution_balance") @db.Decimal(30, 10)
contributionNeverExpires Boolean @default(false) @map("contribution_never_expires")
version Int @default(1)
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
records SystemContributionRecord[]
@@map("system_accounts")
}
// 系统账户算力明细
model SystemContributionRecord {
id BigInt @id @default(autoincrement())
systemAccountId BigInt @map("system_account_id")
sourceAdoptionId BigInt @map("source_adoption_id")
sourceAccountSequence String @map("source_account_sequence") @db.VarChar(20)
distributionRate Decimal @map("distribution_rate") @db.Decimal(10, 6)
amount Decimal @map("amount") @db.Decimal(30, 10)
effectiveDate DateTime @map("effective_date") @db.Date
expireDate DateTime? @map("expire_date") @db.Date
isExpired Boolean @default(false) @map("is_expired")
createdAt DateTime @default(now()) @map("created_at")
systemAccount SystemAccount @relation(fields: [systemAccountId], references: [id])
@@map("system_contribution_records")
@@index([systemAccountId])
@@index([sourceAdoptionId])
}
// ============================================
// 快照与统计表
// ============================================
// 每日算力快照(用于挖矿分配计算)
model DailyContributionSnapshot {
id BigInt @id @default(autoincrement())
snapshotDate DateTime @map("snapshot_date") @db.Date
accountSequence String @map("account_sequence") @db.VarChar(20)
effectiveContribution Decimal @map("effective_contribution") @db.Decimal(30, 10)
networkTotalContribution Decimal @map("network_total_contribution") @db.Decimal(30, 10)
contributionRatio Decimal @map("contribution_ratio") @db.Decimal(30, 18)
createdAt DateTime @default(now()) @map("created_at")
@@unique([snapshotDate, accountSequence])
@@map("daily_contribution_snapshots")
@@index([snapshotDate])
@@index([accountSequence])
}
// 用户团队统计(缓存,定期更新)
model UserTeamStats {
id BigInt @id @default(autoincrement())
accountSequence String @map("account_sequence") @db.VarChar(20)
statsDate DateTime @map("stats_date") @db.Date
// 各级认种统计
level1Trees Int @default(0) @map("level_1_trees")
level2Trees Int @default(0) @map("level_2_trees")
level3Trees Int @default(0) @map("level_3_trees")
level4Trees Int @default(0) @map("level_4_trees")
level5Trees Int @default(0) @map("level_5_trees")
level6Trees Int @default(0) @map("level_6_trees")
level7Trees Int @default(0) @map("level_7_trees")
level8Trees Int @default(0) @map("level_8_trees")
level9Trees Int @default(0) @map("level_9_trees")
level10Trees Int @default(0) @map("level_10_trees")
level11Trees Int @default(0) @map("level_11_trees")
level12Trees Int @default(0) @map("level_12_trees")
level13Trees Int @default(0) @map("level_13_trees")
level14Trees Int @default(0) @map("level_14_trees")
level15Trees Int @default(0) @map("level_15_trees")
totalTeamTrees Int @default(0) @map("total_team_trees")
directAdoptedReferrals Int @default(0) @map("direct_adopted_referrals")
createdAt DateTime @default(now()) @map("created_at")
@@unique([accountSequence, statsDate])
@@map("user_team_stats")
@@index([accountSequence])
@@index([statsDate])
}
// ============================================
// CDC 同步状态追踪
// ============================================
// CDC 同步进度表
model CdcSyncProgress {
id BigInt @id @default(autoincrement())
sourceTopic String @unique @map("source_topic") @db.VarChar(100)
lastSequenceNum BigInt @default(0) @map("last_sequence_num")
lastSyncedAt DateTime? @map("last_synced_at")
updatedAt DateTime @updatedAt @map("updated_at")
@@map("cdc_sync_progress")
}
// 已处理事件表(幂等性)
model ProcessedEvent {
id BigInt @id @default(autoincrement())
eventId String @unique @map("event_id") @db.VarChar(100)
eventType String @map("event_type") @db.VarChar(50)
sourceService String? @map("source_service") @db.VarChar(50)
processedAt DateTime @default(now()) @map("processed_at")
@@map("processed_events")
@@index([eventType])
@@index([processedAt])
}
// ============================================
// 配置表
// ============================================
// 贡献值递增配置
model ContributionConfig {
id BigInt @id @default(autoincrement())
baseContribution Decimal @default(22617) @map("base_contribution") @db.Decimal(20, 10)
incrementPercentage Decimal @default(0.003) @map("increment_percentage") @db.Decimal(10, 6)
unitSize Int @default(100) @map("unit_size")
startTreeNumber Int @default(1000) @map("start_tree_number")
isActive Boolean @default(true) @map("is_active")
createdAt DateTime @default(now()) @map("created_at")
@@map("contribution_configs")
@@index([isActive])
}
// 分配比例配置
model DistributionRateConfig {
id BigInt @id @default(autoincrement())
rateType String @unique @map("rate_type") @db.VarChar(30)
rateValue Decimal @map("rate_value") @db.Decimal(10, 6)
description String? @db.VarChar(100)
isActive Boolean @default(true) @map("is_active")
createdAt DateTime @default(now()) @map("created_at")
@@map("distribution_rate_configs")
@@index([isActive])
}
// ============================================
// Outbox 事件表(可靠事件发布)
// ============================================
model OutboxEvent {
id BigInt @id @default(autoincrement()) @map("outbox_id")
eventType String @map("event_type") @db.VarChar(100)
topic String @map("topic") @db.VarChar(100)
key String @map("key") @db.VarChar(200)
payload Json @map("payload")
aggregateId String @map("aggregate_id") @db.VarChar(100)
aggregateType String @map("aggregate_type") @db.VarChar(50)
status String @default("PENDING") @map("status") @db.VarChar(20)
retryCount Int @default(0) @map("retry_count")
maxRetries Int @default(5) @map("max_retries")
lastError String? @map("last_error") @db.Text
createdAt DateTime @default(now()) @map("created_at")
publishedAt DateTime? @map("published_at")
nextRetryAt DateTime? @map("next_retry_at")
@@map("outbox_events")
@@index([status, createdAt])
@@index([status, nextRetryAt])
@@index([aggregateType, aggregateId])
@@index([topic])
}