213 lines
7.5 KiB
Plaintext
213 lines
7.5 KiB
Plaintext
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 @db.Decimal(30, 8) @default(0) // 已分配量
|
||
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 @db.Decimal(30, 8) @default(0) // 总挖到的积分股
|
||
availableBalance Decimal @db.Decimal(30, 8) @default(0) // 可用余额
|
||
frozenBalance Decimal @db.Decimal(30, 8) @default(0) // 冻结余额
|
||
totalContribution Decimal @db.Decimal(30, 8) @default(0) // 当前算力(从 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? // 关联类型
|
||
description String?
|
||
createdAt DateTime @default(now())
|
||
|
||
account MiningAccount @relation(fields: [accountSequence], references: [accountSequence])
|
||
|
||
@@index([accountSequence, createdAt(sort: Desc)])
|
||
@@index([type])
|
||
@@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 @db.Decimal(30, 8) @default(0) // 该分钟销毁量
|
||
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 @db.Decimal(30, 8) @default(0) // 已销毁总量
|
||
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) // 销毁后剩余目标
|
||
createdAt DateTime @default(now())
|
||
|
||
blackHole BlackHole @relation(fields: [blackHoleId], references: [id])
|
||
|
||
@@unique([blackHoleId, burnMinute])
|
||
@@index([burnMinute])
|
||
@@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")
|
||
}
|
||
|
||
// ==================== 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")
|
||
}
|