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

684 lines
24 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.

// =============================================================================
// Mining Wallet Service - Prisma Schema
// 100% 独立于 1.0 系统,完全隔离的钱包管理服务
// =============================================================================
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
// =============================================================================
// 枚举定义
// =============================================================================
// 系统账户类型
enum SystemAccountType {
HEADQUARTERS // 总部账户
OPERATION // 运营账户
PROVINCE // 省级公司账户
CITY // 市级公司账户
FEE // 手续费账户
HOT_WALLET // 热钱包KAVA链上
COLD_WALLET // 冷钱包(离线存储)
}
// 池账户类型
enum PoolAccountType {
SHARE_POOL // 积分股池 - 总股池
BLACK_HOLE_POOL // 黑洞积分股池 - 销毁池
CIRCULATION_POOL // 流通积分股池 - 交易流通池
}
// 用户钱包账户类型
enum UserWalletType {
CONTRIBUTION // 算力账户hashpower/contribution
TOKEN_STORAGE // 积分股存储账户
GREEN_POINTS // 绿色积分账户
}
// 资产类型
enum AssetType {
SHARE // 积分股 (RWA Token)
USDT // USDT 稳定币
GREEN_POINT // 绿色积分
CONTRIBUTION // 算力值
}
// 交易类型
enum TransactionType {
// 挖矿相关
MINING_REWARD // 挖矿奖励
MINING_DISTRIBUTE // 挖矿分配
// 划转相关
TRANSFER_IN // 划入
TRANSFER_OUT // 划出
INTERNAL_TRANSFER // 内部划转
// 交易相关
TRADE_BUY // 买入
TRADE_SELL // 卖出
// 提现/充值
WITHDRAW // 提现到链上
DEPOSIT // 从链上充值
// 销毁
BURN // 销毁到黑洞
// 冻结/解冻
FREEZE // 冻结
UNFREEZE // 解冻
// 手续费
FEE_COLLECT // 收取手续费
FEE_DISTRIBUTE // 分发手续费
// 池操作
POOL_INJECT // 注入池
POOL_EXTRACT // 从池提取
// 系统调整
ADJUSTMENT // 系统调整
INITIAL_INJECT // 初始注入
}
// 交易对手方类型
enum CounterpartyType {
USER // 用户
SYSTEM_ACCOUNT // 系统账户
POOL // 池账户
BLOCKCHAIN // 区块链地址
EXTERNAL // 外部
}
// 提现状态
enum WithdrawStatus {
PENDING // 待处理
PROCESSING // 处理中
CONFIRMING // 链上确认中
COMPLETED // 已完成
FAILED // 失败
CANCELLED // 已取消
}
// Outbox 状态
enum OutboxStatus {
PENDING
PUBLISHED
FAILED
}
// =============================================================================
// 区域管理100% 独立于 1.0
// =============================================================================
// 省份
model Province {
id String @id @default(uuid())
code String @unique // 省份代码 e.g. "GD"
name String // 省份名称 e.g. "广东省"
status String @default("ACTIVE") // ACTIVE, DISABLED
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
cities City[]
systemAccounts SystemAccount[]
@@index([code])
@@map("provinces")
}
// 城市
model City {
id String @id @default(uuid())
provinceId String @map("province_id")
code String @unique // 城市代码 e.g. "SZ"
name String // 城市名称 e.g. "深圳市"
status String @default("ACTIVE") // ACTIVE, DISABLED
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
province Province @relation(fields: [provinceId], references: [id])
userMappings UserRegionMapping[]
systemAccounts SystemAccount[]
@@index([provinceId])
@@index([code])
@@map("cities")
}
// 用户区域映射100% 独立于 1.0
model UserRegionMapping {
id String @id @default(uuid())
accountSequence String @unique @map("account_sequence") // 用户账户序列号
cityId String @map("city_id")
assignedAt DateTime @default(now()) @map("assigned_at")
assignedBy String? @map("assigned_by") // 分配人管理员ID
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
city City @relation(fields: [cityId], references: [id])
@@index([cityId])
@@map("user_region_mappings")
}
// =============================================================================
// 系统账户HQ、运营、省/市公司、手续费、热/冷钱包)
// =============================================================================
model SystemAccount {
id String @id @default(uuid())
accountType SystemAccountType @map("account_type")
name String // 账户名称
code String @unique // 账户代码 e.g. "HQ", "OP", "GD-SZ"
// 关联区域(省/市级公司账户使用)
provinceId String? @map("province_id")
cityId String? @map("city_id")
// 余额信息
shareBalance Decimal @default(0) @map("share_balance") @db.Decimal(30, 8)
usdtBalance Decimal @default(0) @map("usdt_balance") @db.Decimal(30, 8)
greenPointBalance Decimal @default(0) @map("green_point_balance") @db.Decimal(30, 8)
contributionBalance Decimal @default(0) @map("contribution_balance") @db.Decimal(30, 8)
frozenShare Decimal @default(0) @map("frozen_share") @db.Decimal(30, 8)
frozenUsdt Decimal @default(0) @map("frozen_usdt") @db.Decimal(30, 8)
// 累计统计
totalInflow Decimal @default(0) @map("total_inflow") @db.Decimal(30, 8)
totalOutflow Decimal @default(0) @map("total_outflow") @db.Decimal(30, 8)
// 链上地址(热/冷钱包使用)
blockchainAddress String? @map("blockchain_address")
description String?
isActive Boolean @default(true) @map("is_active")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
province Province? @relation(fields: [provinceId], references: [id])
city City? @relation(fields: [cityId], references: [id])
transactions SystemAccountTransaction[]
@@unique([accountType, provinceId, cityId])
@@index([accountType])
@@index([provinceId])
@@index([cityId])
@@map("system_accounts")
}
// 系统账户交易明细
model SystemAccountTransaction {
id String @id @default(uuid())
systemAccountId String @map("system_account_id")
transactionType TransactionType @map("transaction_type")
assetType AssetType @map("asset_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)
// 交易对手方信息
counterpartyType CounterpartyType? @map("counterparty_type")
counterpartyAccountSeq String? @map("counterparty_account_seq")
counterpartyUserId String? @map("counterparty_user_id")
counterpartySystemId String? @map("counterparty_system_id")
counterpartyPoolType PoolAccountType? @map("counterparty_pool_type")
counterpartyAddress String? @map("counterparty_address")
// 关联信息
referenceId String? @map("reference_id")
referenceType String? @map("reference_type")
txHash String? @map("tx_hash")
// 详细备注(格式: "手续费收取自用户[U123456], 交易订单ORD20240110001"
memo String? @db.Text
metadata Json?
createdAt DateTime @default(now()) @map("created_at")
systemAccount SystemAccount @relation(fields: [systemAccountId], references: [id])
@@index([systemAccountId, createdAt(sort: Desc)])
@@index([transactionType])
@@index([counterpartyAccountSeq])
@@index([counterpartyUserId])
@@index([referenceId])
@@index([createdAt(sort: Desc)])
@@map("system_account_transactions")
}
// =============================================================================
// 池账户(积分股池、黑洞池、流通池)
// =============================================================================
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) @map("total_inflow") @db.Decimal(30, 8)
totalOutflow Decimal @default(0) @map("total_outflow") @db.Decimal(30, 8)
// 黑洞池特有字段
targetBurn Decimal? @map("target_burn") @db.Decimal(30, 8)
remainingBurn Decimal? @map("remaining_burn") @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 PoolAccountTransaction[]
@@index([poolType])
@@map("pool_accounts")
}
// 池账户交易明细
model PoolAccountTransaction {
id String @id @default(uuid())
poolAccountId String @map("pool_account_id")
poolType PoolAccountType @map("pool_type")
transactionType TransactionType @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 CounterpartyType? @map("counterparty_type")
counterpartyAccountSeq String? @map("counterparty_account_seq")
counterpartyUserId String? @map("counterparty_user_id")
counterpartySystemId String? @map("counterparty_system_id")
counterpartyPoolType PoolAccountType? @map("counterparty_pool_type")
counterpartyAddress String? @map("counterparty_address")
// 关联信息
referenceId String? @map("reference_id")
referenceType String? @map("reference_type")
txHash String? @map("tx_hash")
// 详细备注(格式: "挖矿分配给用户[U123456], 算力占比0.5%, 分钟2024-01-10 10:30"
memo String? @db.Text
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_account_transactions")
}
// =============================================================================
// 用户钱包账户
// =============================================================================
// 用户钱包(每个用户有多个钱包类型)
model UserWallet {
id String @id @default(uuid())
accountSequence String @map("account_sequence")
walletType UserWalletType @map("wallet_type")
// 余额信息
balance Decimal @default(0) @db.Decimal(30, 8)
frozenBalance Decimal @default(0) @map("frozen_balance") @db.Decimal(30, 8)
// 累计统计
totalInflow Decimal @default(0) @map("total_inflow") @db.Decimal(30, 8)
totalOutflow Decimal @default(0) @map("total_outflow") @db.Decimal(30, 8)
isActive Boolean @default(true) @map("is_active")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
transactions UserWalletTransaction[]
@@unique([accountSequence, walletType])
@@index([accountSequence])
@@index([walletType])
@@map("user_wallets")
}
// 用户钱包交易明细
model UserWalletTransaction {
id String @id @default(uuid())
userWalletId String @map("user_wallet_id")
accountSequence String @map("account_sequence")
walletType UserWalletType @map("wallet_type")
transactionType TransactionType @map("transaction_type")
assetType AssetType @map("asset_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 CounterpartyType? @map("counterparty_type")
counterpartyAccountSeq String? @map("counterparty_account_seq")
counterpartyUserId String? @map("counterparty_user_id")
counterpartySystemId String? @map("counterparty_system_id")
counterpartyPoolType PoolAccountType? @map("counterparty_pool_type")
counterpartyAddress String? @map("counterparty_address")
// 关联信息
referenceId String? @map("reference_id")
referenceType String? @map("reference_type")
txHash String? @map("tx_hash")
// 详细备注(格式: "划转到交易账户, 接收方用户[U789012]"
memo String? @db.Text
metadata Json?
createdAt DateTime @default(now()) @map("created_at")
userWallet UserWallet @relation(fields: [userWalletId], references: [id])
@@index([userWalletId, createdAt(sort: Desc)])
@@index([accountSequence, walletType])
@@index([transactionType])
@@index([counterpartyAccountSeq])
@@index([counterpartyUserId])
@@index([referenceId])
@@index([createdAt(sort: Desc)])
@@map("user_wallet_transactions")
}
// =============================================================================
// KAVA 区块链集成
// =============================================================================
// 提现请求
model WithdrawRequest {
id String @id @default(uuid())
requestNo String @unique @map("request_no")
accountSequence String @map("account_sequence")
// 提现信息
assetType AssetType @map("asset_type")
amount Decimal @db.Decimal(30, 8)
fee Decimal @default(0) @db.Decimal(30, 8)
netAmount Decimal @map("net_amount") @db.Decimal(30, 8)
// 目标地址
toAddress String @map("to_address")
// 状态
status WithdrawStatus @default(PENDING)
// 链上信息
txHash String? @map("tx_hash")
blockNumber BigInt? @map("block_number")
confirmations Int @default(0)
// 错误信息
errorMessage String? @map("error_message")
// 审核信息
approvedBy String? @map("approved_by")
approvedAt DateTime? @map("approved_at")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
completedAt DateTime? @map("completed_at")
@@index([accountSequence])
@@index([status])
@@index([txHash])
@@index([createdAt(sort: Desc)])
@@map("withdraw_requests")
}
// 充值记录(链上检测到的充值)
model DepositRecord {
id String @id @default(uuid())
txHash String @unique @map("tx_hash")
// 来源信息
fromAddress String @map("from_address")
toAddress String @map("to_address")
// 充值信息
assetType AssetType @map("asset_type")
amount Decimal @db.Decimal(30, 8)
// 链上信息
blockNumber BigInt @map("block_number")
confirmations Int @default(0)
// 匹配的用户(如果能匹配到)
matchedAccountSeq String? @map("matched_account_seq")
isProcessed Boolean @default(false) @map("is_processed")
processedAt DateTime? @map("processed_at")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
@@index([fromAddress])
@@index([toAddress])
@@index([matchedAccountSeq])
@@index([isProcessed])
@@index([createdAt(sort: Desc)])
@@map("deposit_records")
}
// DEX Swap 记录
model DexSwapRecord {
id String @id @default(uuid())
swapNo String @unique @map("swap_no")
accountSequence String @map("account_sequence")
// Swap 信息
fromAsset AssetType @map("from_asset")
toAsset AssetType @map("to_asset")
fromAmount Decimal @map("from_amount") @db.Decimal(30, 8)
toAmount Decimal @map("to_amount") @db.Decimal(30, 8)
exchangeRate Decimal @map("exchange_rate") @db.Decimal(30, 18)
// 滑点/手续费
slippage Decimal @default(0) @db.Decimal(10, 4)
fee Decimal @default(0) @db.Decimal(30, 8)
// 状态
status WithdrawStatus @default(PENDING)
// 链上信息
txHash String? @map("tx_hash")
blockNumber BigInt? @map("block_number")
errorMessage String? @map("error_message")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
completedAt DateTime? @map("completed_at")
@@index([accountSequence])
@@index([status])
@@index([txHash])
@@index([createdAt(sort: Desc)])
@@map("dex_swap_records")
}
// 链上地址绑定
model BlockchainAddressBinding {
id String @id @default(uuid())
accountSequence String @unique @map("account_sequence")
// KAVA 地址
kavaAddress String @unique @map("kava_address")
// 验证信息
isVerified Boolean @default(false) @map("is_verified")
verifiedAt DateTime? @map("verified_at")
verificationTxHash String? @map("verification_tx_hash")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
@@index([kavaAddress])
@@map("blockchain_address_bindings")
}
// 黑洞合约KAVA 链上销毁地址)
model BlackHoleContract {
id String @id @default(uuid())
contractAddress String @unique @map("contract_address")
name String
// 累计销毁
totalBurned Decimal @default(0) @map("total_burned") @db.Decimal(30, 8)
targetBurn Decimal @map("target_burn") @db.Decimal(30, 8)
remainingBurn Decimal @map("remaining_burn") @db.Decimal(30, 8)
isActive Boolean @default(true) @map("is_active")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
burnRecords BurnToBlackHoleRecord[]
@@map("black_hole_contracts")
}
// 销毁到黑洞的记录
model BurnToBlackHoleRecord {
id String @id @default(uuid())
blackHoleId String @map("black_hole_id")
// 销毁信息
amount Decimal @db.Decimal(30, 8)
// 来源
sourceType CounterpartyType @map("source_type")
sourceAccountSeq String? @map("source_account_seq")
sourceUserId String? @map("source_user_id")
sourcePoolType PoolAccountType? @map("source_pool_type")
// 链上信息
txHash String? @map("tx_hash")
blockNumber BigInt? @map("block_number")
// 备注
memo String? @db.Text
createdAt DateTime @default(now()) @map("created_at")
blackHole BlackHoleContract @relation(fields: [blackHoleId], references: [id])
@@index([blackHoleId])
@@index([sourceAccountSeq])
@@index([txHash])
@@index([createdAt(sort: Desc)])
@@map("burn_to_black_hole_records")
}
// =============================================================================
// 手续费配置
// =============================================================================
model FeeConfig {
id String @id @default(uuid())
feeType String @unique @map("fee_type") // WITHDRAW, TRADE, SWAP, TRANSFER
// 费率配置
feeRate Decimal @map("fee_rate") @db.Decimal(10, 6) // 费率 e.g. 0.001 = 0.1%
minFee Decimal @map("min_fee") @db.Decimal(30, 8) // 最低手续费
maxFee Decimal? @map("max_fee") @db.Decimal(30, 8) // 最高手续费(可选)
// 分配比例
headquartersRate Decimal @map("headquarters_rate") @db.Decimal(10, 6) // 总部分成比例
operationRate Decimal @map("operation_rate") @db.Decimal(10, 6) // 运营分成比例
provinceRate Decimal @map("province_rate") @db.Decimal(10, 6) // 省级分成比例
cityRate Decimal @map("city_rate") @db.Decimal(10, 6) // 市级分成比例
isActive Boolean @default(true) @map("is_active")
description String?
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
@@map("fee_configs")
}
// =============================================================================
// Outbox Pattern事件发布
// =============================================================================
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-wallet.events")
key String?
status OutboxStatus @default(PENDING)
retryCount Int @default(0) @map("retry_count")
maxRetries Int @default(10) @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")
}
// =============================================================================
// 已处理事件(幂等性)
// =============================================================================
model ProcessedEvent {
id String @id @default(uuid())
eventId String @unique @map("event_id")
eventType String @map("event_type")
sourceService String @map("source_service")
processedAt DateTime @default(now()) @map("processed_at")
@@index([sourceService])
@@index([processedAt])
@@map("processed_events")
}
// =============================================================================
// 审计日志
// =============================================================================
model AuditLog {
id String @id @default(uuid())
operatorId String @map("operator_id")
operatorType String @map("operator_type") // ADMIN, SYSTEM, USER
action String // CREATE, UPDATE, DELETE, TRANSFER, WITHDRAW, etc.
resource String // SYSTEM_ACCOUNT, USER_WALLET, POOL, etc.
resourceId String? @map("resource_id")
oldValue Json? @map("old_value")
newValue Json? @map("new_value")
ipAddress String? @map("ip_address")
userAgent String? @map("user_agent")
createdAt DateTime @default(now()) @map("created_at")
@@index([operatorId])
@@index([action])
@@index([resource])
@@index([createdAt(sort: Desc)])
@@map("audit_logs")
}