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

378 lines
14 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 WalletAccount {
id BigInt @id @default(autoincrement()) @map("wallet_id")
accountSequence String @unique @map("account_sequence") @db.VarChar(20) // 跨服务关联标识 (全局唯一业务ID)
userId BigInt @unique @map("user_id") // 保留兼容
// USDT 余额
usdtAvailable Decimal @default(0) @map("usdt_available") @db.Decimal(20, 8)
usdtFrozen Decimal @default(0) @map("usdt_frozen") @db.Decimal(20, 8)
// DST 余额
dstAvailable Decimal @default(0) @map("dst_available") @db.Decimal(20, 8)
dstFrozen Decimal @default(0) @map("dst_frozen") @db.Decimal(20, 8)
// BNB 余额
bnbAvailable Decimal @default(0) @map("bnb_available") @db.Decimal(20, 8)
bnbFrozen Decimal @default(0) @map("bnb_frozen") @db.Decimal(20, 8)
// OG 余额
ogAvailable Decimal @default(0) @map("og_available") @db.Decimal(20, 8)
ogFrozen Decimal @default(0) @map("og_frozen") @db.Decimal(20, 8)
// RWAD 余额
rwadAvailable Decimal @default(0) @map("rwad_available") @db.Decimal(20, 8)
rwadFrozen Decimal @default(0) @map("rwad_frozen") @db.Decimal(20, 8)
// 算力
hashpower Decimal @default(0) @map("hashpower") @db.Decimal(20, 8)
// 待领取收益
pendingUsdt Decimal @default(0) @map("pending_usdt") @db.Decimal(20, 8)
pendingHashpower Decimal @default(0) @map("pending_hashpower") @db.Decimal(20, 8)
pendingExpireAt DateTime? @map("pending_expire_at")
// 可结算收益
settleableUsdt Decimal @default(0) @map("settleable_usdt") @db.Decimal(20, 8)
settleableHashpower Decimal @default(0) @map("settleable_hashpower") @db.Decimal(20, 8)
// 已结算总额
settledTotalUsdt Decimal @default(0) @map("settled_total_usdt") @db.Decimal(20, 8)
settledTotalHashpower Decimal @default(0) @map("settled_total_hashpower") @db.Decimal(20, 8)
// 已过期总额
expiredTotalUsdt Decimal @default(0) @map("expired_total_usdt") @db.Decimal(20, 8)
expiredTotalHashpower Decimal @default(0) @map("expired_total_hashpower") @db.Decimal(20, 8)
// 状态
status String @default("ACTIVE") @map("status") @db.VarChar(20)
// 是否已认种过(认种后分享权益直接进入可结算)
hasPlanted Boolean @default(false) @map("has_planted")
// 乐观锁版本号
version Int @default(0) @map("version")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
@@map("wallet_accounts")
@@index([userId])
@@index([usdtAvailable(sort: Desc)])
@@index([hashpower(sort: Desc)])
@@index([status])
}
// ============================================
// 账本流水表 (行为表, append-only)
// ============================================
model LedgerEntry {
id BigInt @id @default(autoincrement()) @map("entry_id")
accountSequence String @map("account_sequence") @db.VarChar(20) // 跨服务关联标识
userId BigInt @map("user_id") // 保留兼容
// 流水类型
entryType String @map("entry_type") @db.VarChar(50)
// 金额变动 (正数入账, 负数支出)
amount Decimal @map("amount") @db.Decimal(20, 8)
assetType String @map("asset_type") @db.VarChar(20)
// 余额快照 (操作后余额)
balanceAfter Decimal? @map("balance_after") @db.Decimal(20, 8)
// 关联引用
refOrderId String? @map("ref_order_id") @db.VarChar(100)
refTxHash String? @map("ref_tx_hash") @db.VarChar(100)
// 备注
memo String? @map("memo") @db.VarChar(500)
// 扩展数据
payloadJson Json? @map("payload_json")
createdAt DateTime @default(now()) @map("created_at")
@@map("wallet_ledger_entries")
@@index([accountSequence, createdAt(sort: Desc)])
@@index([userId, createdAt(sort: Desc)])
@@index([entryType])
@@index([assetType])
@@index([refOrderId])
@@index([refTxHash])
@@index([createdAt])
}
// ============================================
// 充值订单表
// ============================================
model DepositOrder {
id BigInt @id @default(autoincrement()) @map("order_id")
accountSequence String @map("account_sequence") @db.VarChar(20) // 跨服务关联标识
userId BigInt @map("user_id") // 保留兼容
// 充值信息
chainType String @map("chain_type") @db.VarChar(20)
amount Decimal @map("amount") @db.Decimal(20, 8)
txHash String @unique @map("tx_hash") @db.VarChar(100)
// 状态
status String @default("PENDING") @map("status") @db.VarChar(20)
confirmedAt DateTime? @map("confirmed_at")
createdAt DateTime @default(now()) @map("created_at")
@@map("deposit_orders")
@@index([accountSequence])
@@index([userId])
@@index([txHash])
@@index([status])
@@index([chainType])
}
// ============================================
// 结算订单表
// ============================================
model SettlementOrder {
id BigInt @id @default(autoincrement()) @map("order_id")
userId BigInt @map("user_id")
// 结算信息
usdtAmount Decimal @map("usdt_amount") @db.Decimal(20, 8)
settleCurrency String @map("settle_currency") @db.VarChar(10)
// SWAP 信息
swapTxHash String? @map("swap_tx_hash") @db.VarChar(100)
receivedAmount Decimal? @map("received_amount") @db.Decimal(20, 8)
// 状态
status String @default("PENDING") @map("status") @db.VarChar(20)
settledAt DateTime? @map("settled_at")
createdAt DateTime @default(now()) @map("created_at")
@@map("settlement_orders")
@@index([userId])
@@index([status])
@@index([settleCurrency])
@@index([createdAt])
}
// ============================================
// 提现订单表 (法币提现: 银行卡/支付宝/微信)
// ============================================
model WithdrawalOrder {
id BigInt @id @default(autoincrement()) @map("order_id")
orderNo String @unique @map("order_no") @db.VarChar(50)
accountSequence String @map("account_sequence") @db.VarChar(20) // 跨服务关联标识
userId BigInt @map("user_id")
// 提现信息
amount Decimal @map("amount") @db.Decimal(20, 8) // 提现金额 (绿积分, 1:1人民币)
fee Decimal @map("fee") @db.Decimal(20, 8) // 手续费
// 提现类型: FIAT (法币)
withdrawalType String @default("FIAT") @map("withdrawal_type") @db.VarChar(20)
// 收款方式: BANK_CARD / ALIPAY / WECHAT
paymentMethod String? @map("payment_method") @db.VarChar(20)
// 银行卡信息
bankName String? @map("bank_name") @db.VarChar(100)
bankCardNo String? @map("bank_card_no") @db.VarChar(30)
cardHolderName String? @map("card_holder_name") @db.VarChar(50)
// 支付宝信息
alipayAccount String? @map("alipay_account") @db.VarChar(100)
alipayRealName String? @map("alipay_real_name") @db.VarChar(50)
// 微信信息
wechatAccount String? @map("wechat_account") @db.VarChar(100)
wechatRealName String? @map("wechat_real_name") @db.VarChar(50)
// 状态: PENDING -> REVIEWING -> APPROVED -> PAYING -> COMPLETED / REJECTED / FAILED
status String @default("PENDING") @map("status") @db.VarChar(20)
errorMessage String? @map("error_message") @db.VarChar(500)
// 审核信息
reviewedBy String? @map("reviewed_by") @db.VarChar(50) // 审核人
reviewedAt DateTime? @map("reviewed_at") // 审核时间
reviewRemark String? @map("review_remark") @db.VarChar(500) // 审核备注
// 打款信息
paidBy String? @map("paid_by") @db.VarChar(50) // 打款人
paidAt DateTime? @map("paid_at") // 打款时间
paymentProof String? @map("payment_proof") @db.VarChar(500) // 打款凭证(截图URL等)
paymentRemark String? @map("payment_remark") @db.VarChar(500) // 打款备注
// 详细备注(记录完整的提现过程)
detailMemo String? @map("detail_memo") @db.Text
// 时间戳
frozenAt DateTime? @map("frozen_at") // 资金冻结时间
completedAt DateTime? @map("completed_at") // 完成时间
createdAt DateTime @default(now()) @map("created_at")
// 兼容旧字段(已弃用,保留用于迁移)
chainType String? @map("chain_type") @db.VarChar(20)
toAddress String? @map("to_address") @db.VarChar(100)
txHash String? @map("tx_hash") @db.VarChar(100)
isInternalTransfer Boolean @default(false) @map("is_internal_transfer")
toAccountSequence String? @map("to_account_sequence") @db.VarChar(20)
toUserId BigInt? @map("to_user_id")
broadcastedAt DateTime? @map("broadcasted_at")
confirmedAt DateTime? @map("confirmed_at")
@@map("withdrawal_orders")
@@index([accountSequence])
@@index([userId])
@@index([status])
@@index([paymentMethod])
@@index([reviewedAt])
@@index([paidAt])
@@index([createdAt])
}
// ============================================
// 用户收款账户表(保存用户的常用收款信息)
// ============================================
model UserPaymentAccount {
id BigInt @id @default(autoincrement()) @map("account_id")
accountSequence String @map("account_sequence") @db.VarChar(20)
userId BigInt @map("user_id")
// 收款方式: BANK_CARD / ALIPAY / WECHAT
paymentMethod String @map("payment_method") @db.VarChar(20)
// 银行卡信息
bankName String? @map("bank_name") @db.VarChar(100)
bankCardNo String? @map("bank_card_no") @db.VarChar(30)
cardHolderName String? @map("card_holder_name") @db.VarChar(50)
// 支付宝信息
alipayAccount String? @map("alipay_account") @db.VarChar(100)
alipayRealName String? @map("alipay_real_name") @db.VarChar(50)
// 微信信息
wechatAccount String? @map("wechat_account") @db.VarChar(100)
wechatRealName String? @map("wechat_real_name") @db.VarChar(50)
// 是否为默认账户
isDefault Boolean @default(false) @map("is_default")
// 状态
isActive Boolean @default(true) @map("is_active")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
@@map("user_payment_accounts")
@@index([accountSequence])
@@index([userId])
@@index([paymentMethod])
@@index([isDefault])
}
// ============================================
// 待领取奖励表 (逐笔记录)
// 每笔待领取奖励独立跟踪过期时间
// ============================================
model PendingReward {
id BigInt @id @default(autoincrement()) @map("pending_reward_id")
accountSequence String @map("account_sequence") @db.VarChar(20) // 跨服务关联标识
userId BigInt @map("user_id") // 保留兼容
// 奖励金额
usdtAmount Decimal @map("usdt_amount") @db.Decimal(20, 8)
hashpowerAmount Decimal @map("hashpower_amount") @db.Decimal(20, 8)
// 来源信息
sourceOrderId String @map("source_order_id") @db.VarChar(100) // 触发奖励的认种订单
allocationType String @map("allocation_type") @db.VarChar(50) // 分配类型 (SHARE_RIGHT, TEAM_RIGHT 等)
// 过期时间
expireAt DateTime @map("expire_at")
// 状态: PENDING(待领取) / SETTLED(已结算) / EXPIRED(已过期)
status String @default("PENDING") @map("status") @db.VarChar(20)
// 结算/过期时间
settledAt DateTime? @map("settled_at")
expiredAt DateTime? @map("expired_at")
createdAt DateTime @default(now()) @map("created_at")
@@map("pending_rewards")
@@index([accountSequence, status])
@@index([userId, status])
@@index([status, expireAt]) // 用于定时任务查询过期奖励
@@index([sourceOrderId])
@@index([createdAt])
}
// ============================================
// 提取手续费配置表
// ============================================
model WithdrawalFeeConfig {
id BigInt @id @default(autoincrement()) @map("config_id")
// 费率类型: FIXED(固定金额) / PERCENTAGE(百分比)
feeType String @map("fee_type") @db.VarChar(20)
// 费率值: 固定金额时为具体数值,百分比时为小数 (如 0.001 = 0.1%)
feeValue Decimal @map("fee_value") @db.Decimal(20, 8)
// 最小手续费 (百分比模式下生效)
minFee Decimal @default(0) @map("min_fee") @db.Decimal(20, 8)
// 最大手续费 (百分比模式下生效0表示不限制)
maxFee Decimal @default(0) @map("max_fee") @db.Decimal(20, 8)
// 是否启用
isActive Boolean @default(true) @map("is_active")
// 备注
memo String? @map("memo") @db.VarChar(200)
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
@@map("withdrawal_fee_configs")
@@index([isActive])
}
// ============================================
// 已处理事件表 (幂等性检查)
// 用于确保 Kafka 事件不会被重复处理
// ============================================
model ProcessedEvent {
id BigInt @id @default(autoincrement()) @map("processed_id")
// 事件标识 (聚合根ID + 事件类型)
eventId String @map("event_id") @db.VarChar(200)
eventType String @map("event_type") @db.VarChar(100)
// 来源服务
sourceService String @map("source_service") @db.VarChar(50)
// 处理时间
processedAt DateTime @default(now()) @map("processed_at")
@@unique([eventId, eventType])
@@map("processed_events")
@@index([eventId])
@@index([eventType])
@@index([processedAt])
}