Skip to content

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 iniciais

Modelos 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.

Documentação Técnica CSGOFlip