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")

  @@index([originalUserId])
  @@index([contributionCalculated])
  @@map("synced_users")
}

// 同步的认种数据
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(30) // 与1.0 planting_orders.status保持一致

  // 认种选择的省市（用于系统账户分配）
  selectedProvince String? @map("selected_province") @db.VarChar(10)
  selectedCity     String? @map("selected_city") @db.VarChar(10)

  // 贡献值计算参数（从认种时的配置）
  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")

  // 分配明细摘要 (JSON 字符串格式)
  // 格式: { personal: {rate, amount}, operation: {rate, amount}, province: {rate, amount}, city: {rate, amount}, team: {rate, amount, distributed, unallocated} }
  distributionSummary String? @map("distribution_summary") @db.Text

  createdAt DateTime @default(now()) @map("created_at")

  @@index([accountSequence])
  @@index([adoptionDate])
  @@index([contributionDistributed])
  @@index([selectedProvince, selectedCity])
  @@map("synced_adoptions")
}

// 同步的推荐关系数据
model SyncedReferral {
  id                      BigInt  @id @default(autoincrement())
  accountSequence         String  @unique @map("account_sequence") @db.VarChar(20)
  // 推荐人信息：优先使用 account_sequence，但也保存 user_id 以便后续解析
  referrerAccountSequence String? @map("referrer_account_sequence") @db.VarChar(20)
  referrerUserId          BigInt? @map("referrer_user_id") // 1.0 的 referrer_id
  originalUserId          BigInt? @map("original_user_id") // 1.0 的 user_id

  // 预计算的层级路径（便于快速查询上下级）
  // 1.0 存储的是 BigInt[]，这里转换为逗号分隔的字符串
  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")

  @@index([referrerAccountSequence])
  @@index([referrerUserId])
  @@index([originalUserId])
  @@map("synced_referrals")
}

// ============================================
// 算力账户与明细表
// ============================================

// 算力账户表（汇总）
// 设计说明：
// - 个人算力：自己认种，立即生效
// - 层级算力：下级1-15层认种的分成，每层0.5%，共7.5%
// - 加成算力：团队加成，3档各2.5%，共7.5%
// 解锁规则：
// - 自己认种：解锁层级1-5 + 加成第1档
// - 直推≥2人认种：解锁加成第2档
// - 直推≥3人认种：解锁层级6-10
// - 直推≥4人认种：解锁加成第3档
// - 直推≥5人认种：解锁层级11-15
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)

  // ========== 15级层级算力（待解锁/已解锁）==========
  // 每级0.5%，分三档解锁
  // 第1档(1-5级)：自己认种解锁
  level1Pending  Decimal @default(0) @map("level_1_pending") @db.Decimal(30, 10)
  level2Pending  Decimal @default(0) @map("level_2_pending") @db.Decimal(30, 10)
  level3Pending  Decimal @default(0) @map("level_3_pending") @db.Decimal(30, 10)
  level4Pending  Decimal @default(0) @map("level_4_pending") @db.Decimal(30, 10)
  level5Pending  Decimal @default(0) @map("level_5_pending") @db.Decimal(30, 10)
  // 第2档(6-10级)：直推≥3人认种解锁
  level6Pending  Decimal @default(0) @map("level_6_pending") @db.Decimal(30, 10)
  level7Pending  Decimal @default(0) @map("level_7_pending") @db.Decimal(30, 10)
  level8Pending  Decimal @default(0) @map("level_8_pending") @db.Decimal(30, 10)
  level9Pending  Decimal @default(0) @map("level_9_pending") @db.Decimal(30, 10)
  level10Pending Decimal @default(0) @map("level_10_pending") @db.Decimal(30, 10)
  // 第3档(11-15级)：直推≥5人认种解锁
  level11Pending Decimal @default(0) @map("level_11_pending") @db.Decimal(30, 10)
  level12Pending Decimal @default(0) @map("level_12_pending") @db.Decimal(30, 10)
  level13Pending Decimal @default(0) @map("level_13_pending") @db.Decimal(30, 10)
  level14Pending Decimal @default(0) @map("level_14_pending") @db.Decimal(30, 10)
  level15Pending Decimal @default(0) @map("level_15_pending") @db.Decimal(30, 10)

  // ========== 3档加成算力（待解锁）==========
  // 每档2.5%
  bonusTier1Pending Decimal @default(0) @map("bonus_tier_1_pending") @db.Decimal(30, 10) // 自己认种解锁
  bonusTier2Pending Decimal @default(0) @map("bonus_tier_2_pending") @db.Decimal(30, 10) // 直推≥2人认种解锁
  bonusTier3Pending Decimal @default(0) @map("bonus_tier_3_pending") @db.Decimal(30, 10) // 直推≥4人认种解锁

  // ========== 汇总字段 ==========
  totalLevelPending     Decimal @default(0) @map("total_level_pending") @db.Decimal(30, 10) // sum(level1-15 pending)
  totalBonusPending     Decimal @default(0) @map("total_bonus_pending") @db.Decimal(30, 10) // sum(tier1-3 pending)
  totalPending          Decimal @default(0) @map("total_pending") @db.Decimal(30, 10) // 所有待解锁总和
  totalUnlocked         Decimal @default(0) @map("total_unlocked") @db.Decimal(30, 10) // 所有已解锁总和
  effectiveContribution Decimal @default(0) @map("effective_contribution") @db.Decimal(30, 10) // personal + unlocked

  // ========== 解锁条件状态 ==========
  hasAdopted                 Boolean @default(false) @map("has_adopted")
  directReferralAdoptedCount Int     @default(0) @map("direct_referral_adopted_count")

  // 解锁深度：0=未解锁, 5=第1档, 10=第2档, 15=全部解锁
  unlockedLevelDepth Int @default(0) @map("unlocked_level_depth")
  // 解锁加成档位：0=未解锁, 1/2/3=对应档位
  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")

  @@index([effectiveContribution(sort: Desc)])
  @@index([hasAdopted])
  @@index([directReferralAdoptedCount])
  @@map("contribution_accounts")
}

