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

174 lines
5.8 KiB
Plaintext

// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
// ============================================
// 监控地址表
// 存储需要监听充值的地址
// ============================================
model MonitoredAddress {
id BigInt @id @default(autoincrement()) @map("address_id")
chainType String @map("chain_type") @db.VarChar(20) // KAVA, BSC
address String @db.VarChar(42) // 0x地址
userId BigInt @map("user_id") // 关联用户ID
isActive Boolean @default(true) @map("is_active") // 是否激活监听
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
deposits DepositTransaction[]
@@unique([chainType, address], name: "uk_chain_address")
@@index([userId], name: "idx_user")
@@index([chainType, isActive], name: "idx_chain_active")
@@map("monitored_addresses")
}
// ============================================
// 充值交易表 (Append-Only)
// 记录检测到的所有充值交易
// ============================================
model DepositTransaction {
id BigInt @id @default(autoincrement()) @map("deposit_id")
chainType String @map("chain_type") @db.VarChar(20)
txHash String @unique @map("tx_hash") @db.VarChar(66)
fromAddress String @map("from_address") @db.VarChar(42)
toAddress String @map("to_address") @db.VarChar(42)
tokenContract String @map("token_contract") @db.VarChar(42) // USDT合约地址
amount Decimal @db.Decimal(36, 18) // 原始金额
amountFormatted Decimal @map("amount_formatted") @db.Decimal(20, 8) // 格式化金额
blockNumber BigInt @map("block_number")
blockTimestamp DateTime @map("block_timestamp")
logIndex Int @map("log_index")
// 确认状态
confirmations Int @default(0)
status String @default("DETECTED") @db.VarChar(20) // DETECTED, CONFIRMING, CONFIRMED, NOTIFIED
// 关联
addressId BigInt @map("address_id")
userId BigInt @map("user_id")
// 通知状态
notifiedAt DateTime? @map("notified_at")
notifyAttempts Int @default(0) @map("notify_attempts")
lastNotifyError String? @map("last_notify_error") @db.Text
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
monitoredAddress MonitoredAddress @relation(fields: [addressId], references: [id])
@@index([chainType, status], name: "idx_chain_status")
@@index([userId], name: "idx_deposit_user")
@@index([blockNumber], name: "idx_block")
@@index([status, notifiedAt], name: "idx_pending_notify")
@@map("deposit_transactions")
}
// ============================================
// 区块扫描检查点 (每条链一条记录)
// 记录扫描进度,用于断点续扫
// ============================================
model BlockCheckpoint {
id BigInt @id @default(autoincrement()) @map("checkpoint_id")
chainType String @unique @map("chain_type") @db.VarChar(20)
lastScannedBlock BigInt @map("last_scanned_block")
lastScannedAt DateTime @map("last_scanned_at")
// 健康状态
isHealthy Boolean @default(true) @map("is_healthy")
lastError String? @map("last_error") @db.Text
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
@@map("block_checkpoints")
}
// ============================================
// 交易广播请求表
// 记录待广播和已广播的交易
// ============================================
model TransactionRequest {
id BigInt @id @default(autoincrement()) @map("request_id")
chainType String @map("chain_type") @db.VarChar(20)
// 请求来源
sourceService String @map("source_service") @db.VarChar(50)
sourceOrderId String @map("source_order_id") @db.VarChar(100)
// 交易数据
fromAddress String @map("from_address") @db.VarChar(42)
toAddress String @map("to_address") @db.VarChar(42)
value Decimal @db.Decimal(36, 18)
data String? @db.Text // 合约调用数据
// 签名数据 (由 MPC 服务提供)
signedTx String? @map("signed_tx") @db.Text
// 广播结果
txHash String? @map("tx_hash") @db.VarChar(66)
status String @default("PENDING") @db.VarChar(20) // PENDING, SIGNED, BROADCASTED, CONFIRMED, FAILED
// Gas 信息
gasLimit BigInt? @map("gas_limit")
gasPrice Decimal? @map("gas_price") @db.Decimal(36, 18)
nonce Int?
// 错误信息
errorMessage String? @map("error_message") @db.Text
retryCount Int @default(0) @map("retry_count")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
@@unique([sourceService, sourceOrderId], name: "uk_source_order")
@@index([chainType, status], name: "idx_tx_chain_status")
@@index([txHash], name: "idx_tx_hash")
@@map("transaction_requests")
}
// ============================================
// 区块链事件日志 (Append-Only 审计)
// ============================================
model BlockchainEvent {
id BigInt @id @default(autoincrement()) @map("event_id")
eventType String @map("event_type") @db.VarChar(50)
aggregateId String @map("aggregate_id") @db.VarChar(100)
aggregateType String @map("aggregate_type") @db.VarChar(50)
eventData Json @map("event_data")
chainType String? @map("chain_type") @db.VarChar(20)
txHash String? @map("tx_hash") @db.VarChar(66)
occurredAt DateTime @default(now()) @map("occurred_at") @db.Timestamp(6)
@@index([aggregateType, aggregateId], name: "idx_event_aggregate")
@@index([eventType], name: "idx_event_type")
@@index([chainType], name: "idx_event_chain")
@@index([occurredAt], name: "idx_event_occurred")
@@map("blockchain_events")
}