Schema Prisma
O schema Prisma define todos os modelos, relacionamentos e tipos do banco de dados.
Localização
prisma/
├── schema.prisma # Schema principal
├── migrations/ # Histórico de migrations
└── seed.ts # Dados iniciaisModelos Principais
User
prisma
model User {
id BigInt @id @default(autoincrement())
// Steam
steamId String @unique
username String
avatarUrl String?
// Contato
email String? @unique
phone String?
// Saldo (cache - Source of Truth são as transações)
balanceCents BigInt @default(0)
// Status
status UserStatus @default(ACTIVE)
isAdmin Boolean @default(false)
adminRole AdminRole?
// 2FA
twoFactorEnabled Boolean @default(false)
twoFactorSecret String?
// Ban
bannedAt DateTime?
bannedReason String?
bannedUntil DateTime?
bannedBy BigInt?
// Relações
transactions Transaction[]
caseOpenings CaseOpening[]
battles BattleParticipant[]
deposits Deposit[]
withdrawals Withdrawal[]
inventory UserInventory[]
sessions Session[]
// Timestamps
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
lastLoginAt DateTime?
@@index([steamId])
@@index([status])
@@index([createdAt])
}
enum UserStatus {
ACTIVE
BANNED
SUSPENDED
}
enum AdminRole {
SUPER_ADMIN
ADMIN
MODERATOR
SUPPORT
FINANCIAL
}Transaction
prisma
model Transaction {
id BigInt @id @default(autoincrement())
// Usuários
debitUserId BigInt?
creditUserId BigInt?
// Valores
amountCents BigInt
// Tipo
type TransactionType
// Referência
referenceId BigInt?
referenceType String?
// Metadados
description String?
metadata Json?
// Relações
debitUser User? @relation("TransactionDebit", ...)
creditUser User? @relation("TransactionCredit", ...)
// Timestamps
createdAt DateTime @default(now())
@@index([debitUserId, createdAt])
@@index([creditUserId, createdAt])
@@index([referenceId, referenceType])
@@index([type])
}
enum TransactionType {
// Depósitos e Saques
DEPOSIT
WITHDRAWAL_PENDING
WITHDRAWAL_COMPLETED
WITHDRAWAL_REVERSAL
// Jogos
CASE_OPEN
CASE_WIN
BATTLE_ENTRY
BATTLE_WIN
UPGRADE_BET
UPGRADE_WIN
RAFFLE_TICKET
RAFFLE_WIN
// Admin
ADMIN_CREDIT
ADMIN_DEBIT
// Sistema
REFERRAL_BONUS
PROMO_CREDIT
}Case e CaseItem
prisma
model Case {
id BigInt @id @default(autoincrement())
// Identificação
name String
slug String @unique
description String?
imageUrl String
// Preço
priceCents BigInt
// Configuração
category CaseCategory
isActive Boolean @default(true)
isFeatured Boolean @default(false)
houseEdge Float @default(0.10)
// Relações
items CaseItem[]
openings CaseOpening[]
// Timestamps
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([isActive])
@@index([category])
}
enum CaseCategory {
CHEAP
MEDIUM
EXPENSIVE
PREMIUM
EVENT
}
model CaseItem {
id BigInt @id @default(autoincrement())
caseId BigInt
itemId BigInt
// Probabilidade
dropChance Float
rangeStart Int
rangeEnd Int
// Relações
case Case @relation(...)
item Item @relation(...)
@@index([caseId])
@@unique([caseId, itemId])
}Item
prisma
model Item {
id BigInt @id @default(autoincrement())
// Identificação
name String
slug String @unique
description String?
imageUrl String
// Classificação
rarity ItemRarity
category ItemCategory
// Valor
valueCents BigInt
// Configuração
isActive Boolean @default(true)
isUpgradable Boolean @default(true)
isTradable Boolean @default(true)
// Relações
caseItems CaseItem[]
inventory UserInventory[]
// Timestamps
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([rarity])
@@index([valueCents])
}
enum ItemRarity {
CONSUMER
INDUSTRIAL
MIL_SPEC
RESTRICTED
CLASSIFIED
COVERT
EXTRAORDINARY
}
enum ItemCategory {
RIFLE
PISTOL
SMG
SHOTGUN
SNIPER
KNIFE
GLOVES
STICKER
AGENT
CASE
KEY
}CaseOpening
prisma
model CaseOpening {
id BigInt @id @default(autoincrement())
// Referências
caseId BigInt
userId BigInt
itemId BigInt
// Provably Fair
serverSeed String
serverSeedHash String
clientSeed String
nonce Int
roll Int
// FLIP
isFlip Boolean @default(false)
flipServerSeed String?
flipClientSeed String?
flipNonce Int?
flipRoll Int?
// Valores
pricePaidCents BigInt
itemValueCents BigInt
profit BigInt
// Relações
case Case @relation(...)
user User @relation(...)
item Item @relation(...)
// Timestamps
createdAt DateTime @default(now())
@@index([userId, createdAt])
@@index([caseId])
@@index([createdAt])
}Battle e BattleParticipant
prisma
model Battle {
id BigInt @id @default(autoincrement())
// Configuração
caseId BigInt
creatorId BigInt
mode BattleMode
type BattleType
status BattleStatus
// Valores
entryPriceCents BigInt
totalPotCents BigInt
roundCount Int @default(1)
// Provably Fair
serverSeed String
serverSeedHash String
// Resultado
winnerTeam Int?
// Relações
case Case @relation(...)
creator User @relation(...)
participants BattleParticipant[]
rounds BattleRound[]
settlements BattleSettlement[]
// Timestamps
createdAt DateTime @default(now())
startedAt DateTime?
finishedAt DateTime?
@@index([status])
@@index([creatorId])
@@index([createdAt])
}
enum BattleMode {
NORMAL
FLIP
CRAZY
}
enum BattleType {
SOLO_1V1
TEAM_3V3
}
enum BattleStatus {
WAITING
READY
COUNTDOWN
RUNNING
FINISHED
CANCELLED
}
model BattleParticipant {
id BigInt @id @default(autoincrement())
battleId BigInt
userId BigInt
// Posição
team Int
slot Int
// Provably Fair
clientSeed String
nonce Int
// Resultado
totalValueCents BigInt @default(0)
isWinner Boolean @default(false)
// Relações
battle Battle @relation(...)
user User @relation(...)
rounds BattleRound[]
@@unique([battleId, userId])
@@index([battleId])
}
model BattleRound {
id BigInt @id @default(autoincrement())
battleId BigInt
participantId BigInt
roundNumber Int
// Resultado
roll Int
itemId BigInt
itemValueCents BigInt
// FLIP
isFlip Boolean @default(false)
flipRoll Int?
// Relações
battle Battle @relation(...)
participant BattleParticipant @relation(...)
item Item @relation(...)
@@unique([battleId, participantId, roundNumber])
}
model BattleSettlement {
id BigInt @id @default(autoincrement())
battleId BigInt
userId BigInt?
itemId BigInt
// Tipo
type BattleSettlementType
valueCents BigInt
roundNumber Int?
// Relações
battle Battle @relation(...)
user User? @relation(...)
item Item @relation(...)
// Timestamps
createdAt DateTime @default(now())
@@index([battleId])
}
enum BattleSettlementType {
DROPPED
REMOVED_TO_POOL
ADDED_FROM_POOL
}Deposit e Withdrawal
prisma
model Deposit {
id BigInt @id @default(autoincrement())
userId BigInt
// Valores
amountCents BigInt
// Pagamento
paymentMethod String
externalId String? @unique
// Status
status DepositStatus
// Relações
user User @relation(...)
// Timestamps
createdAt DateTime @default(now())
confirmedAt DateTime?
@@index([userId])
@@index([status])
@@index([externalId])
}
enum DepositStatus {
PENDING
CONFIRMED
FAILED
EXPIRED
}
model Withdrawal {
id BigInt @id @default(autoincrement())
userId BigInt
// Valores
amountCents BigInt
// Pagamento
paymentMethod String
paymentDetails String // Encrypted
// Status
status WithdrawalStatus
// Admin
approvedBy BigInt?
approvedAt DateTime?
rejectedBy BigInt?
rejectedAt DateTime?
rejectionReason String?
adminNotes String?
// Processamento
externalId String?
// Relações
user User @relation(...)
// Timestamps
createdAt DateTime @default(now())
completedAt DateTime?
@@index([userId])
@@index([status])
}
enum WithdrawalStatus {
PENDING
APPROVED
PROCESSING
COMPLETED
REJECTED
CANCELLED
FAILED
}UserInventory
prisma
model UserInventory {
id BigInt @id @default(autoincrement())
userId BigInt
itemId BigInt
// Status
status InventoryStatus @default(AVAILABLE)
// Origem
sourceType String // CASE_OPENING, BATTLE, etc.
sourceId BigInt
// Relações
user User @relation(...)
item Item @relation(...)
// Timestamps
createdAt DateTime @default(now())
@@index([userId, status])
@@index([itemId])
}
enum InventoryStatus {
AVAILABLE
LOCKED
SOLD
WITHDRAWN
}Session
prisma
model Session {
id String @id
userId BigInt
// Metadados
ipAddress String
userAgent String
deviceFingerprint String?
// Timestamps
createdAt DateTime @default(now())
expiresAt DateTime
lastActivity DateTime @default(now())
// Relações
user User @relation(...)
@@index([userId])
@@index([expiresAt])
}AuditLog
prisma
model AuditLog {
id BigInt @id @default(autoincrement())
// Ator
userId BigInt?
adminId BigInt?
// Ação
action String
resourceType String
resourceId BigInt?
// Dados
previousValue Json?
newValue Json?
metadata Json?
// Contexto
ipAddress String
userAgent String
// Integridade
hash String
previousHash String?
// Timestamps
createdAt DateTime @default(now())
@@index([userId])
@@index([adminId])
@@index([action])
@@index([resourceType, resourceId])
@@index([createdAt])
}Relacionamentos
Diagrama Completo
Validações
O Prisma Client valida automaticamente:
- Tipos de dados
- Campos obrigatórios
- Unicidade
- Relacionamentos
Validações adicionais são feitas nos DTOs com class-validator.