// 算力明细表（分类账）
// 每笔算力变动都记录在此表，用于审计和追溯
// 状态流转：PENDING -> UNLOCKED -> EXPIRED (或直接 EFFECTIVE -> EXPIRED)
model ContributionRecord {
  id              BigInt @id @default(autoincrement())
  accountSequence String @map("account_sequence") @db.VarChar(20)

  // ========== 来源信息（可追溯）==========
  sourceType            String @map("source_type") @db.VarChar(30) // PERSONAL / LEVEL_1~15 / BONUS_TIER_1~3
  sourceAdoptionId      BigInt @map("source_adoption_id") // 来源认种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) // 分配比例 (0.005=0.5%, 0.025=2.5%)
  levelDepth       Int?    @map("level_depth") // 层级深度 (1-15)
  bonusTier        Int?    @map("bonus_tier") // 加成档位 (1-3)

  // ========== 金额 ==========
  amount Decimal @map("amount") @db.Decimal(30, 10) // 算力金额

  // ========== 解锁状态 ==========
  status       String    @default("PENDING") @map("status") @db.VarChar(20) // PENDING/UNLOCKED/EFFECTIVE
  unlockedAt   DateTime? @map("unlocked_at") // 解锁时间
  unlockReason String?   @map("unlock_reason") @db.VarChar(200) // 解锁原因描述

  // ========== 有效期 ==========
  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")

  // ========== 备注 ==========
  remark String? @map("remark") @db.VarChar(500) // 备注说明

  createdAt DateTime @default(now()) @map("created_at")

  @@index([accountSequence, status])
  @@index([accountSequence, createdAt(sort: Desc)])
  @@index([sourceAdoptionId])
  @@index([sourceAccountSequence])
  @@index([sourceType])
  @@index([status])
  @@index([expireDate])
  @@index([isExpired])
  @@map("contribution_records")
}

