380 lines
13 KiB
Plaintext
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])
|
|
}
|