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

215 lines
6.7 KiB
Plaintext

generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
// ==================== 交易账户 ====================
// 用户交易账户
model TradingAccount {
id String @id @default(uuid())
accountSequence String @unique
shareBalance Decimal @db.Decimal(30, 8) @default(0) // 积分股余额
cashBalance Decimal @db.Decimal(30, 8) @default(0) // 现金余额
frozenShares Decimal @db.Decimal(30, 8) @default(0) // 冻结积分股
frozenCash Decimal @db.Decimal(30, 8) @default(0) // 冻结现金
totalBought Decimal @db.Decimal(30, 8) @default(0) // 累计买入量
totalSold Decimal @db.Decimal(30, 8) @default(0) // 累计卖出量
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
orders Order[]
transactions TradingTransaction[]
@@map("trading_accounts")
}
// ==================== 订单 ====================
// 交易订单
model Order {
id String @id @default(uuid())
orderNo String @unique // 订单号
accountSequence String
type String // BUY, SELL
status String // PENDING, PARTIAL, FILLED, CANCELLED
price Decimal @db.Decimal(30, 18) // 挂单价格
quantity Decimal @db.Decimal(30, 8) // 订单数量
filledQuantity Decimal @db.Decimal(30, 8) @default(0) // 已成交数量
remainingQuantity Decimal @db.Decimal(30, 8) // 剩余数量
averagePrice Decimal @db.Decimal(30, 18) @default(0) // 平均成交价
totalAmount Decimal @db.Decimal(30, 8) @default(0) // 总成交金额
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
cancelledAt DateTime?
completedAt DateTime?
account TradingAccount @relation(fields: [accountSequence], references: [accountSequence])
trades Trade[]
@@index([accountSequence, status])
@@index([type, status, price])
@@index([createdAt(sort: Desc)])
@@map("orders")
}
// 成交记录
model Trade {
id String @id @default(uuid())
tradeNo String @unique
buyOrderId String
sellOrderId String
buyerSequence String
sellerSequence String
price Decimal @db.Decimal(30, 18)
quantity Decimal @db.Decimal(30, 8)
amount Decimal @db.Decimal(30, 8) // price * quantity
createdAt DateTime @default(now())
buyOrder Order @relation(fields: [buyOrderId], references: [id])
@@index([buyerSequence])
@@index([sellerSequence])
@@index([createdAt(sort: Desc)])
@@map("trades")
}
// ==================== 交易流水 ====================
model TradingTransaction {
id String @id @default(uuid())
accountSequence String
type String // TRANSFER_IN, TRANSFER_OUT, BUY, SELL, FREEZE, UNFREEZE, DEPOSIT, WITHDRAW
assetType String // SHARE, CASH
amount Decimal @db.Decimal(30, 8)
balanceBefore Decimal @db.Decimal(30, 8)
balanceAfter Decimal @db.Decimal(30, 8)
referenceId String?
referenceType String?
description String?
createdAt DateTime @default(now())
account TradingAccount @relation(fields: [accountSequence], references: [accountSequence])
@@index([accountSequence, createdAt(sort: Desc)])
@@map("trading_transactions")
}
// ==================== 流通池 ====================
// 流通池
model CirculationPool {
id String @id @default(uuid())
totalShares Decimal @db.Decimal(30, 8) @default(0) // 流通池中的积分股
totalCash Decimal @db.Decimal(30, 8) @default(0) // 流通池中的现金(股池)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@map("circulation_pools")
}
// 流通池变动记录
model PoolTransaction {
id String @id @default(uuid())
type String // SHARE_IN, SHARE_OUT, CASH_IN, CASH_OUT
amount Decimal @db.Decimal(30, 8)
referenceId String?
description String?
createdAt DateTime @default(now())
@@index([createdAt(sort: Desc)])
@@map("pool_transactions")
}
// ==================== K线数据 ====================
// 分钟K线
model MinuteKLine {
id String @id @default(uuid())
minute DateTime @unique
open Decimal @db.Decimal(30, 18)
high Decimal @db.Decimal(30, 18)
low Decimal @db.Decimal(30, 18)
close Decimal @db.Decimal(30, 18)
volume Decimal @db.Decimal(30, 8) // 成交量
amount Decimal @db.Decimal(30, 8) // 成交额
tradeCount Int @default(0) // 成交笔数
createdAt DateTime @default(now())
@@index([minute(sort: Desc)])
@@map("minute_klines")
}
// 小时K线
model HourKLine {
id String @id @default(uuid())
hour DateTime @unique
open Decimal @db.Decimal(30, 18)
high Decimal @db.Decimal(30, 18)
low Decimal @db.Decimal(30, 18)
close Decimal @db.Decimal(30, 18)
volume Decimal @db.Decimal(30, 8)
amount Decimal @db.Decimal(30, 8)
tradeCount Int @default(0)
createdAt DateTime @default(now())
@@index([hour(sort: Desc)])
@@map("hour_klines")
}
// 日K线
model DayKLine {
id String @id @default(uuid())
date DateTime @unique @db.Date
open Decimal @db.Decimal(30, 18)
high Decimal @db.Decimal(30, 18)
low Decimal @db.Decimal(30, 18)
close Decimal @db.Decimal(30, 18)
volume Decimal @db.Decimal(30, 8)
amount Decimal @db.Decimal(30, 8)
tradeCount Int @default(0)
createdAt DateTime @default(now())
@@index([date(sort: Desc)])
@@map("day_klines")
}
// ==================== 划转记录 ====================
// 从挖矿账户划转记录
model TransferRecord {
id String @id @default(uuid())
transferNo String @unique
accountSequence String
direction String // IN (从挖矿账户划入), OUT (划出到挖矿账户)
amount Decimal @db.Decimal(30, 8)
status String // PENDING, COMPLETED, FAILED
miningTxId String? // 挖矿服务的交易ID
errorMessage String?
createdAt DateTime @default(now())
completedAt DateTime?
@@index([accountSequence])
@@index([status])
@@map("transfer_records")
}
// ==================== Outbox ====================
model OutboxEvent {
id String @id @default(uuid())
aggregateType String
aggregateId String
eventType String
payload Json
createdAt DateTime @default(now())
processedAt DateTime?
@@index([processedAt])
@@map("outbox_events")
}