// 解锁事件记录表
// 记录每次解锁的触发原因，便于审计和追溯
model UnlockEvent {
  id              BigInt @id @default(autoincrement())
  accountSequence String @map("account_sequence") @db.VarChar(20) // 被解锁的账户

  // ========== 触发信息 ==========
  triggerType            String @map("trigger_type") @db.VarChar(30) // SELF_ADOPT / REFERRAL_ADOPT
  triggerAdoptionId      BigInt @map("trigger_adoption_id") // 触发认种的ID
  triggerAccountSequence String @map("trigger_account_sequence") @db.VarChar(20) // 触发认种的账户

  // ========== 解锁内容 ==========
  unlockType      String @map("unlock_type") @db.VarChar(30) // LEVEL_1_5 / LEVEL_6_10 / LEVEL_11_15 / BONUS_TIER_1 / BONUS_TIER_2 / BONUS_TIER_3
  unlockCondition String @map("unlock_condition") @db.VarChar(100) // 解锁条件描述，如 "自己认种" / "直推认种人数达到3人"

  // ========== 解锁前后状态 ==========
  beforeDirectReferralCount Int @map("before_direct_referral_count") // 解锁前直推认种人数
  afterDirectReferralCount  Int @map("after_direct_referral_count") // 解锁后直推认种人数
  beforeUnlockedLevelDepth  Int @map("before_unlocked_level_depth") // 解锁前层级深度
  afterUnlockedLevelDepth   Int @map("after_unlocked_level_depth") // 解锁后层级深度
  beforeUnlockedBonusTiers  Int @map("before_unlocked_bonus_tiers") // 解锁前加成档位
  afterUnlockedBonusTiers   Int @map("after_unlocked_bonus_tiers") // 解锁后加成档位

  // ========== 解锁金额 ==========
  unlockedAmount      Decimal @map("unlocked_amount") @db.Decimal(30, 10) // 本次解锁的算力金额
  unlockedRecordCount Int     @map("unlocked_record_count") // 本次解锁的明细记录数

  // ========== 备注 ==========
  remark String? @map("remark") @db.VarChar(500)

  createdAt DateTime @default(now()) @map("created_at")

  @@index([accountSequence])
  @@index([triggerAccountSequence])
  @@index([triggerAdoptionId])
  @@index([unlockType])
  @@index([createdAt(sort: Desc)])
  @@map("unlock_events")
}

// 未分配算力记录（归总部）
// 当上级未解锁对应层级/加成时，算力暂存于此
model UnallocatedContribution {
  id                    BigInt @id @default(autoincrement())
  sourceAdoptionId      BigInt @map("source_adoption_id") // 来源认种ID
  sourceAccountSequence String @map("source_account_sequence") @db.VarChar(20) // 认种人账号

  // ========== 未分配类型 ==========
  unallocType            String  @map("unalloc_type") @db.VarChar(30) // LEVEL_6~15_PENDING / BONUS_TIER_2_PENDING / BONUS_TIER_3_PENDING
  wouldBeAccountSequence String? @map("would_be_account_sequence") @db.VarChar(20) // 应该归属的账户
  levelDepth             Int?    @map("level_depth") // 层级深度
  bonusTier              Int?    @map("bonus_tier") // 加成档位

  amount Decimal @map("amount") @db.Decimal(30, 10)
  reason String? @db.VarChar(200) // 未分配原因

  // ========== 分配状态 ==========
  status                     String    @default("PENDING") @map("status") @db.VarChar(20) // PENDING / ALLOCATED_TO_USER / ALLOCATED_TO_HQ
  allocatedAt                DateTime? @map("allocated_at")
  allocatedToAccountSequence String?   @map("allocated_to_account_sequence") @db.VarChar(20) // 最终分配给的账户

  // ========== 有效期 ==========
  effectiveDate DateTime @map("effective_date") @db.Date
  expireDate    DateTime @map("expire_date") @db.Date

  createdAt DateTime @default(now()) @map("created_at")

  @@index([sourceAdoptionId])
  @@index([wouldBeAccountSequence])
  @@index([unallocType])
  @@index([status])
  @@map("unallocated_contributions")
}

// 系统账户（运营/省/市/总部）
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])

  @@index([systemAccountId])
  @@index([sourceAdoptionId])
  @@map("system_contribution_records")
}

// ============================================
// 快照与统计表
// ============================================

// 每日算力快照（用于挖矿分配计算）
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])
  @@index([snapshotDate])
  @@index([accountSequence])
  @@map("daily_contribution_snapshots")
}

// 用户团队统计（缓存，定期更新）
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])
  @@index([accountSequence])
  @@index([statsDate])
  @@map("user_team_stats")
}

// ============================================
// 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")
}

// 已处理 CDC 事件表（幂等性）
// 使用 (sourceTopic, offset) 作为复合唯一键
// 这是事务性幂等消费的关键：在同一事务中插入此记录 + 执行业务逻辑
model ProcessedCdcEvent {
  id          BigInt @id @default(autoincrement())
  sourceTopic String @map("source_topic") @db.VarChar(200) // CDC topic 名称
  offset      BigInt @map("offset") // Kafka offset 作为唯一标识

  tableName   String  @map("table_name") @db.VarChar(100) // 表名
  operation   String  @map("operation") @db.VarChar(10) // c/u/d/r
  processedAt DateTime @default(now()) @map("processed_at")

  @@unique([sourceTopic, offset])
  @@index([processedAt])
  @@map("processed_cdc_events")
}

