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

324 lines
12 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.

generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
// ==================== 挖矿配置 ====================
// 挖矿全局配置
model MiningConfig {
id String @id @default(uuid())
totalShares Decimal @db.Decimal(30, 8) // 总积分股数量 (100.02B)
distributionPool Decimal @db.Decimal(30, 8) // 分配池 (200M)
remainingDistribution Decimal @db.Decimal(30, 8) // 剩余可分配
halvingPeriodYears Int @default(2) // 减半周期(年)
currentEra Int @default(1) // 当前纪元
eraStartDate DateTime // 当前纪元开始日期
minuteDistribution Decimal @db.Decimal(30, 18) // 每分钟分配量
isActive Boolean @default(false) // 是否已激活挖矿
activatedAt DateTime? // 激活时间
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@map("mining_configs")
}
// 减半纪元记录
model MiningEra {
id String @id @default(uuid())
eraNumber Int @unique
startDate DateTime
endDate DateTime?
initialDistribution Decimal @db.Decimal(30, 8) // 纪元初始可分配量
totalDistributed Decimal @default(0) @db.Decimal(30, 8) // 已分配量
minuteDistribution Decimal @db.Decimal(30, 18) // 每分钟分配量
isActive Boolean @default(true)
createdAt DateTime @default(now())
@@map("mining_eras")
}
// ==================== 用户挖矿账户 ====================
// 用户挖矿账户
model MiningAccount {
id String @id @default(uuid())
accountSequence String @unique
totalMined Decimal @default(0) @db.Decimal(30, 8) // 总挖到的积分股
availableBalance Decimal @default(0) @db.Decimal(30, 8) // 可用余额
frozenBalance Decimal @default(0) @db.Decimal(30, 8) // 冻结余额
totalContribution Decimal @default(0) @db.Decimal(30, 8) // 当前算力(从 contribution-service 同步)
lastSyncedAt DateTime? // 最后同步算力时间
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
records MiningRecord[]
transactions MiningTransaction[]
@@index([totalContribution(sort: Desc)])
@@map("mining_accounts")
}
// 挖矿记录(分钟级别)
model MiningRecord {
id String @id @default(uuid())
accountSequence String
miningMinute DateTime // 挖矿分钟(精确到分钟)
contributionRatio Decimal @db.Decimal(30, 18) // 当时的算力占比
totalContribution Decimal @db.Decimal(30, 8) // 当时的总算力
minuteDistribution Decimal @db.Decimal(30, 18) // 当分钟总分配量
minedAmount Decimal @db.Decimal(30, 18) // 挖到的数量
createdAt DateTime @default(now())
account MiningAccount @relation(fields: [accountSequence], references: [accountSequence])
@@unique([accountSequence, miningMinute])
@@index([miningMinute])
@@map("mining_records")
}
// 挖矿交易流水
model MiningTransaction {
id String @id @default(uuid())
accountSequence String
type String // MINE, FREEZE, UNFREEZE, TRANSFER_OUT, TRANSFER_IN, BURN
amount Decimal @db.Decimal(30, 8)
balanceBefore Decimal @db.Decimal(30, 8)
balanceAfter Decimal @db.Decimal(30, 8)
referenceId String? // 关联ID如交易ID、划转ID
referenceType String? // 关联类型
// 交易对手方信息
counterpartyType String? @map("counterparty_type") // USER, POOL, SYSTEM
counterpartyAccountSeq String? @map("counterparty_account_seq") // 对手方账户序列号
counterpartyUserId String? @map("counterparty_user_id") // 对手方用户ID
// 详细备注(包含完整交易信息,格式: "划转到用户[U123456]"
memo String? @db.Text
description String? // 保留兼容旧字段
createdAt DateTime @default(now())
account MiningAccount @relation(fields: [accountSequence], references: [accountSequence])
@@index([accountSequence, createdAt(sort: Desc)])
@@index([type])
@@index([counterpartyAccountSeq])
@@index([counterpartyUserId])
@@map("mining_transactions")
}
// ==================== 挖矿统计 ====================
// 每分钟挖矿统计
model MinuteMiningStat {
id String @id @default(uuid())
minute DateTime @unique
totalContribution Decimal @db.Decimal(30, 8) // 参与挖矿的总算力
totalDistributed Decimal @db.Decimal(30, 18) // 该分钟分配的总量
participantCount Int // 参与者数量
burnAmount Decimal @default(0) @db.Decimal(30, 8) // 该分钟销毁量
createdAt DateTime @default(now())
@@index([minute(sort: Desc)])
@@map("minute_mining_stats")
}
// 每日挖矿统计
model DailyMiningStat {
id String @id @default(uuid())
date DateTime @unique @db.Date
totalContribution Decimal @db.Decimal(30, 8)
totalDistributed Decimal @db.Decimal(30, 8)
totalBurned Decimal @db.Decimal(30, 8)
participantCount Int
avgContributionRate Decimal @db.Decimal(10, 8) // 平均算力利用率
createdAt DateTime @default(now())
@@map("daily_mining_stats")
}
// ==================== 销毁机制 ====================
// 黑洞账户
model BlackHole {
id String @id @default(uuid())
totalBurned Decimal @default(0) @db.Decimal(30, 8) // 已销毁总量
targetBurn Decimal @db.Decimal(30, 8) // 目标销毁量 (10B)
remainingBurn Decimal @db.Decimal(30, 8) // 剩余待销毁
lastBurnMinute DateTime?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
records BurnRecord[]
@@map("black_holes")
}
// 销毁记录
model BurnRecord {
id String @id @default(uuid())
blackHoleId String
burnMinute DateTime
burnAmount Decimal @db.Decimal(30, 18)
remainingTarget Decimal @db.Decimal(30, 8) // 销毁后剩余目标
// 来源信息(从哪个池/用户销毁)
sourceType String? @map("source_type") // CIRCULATION_POOL, USER, SYSTEM
sourceAccountSeq String? @map("source_account_seq") // 来源账户序列号
sourceUserId String? @map("source_user_id") // 来源用户ID
// 详细备注
memo String? @db.Text
createdAt DateTime @default(now())
blackHole BlackHole @relation(fields: [blackHoleId], references: [id])
@@unique([blackHoleId, burnMinute])
@@index([burnMinute])
@@index([sourceAccountSeq])
@@map("burn_records")
}
// ==================== 价格相关 ====================
// 价格快照(每分钟)
model PriceSnapshot {
id String @id @default(uuid())
snapshotTime DateTime @unique
price Decimal @db.Decimal(30, 18) // 当时价格
sharePool Decimal @db.Decimal(30, 8) // 股池
blackHoleAmount Decimal @db.Decimal(30, 8) // 黑洞数量
circulationPool Decimal @db.Decimal(30, 8) // 流通池
effectiveDenominator Decimal @db.Decimal(30, 8) // 有效分母
createdAt DateTime @default(now())
@@index([snapshotTime(sort: Desc)])
@@map("price_snapshots")
}
// ==================== 池账户系统 ====================
// 池账户类型枚举
enum PoolAccountType {
SHARE_POOL // 积分股池 - 总股池
BLACK_HOLE_POOL // 黑洞积分股池 - 销毁池
CIRCULATION_POOL // 流通积分股池 - 流通池
}
// 池账户交易类型枚举
enum PoolTransactionType {
// 积分股池操作
MINING_DISTRIBUTE // 挖矿分配(股池 -> 用户)
FEE_COLLECT // 手续费收取(用户 -> 股池)
INITIAL_INJECT // 初始注入
// 黑洞池操作
BURN // 销毁(流通池 -> 黑洞)
// 流通池操作
USER_TRANSFER_IN // 用户划入(用户 -> 流通池)
USER_TRANSFER_OUT // 用户划出(流通池 -> 用户)
TRADE_BUY // 交易买入
TRADE_SELL // 交易卖出
// 通用操作
POOL_TRANSFER // 池间划转
ADJUSTMENT // 系统调整
}
// 池账户(管理三大池:积分股池、黑洞积分股池、流通积分股池)
model PoolAccount {
id String @id @default(uuid())
poolType PoolAccountType @unique @map("pool_type") // 池类型
name String // 池名称
balance Decimal @default(0) @db.Decimal(30, 8) // 当前余额
totalInflow Decimal @default(0) @db.Decimal(30, 8) // 累计流入
totalOutflow Decimal @default(0) @db.Decimal(30, 8) // 累计流出
isActive Boolean @default(true) @map("is_active")
description String?
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
transactions PoolTransaction[]
@@index([poolType])
@@map("pool_accounts")
}
// 池账户交易明细(包含交易对手方信息)
model PoolTransaction {
id String @id @default(uuid())
poolAccountId String @map("pool_account_id")
poolType PoolAccountType @map("pool_type")
transactionType PoolTransactionType @map("transaction_type")
// 金额信息
amount Decimal @db.Decimal(30, 8)
balanceBefore Decimal @map("balance_before") @db.Decimal(30, 8)
balanceAfter Decimal @map("balance_after") @db.Decimal(30, 8)
// 交易对手方信息关键用户ID和账户序列号
counterpartyType String? @map("counterparty_type") // USER, POOL, SYSTEM, EXTERNAL
counterpartyAccountSeq String? @map("counterparty_account_seq") // 对手方账户序列号
counterpartyUserId String? @map("counterparty_user_id") // 对手方用户ID
counterpartyPoolType PoolAccountType? @map("counterparty_pool_type") // 如果对手方是池账户
// 关联信息
referenceId String? @map("reference_id") // 关联业务ID如订单ID、划转ID
referenceType String? @map("reference_type") // 关联类型
txHash String? @map("tx_hash") // 链上交易哈希(如有)
// 详细备注(包含完整交易信息)
// 格式示例: "挖矿分配给用户[U123456], 算力占比0.5%, 分钟2024-01-10 10:30"
memo String? @db.Text
// 扩展数据JSON格式存储更多业务细节
metadata Json?
createdAt DateTime @default(now()) @map("created_at")
poolAccount PoolAccount @relation(fields: [poolAccountId], references: [id])
@@index([poolAccountId, createdAt(sort: Desc)])
@@index([poolType, transactionType])
@@index([counterpartyAccountSeq])
@@index([counterpartyUserId])
@@index([referenceId])
@@index([createdAt(sort: Desc)])
@@map("pool_transactions")
}
// ==================== Outbox ====================
enum OutboxStatus {
PENDING
PUBLISHED
FAILED
}
model OutboxEvent {
id String @id @default(uuid())
aggregateType String @map("aggregate_type")
aggregateId String @map("aggregate_id")
eventType String @map("event_type")
payload Json
topic String @default("mining.events")
key String?
status OutboxStatus @default(PENDING)
retryCount Int @default(0) @map("retry_count")
maxRetries Int @default(5) @map("max_retries")
lastError String? @map("last_error")
publishedAt DateTime? @map("published_at")
nextRetryAt DateTime? @map("next_retry_at")
createdAt DateTime @default(now()) @map("created_at")
@@index([status])
@@index([nextRetryAt])
@@index([createdAt])
@@map("outbox_events")
}