174 lines
5.8 KiB
Plaintext
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")
|
|
}
|