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]) }