// 已处理 Outbox 事件表（用于 2.0 服务间同步）
model ProcessedEvent {
  id            BigInt  @id @default(autoincrement())
  eventId       String  @map("event_id") @db.VarChar(100)
  eventType     String  @map("event_type") @db.VarChar(50)
  sourceService String  @map("source_service") @db.VarChar(100)

  processedAt DateTime @default(now()) @map("processed_at")

  @@unique([sourceService, eventId])
  @@index([eventType])
  @@index([processedAt])
  @@map("processed_events")
}

// ============================================
// 配置表
// ============================================

// 贡献值递增配置
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")

  @@index([isActive])
  @@map("contribution_configs")
}

// 分配比例配置
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")

  @@index([isActive])
  @@map("distribution_rate_configs")
}

// 全网认种进度表（单行记录，实时更新）
// 记录当前全网累计认种数量和对应的算力系数
model NetworkAdoptionProgress {
  id BigInt @id @default(autoincrement())

  // ========== 全网累计认种统计 ==========
  totalTreeCount       Int @default(0) @map("total_tree_count") // 全网累计认种棵数
  totalAdoptionOrders  Int @default(0) @map("total_adoption_orders") // 全网累计认种订单数
  totalAdoptedUsers    Int @default(0) @map("total_adopted_users") // 全网累计认种用户数

  // ========== 当前算力系数 ==========
  // 基础值: 22617 (从第1棵到第999棵)
  // 从第1000棵开始，每100棵为1个单位，每个单位递增 0.3%
  // currentMultiplier = 1 + (currentUnit * 0.003)
  // currentContributionPerTree = baseContribution * currentMultiplier
  currentUnit                Int     @default(0) @map("current_unit") // 当前单位数 (0表示还没到1000棵)
  currentMultiplier          Decimal @default(1.0) @map("current_multiplier") @db.Decimal(10, 6) // 当前系数 (1.000, 1.003, 1.006...)
  currentContributionPerTree Decimal @default(22617) @map("current_contribution_per_tree") @db.Decimal(20, 10) // 当前每棵树贡献值

  // ========== 下一个单位的触发点 ==========
  nextUnitTreeCount Int @default(1000) @map("next_unit_tree_count") // 下一个单位触发的棵数

  // ========== 最后更新信息 ==========
  lastAdoptionId        BigInt?   @map("last_adoption_id") // 最后处理的认种ID
  lastAdoptionDate      DateTime? @map("last_adoption_date") @db.Date // 最后认种日期

  updatedAt DateTime @updatedAt @map("updated_at")
  createdAt DateTime @default(now()) @map("created_at")

  @@map("network_adoption_progress")
}

// 每日算力系数快照表
// 记录每天的算力系数，确保同一天认种的用户使用相同系数
model DailyContributionRate {
  id BigInt @id @default(autoincrement())

  // ========== 日期 ==========
  effectiveDate DateTime @unique @map("effective_date") @db.Date // 生效日期

  // ========== 当日起始状态 ==========
  startTreeCount       Int     @default(0) @map("start_tree_count") // 当日开始时的全网棵数
  startUnit            Int     @default(0) @map("start_unit") // 当日开始时的单位数
  startMultiplier      Decimal @default(1.0) @map("start_multiplier") @db.Decimal(10, 6) // 当日开始时的系数
  contributionPerTree  Decimal @map("contribution_per_tree") @db.Decimal(20, 10) // 当日每棵树贡献值（同一天内不变）

  // ========== 当日结束状态 ==========
  endTreeCount         Int?     @map("end_tree_count") // 当日结束时的全网棵数
  endUnit              Int?     @map("end_unit") // 当日结束时的单位数
  endMultiplier        Decimal? @map("end_multiplier") @db.Decimal(10, 6) // 当日结束时的系数

  // ========== 当日统计 ==========
  dailyTreeCount       Int @default(0) @map("daily_tree_count") // 当日新增认种棵数
  dailyAdoptionOrders  Int @default(0) @map("daily_adoption_orders") // 当日新增认种订单数
  dailyAdoptedUsers    Int @default(0) @map("daily_adopted_users") // 当日新增认种用户数

  // ========== 状态 ==========
  isClosed Boolean @default(false) @map("is_closed") // 是否已结算（日终处理后置为true）

  createdAt DateTime @default(now()) @map("created_at")
  updatedAt DateTime @updatedAt @map("updated_at")

  @@index([effectiveDate])
  @@index([isClosed])
  @@map("daily_contribution_rates")
}

// ============================================
// 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")

  @@index([status, createdAt])
  @@index([status, nextRetryAt])
  @@index([aggregateType, aggregateId])
  @@index([topic])
  @@map("outbox_events")
}
