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

133 lines
5.3 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// ============================================
// [2026-02-17] 预种计划独立 Prisma Schema
// ============================================
//
// 本 schema 仅包含预种计划在 contribution-service 中的追踪表。
// 与主 schema (prisma/schema.prisma) 完全隔离,拥有独立的:
// - Prisma Client生成到 src/pre-planting/infrastructure/prisma/generated/
// - Migration 目录prisma/pre-planting/migrations/
//
// 预种的算力分配结果仍然写入主 schema 的 contribution_accounts、
// contribution_records 等表(通过现有 Repository以便挖矿系统读取。
// 本 schema 仅负责预种 CDC 同步追踪、冻结状态等预种专属数据。
generator client {
provider = "prisma-client-js"
output = "../../src/pre-planting/infrastructure/prisma/generated"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
// ============================================
// 预种 CDC 同步追踪表
// ============================================
/// 预种订单同步记录(从 planting-service CDC 同步)
/// 用于追踪每笔预种订单的算力分配状态
model PrePlantingSyncedOrder {
id BigInt @id @default(autoincrement())
originalOrderId BigInt @unique @map("original_order_id")
orderNo String @map("order_no") @db.VarChar(50)
userId BigInt @map("user_id")
accountSequence String @map("account_sequence") @db.VarChar(20)
portionCount Int @map("portion_count")
pricePerPortion Decimal @map("price_per_portion") @db.Decimal(20, 8)
totalAmount Decimal @map("total_amount") @db.Decimal(20, 8)
provinceCode String @map("province_code") @db.VarChar(10)
cityCode String @map("city_code") @db.VarChar(10)
status String @map("status") @db.VarChar(20) // CREATED, PAID, MERGED
mergedToMergeId BigInt? @map("merged_to_merge_id")
paidAt DateTime? @map("paid_at")
createdAt DateTime @map("created_at")
// 算力追踪
contributionPerPortion Decimal @map("contribution_per_portion") @db.Decimal(20, 10)
contributionDistributed Boolean @default(false) @map("contribution_distributed")
contributionDistributedAt DateTime? @map("contribution_distributed_at")
// CDC 同步元数据
sourceTopic String @map("source_topic") @db.VarChar(200)
sourceOffset BigInt @map("source_offset")
syncedAt DateTime @default(now()) @map("synced_at")
@@index([accountSequence])
@@index([status])
@@index([contributionDistributed])
@@map("pre_planting_synced_orders")
}
/// 预种持仓同步记录(从 planting-service CDC 同步)
/// 用于追踪用户预种总量,判断冻结条件
model PrePlantingSyncedPosition {
id BigInt @id @default(autoincrement())
userId BigInt @unique @map("user_id")
accountSequence String @unique @map("account_sequence") @db.VarChar(20)
totalPortions Int @default(0) @map("total_portions")
mergedPortions Int @default(0) @map("merged_portions")
totalTreesMerged Int @default(0) @map("total_trees_merged")
firstPurchaseAt DateTime? @map("first_purchase_at")
// CDC 同步元数据
sourceTopic String @map("source_topic") @db.VarChar(200)
sourceOffset BigInt @map("source_offset")
syncedAt DateTime @default(now()) @map("synced_at")
@@map("pre_planting_synced_positions")
}
// ============================================
// 预种冻结状态表
// ============================================
/// 预种算力冻结状态(每用户一条)
///
/// 冻结规则:
/// - firstPurchaseAt + 1 年后仍未满 5 份 → 所有预种算力冻结(暂停分配)
/// - 后续累积满 5 份 → 解冻,恢复分配
/// - 解冻后的失效期 = 解冻日起算 + 2 年
/// - 未被冻结过的正常到期 = 首次产生挖矿收益日 + 2 年
model PrePlantingFreezeState {
id BigInt @id @default(autoincrement())
accountSequence String @unique @map("account_sequence") @db.VarChar(20)
totalPortions Int @default(0) @map("total_portions")
totalTreesMerged Int @default(0) @map("total_trees_merged")
firstPurchaseAt DateTime? @map("first_purchase_at")
// 冻结状态
isFrozen Boolean @default(false) @map("is_frozen")
frozenAt DateTime? @map("frozen_at")
unfrozenAt DateTime? @map("unfrozen_at")
// 解冻后的过期日期(解冻日 + 2 年)
postUnfreezeExpireDate DateTime? @map("post_unfreeze_expire_date")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
@@index([isFrozen])
@@index([firstPurchaseAt])
@@map("pre_planting_freeze_states")
}
// ============================================
// 预种 CDC 幂等性追踪表
// ============================================
/// 已处理的预种 CDC 事件(幂等性保证)
/// 使用 (sourceTopic, offset) 作为复合唯一键
model PrePlantingProcessedCdcEvent {
id BigInt @id @default(autoincrement())
sourceTopic String @map("source_topic") @db.VarChar(200)
offset BigInt @map("offset")
tableName String @map("table_name") @db.VarChar(100)
operation String @map("operation") @db.VarChar(10)
processedAt DateTime @default(now()) @map("processed_at")
@@unique([sourceTopic, offset])
@@index([processedAt])
@@map("pre_planting_processed_cdc_events")
}