359 lines
9.5 KiB
Plaintext
359 lines
9.5 KiB
Plaintext
generator client {
|
||
provider = "prisma-client-js"
|
||
output = "../src/generated/prisma"
|
||
}
|
||
|
||
datasource db {
|
||
provider = "postgresql"
|
||
url = env("DATABASE_URL")
|
||
}
|
||
|
||
//
|
||
// ──────────────────────────────────────────────
|
||
// 🧑 Benutzer, Teams & Verwaltung
|
||
// ──────────────────────────────────────────────
|
||
//
|
||
|
||
model User {
|
||
steamId String @id
|
||
name String?
|
||
avatar String?
|
||
location String?
|
||
isAdmin Boolean @default(false)
|
||
|
||
teamId String?
|
||
team Team? @relation("UserTeam", fields: [teamId], references: [id])
|
||
ledTeam Team? @relation("TeamLeader")
|
||
|
||
matchesAsTeamA Match[] @relation("TeamAPlayers")
|
||
matchesAsTeamB Match[] @relation("TeamBPlayers")
|
||
|
||
premierRank Int?
|
||
authCode String?
|
||
lastKnownShareCode String?
|
||
lastKnownShareCodeDate DateTime?
|
||
createdAt DateTime @default(now())
|
||
|
||
invites TeamInvite[] @relation("UserInvitations")
|
||
notifications Notification[]
|
||
matchPlayers MatchPlayer[]
|
||
serverRequests ServerRequest[] @relation("MatchRequests")
|
||
rankHistory RankHistory[] @relation("UserRankHistory")
|
||
demoFiles DemoFile[]
|
||
|
||
createdSchedules Schedule[] @relation("CreatedSchedules")
|
||
confirmedSchedules Schedule[] @relation("ConfirmedSchedules")
|
||
|
||
mapVoteChoices MapVoteStep[] @relation("VoteStepChooser")
|
||
|
||
status UserStatus @default(offline) // 👈 neu
|
||
lastActiveAt DateTime? // optional: wann zuletzt aktiv
|
||
}
|
||
|
||
enum UserStatus {
|
||
online
|
||
away
|
||
offline
|
||
}
|
||
|
||
|
||
model Team {
|
||
id String @id @default(uuid())
|
||
name String @unique
|
||
logo String?
|
||
leaderId String? @unique
|
||
createdAt DateTime @default(now())
|
||
|
||
activePlayers String[]
|
||
inactivePlayers String[]
|
||
|
||
leader User? @relation("TeamLeader", fields: [leaderId], references: [steamId])
|
||
members User[] @relation("UserTeam")
|
||
invites TeamInvite[]
|
||
matchPlayers MatchPlayer[]
|
||
|
||
matchesAsTeamA Match[] @relation("MatchTeamA")
|
||
matchesAsTeamB Match[] @relation("MatchTeamB")
|
||
|
||
schedulesAsTeamA Schedule[] @relation("ScheduleTeamA")
|
||
schedulesAsTeamB Schedule[] @relation("ScheduleTeamB")
|
||
|
||
mapVoteSteps MapVoteStep[] @relation("VoteStepTeam")
|
||
}
|
||
|
||
model TeamInvite {
|
||
id String @id @default(uuid())
|
||
steamId String
|
||
teamId String
|
||
type String
|
||
createdAt DateTime @default(now())
|
||
|
||
user User @relation("UserInvitations", fields: [steamId], references: [steamId])
|
||
team Team @relation(fields: [teamId], references: [id])
|
||
}
|
||
|
||
model Notification {
|
||
id String @id @default(uuid())
|
||
steamId String
|
||
title String?
|
||
message String
|
||
read Boolean @default(false)
|
||
persistent Boolean @default(false)
|
||
actionType String?
|
||
actionData String?
|
||
createdAt DateTime @default(now())
|
||
|
||
user User @relation(fields: [steamId], references: [steamId])
|
||
}
|
||
|
||
//
|
||
// ──────────────────────────────────────────────
|
||
// 🎮 Matches & Spieler
|
||
// ──────────────────────────────────────────────
|
||
//
|
||
|
||
// ──────────────────────────────────────────────
|
||
// 🎮 Matches
|
||
// ──────────────────────────────────────────────
|
||
|
||
model Match {
|
||
id String @id @default(uuid())
|
||
title String
|
||
matchType String @default("community")
|
||
map String?
|
||
description String?
|
||
scoreA Int?
|
||
scoreB Int?
|
||
|
||
teamAId String?
|
||
teamA Team? @relation("MatchTeamA", fields: [teamAId], references: [id])
|
||
|
||
teamBId String?
|
||
teamB Team? @relation("MatchTeamB", fields: [teamBId], references: [id])
|
||
|
||
teamAUsers User[] @relation("TeamAPlayers")
|
||
teamBUsers User[] @relation("TeamBPlayers")
|
||
|
||
filePath String?
|
||
demoFile DemoFile?
|
||
demoDate DateTime?
|
||
demoData Json?
|
||
|
||
players MatchPlayer[]
|
||
rankUpdates RankHistory[] @relation("MatchRankHistory")
|
||
|
||
roundCount Int?
|
||
roundHistory Json?
|
||
winnerTeam String?
|
||
|
||
bestOf Int @default(3) // 1 | 3 | 5 – app-seitig validieren
|
||
matchDate DateTime? // geplante Startzeit (separat von demoDate)
|
||
mapVote MapVote?
|
||
|
||
createdAt DateTime @default(now())
|
||
updatedAt DateTime @updatedAt
|
||
|
||
schedule Schedule?
|
||
}
|
||
|
||
model MatchPlayer {
|
||
id String @id @default(uuid())
|
||
steamId String
|
||
matchId String
|
||
teamId String?
|
||
team Team? @relation(fields: [teamId], references: [id])
|
||
|
||
match Match @relation(fields: [matchId], references: [id])
|
||
user User @relation(fields: [steamId], references: [steamId])
|
||
|
||
stats PlayerStats?
|
||
|
||
createdAt DateTime @default(now())
|
||
|
||
@@unique([matchId, steamId])
|
||
}
|
||
|
||
model PlayerStats {
|
||
id String @id @default(uuid())
|
||
matchId String
|
||
steamId String
|
||
|
||
kills Int
|
||
assists Int
|
||
deaths Int
|
||
headshotPct Float
|
||
|
||
totalDamage Float @default(0)
|
||
utilityDamage Int @default(0)
|
||
flashAssists Int @default(0)
|
||
mvps Int @default(0)
|
||
mvpEliminations Int @default(0)
|
||
mvpDefuse Int @default(0)
|
||
mvpPlant Int @default(0)
|
||
knifeKills Int @default(0)
|
||
zeusKills Int @default(0)
|
||
wallbangKills Int @default(0)
|
||
smokeKills Int @default(0)
|
||
headshots Int @default(0)
|
||
noScopes Int @default(0)
|
||
blindKills Int @default(0)
|
||
|
||
aim Int @default(0)
|
||
|
||
oneK Int @default(0)
|
||
twoK Int @default(0)
|
||
threeK Int @default(0)
|
||
fourK Int @default(0)
|
||
fiveK Int @default(0)
|
||
|
||
rankOld Int?
|
||
rankNew Int?
|
||
rankChange Int?
|
||
winCount Int?
|
||
|
||
matchPlayer MatchPlayer @relation(fields: [matchId, steamId], references: [matchId, steamId])
|
||
|
||
@@unique([matchId, steamId])
|
||
}
|
||
|
||
model RankHistory {
|
||
id String @id @default(uuid())
|
||
steamId String
|
||
matchId String?
|
||
|
||
rankOld Int
|
||
rankNew Int
|
||
delta Int
|
||
winCount Int
|
||
|
||
createdAt DateTime @default(now())
|
||
|
||
user User @relation("UserRankHistory", fields: [steamId], references: [steamId])
|
||
match Match? @relation("MatchRankHistory", fields: [matchId], references: [id])
|
||
}
|
||
|
||
model Schedule {
|
||
id String @id @default(uuid())
|
||
title String
|
||
description String?
|
||
map String?
|
||
date DateTime
|
||
status ScheduleStatus @default(PENDING)
|
||
|
||
teamAId String?
|
||
teamA Team? @relation("ScheduleTeamA", fields: [teamAId], references: [id])
|
||
|
||
teamBId String?
|
||
teamB Team? @relation("ScheduleTeamB", fields: [teamBId], references: [id])
|
||
|
||
createdById String
|
||
createdBy User @relation("CreatedSchedules", fields: [createdById], references: [steamId])
|
||
|
||
confirmedById String?
|
||
confirmedBy User? @relation("ConfirmedSchedules", fields: [confirmedById], references: [steamId])
|
||
|
||
linkedMatchId String? @unique
|
||
linkedMatch Match? @relation(fields: [linkedMatchId], references: [id])
|
||
|
||
createdAt DateTime @default(now())
|
||
updatedAt DateTime @updatedAt
|
||
}
|
||
|
||
enum ScheduleStatus {
|
||
PENDING
|
||
CONFIRMED
|
||
DECLINED
|
||
CANCELLED
|
||
COMPLETED
|
||
}
|
||
|
||
//
|
||
// ──────────────────────────────────────────────
|
||
// 📦 Demo-Dateien & CS2 Requests
|
||
// ──────────────────────────────────────────────
|
||
//
|
||
|
||
model DemoFile {
|
||
id String @id @default(uuid())
|
||
matchId String @unique
|
||
steamId String
|
||
fileName String @unique
|
||
filePath String
|
||
parsed Boolean @default(false)
|
||
|
||
createdAt DateTime @default(now())
|
||
|
||
match Match @relation(fields: [matchId], references: [id])
|
||
user User @relation(fields: [steamId], references: [steamId])
|
||
}
|
||
|
||
model ServerRequest {
|
||
id String @id @default(uuid())
|
||
steamId String
|
||
matchId String
|
||
reservationId BigInt
|
||
tvPort BigInt
|
||
processed Boolean @default(false)
|
||
failed Boolean @default(false)
|
||
|
||
createdAt DateTime @default(now())
|
||
|
||
user User @relation("MatchRequests", fields: [steamId], references: [steamId])
|
||
|
||
@@unique([steamId, matchId])
|
||
}
|
||
|
||
// ──────────────────────────────────────────────
|
||
// 🗺️ Map-Vote
|
||
// ──────────────────────────────────────────────
|
||
|
||
enum MapVoteAction {
|
||
BAN
|
||
PICK
|
||
DECIDER
|
||
}
|
||
|
||
model MapVote {
|
||
id String @id @default(uuid())
|
||
matchId String @unique
|
||
match Match @relation(fields: [matchId], references: [id])
|
||
|
||
bestOf Int @default(3)
|
||
mapPool String[]
|
||
currentIdx Int @default(0)
|
||
locked Boolean @default(false)
|
||
opensAt DateTime?
|
||
|
||
leadMinutes Int @default(60)
|
||
|
||
adminEditingBy String?
|
||
adminEditingSince DateTime?
|
||
|
||
steps MapVoteStep[]
|
||
|
||
createdAt DateTime @default(now())
|
||
updatedAt DateTime @updatedAt
|
||
}
|
||
|
||
model MapVoteStep {
|
||
id String @id @default(uuid())
|
||
voteId String
|
||
order Int
|
||
action MapVoteAction
|
||
|
||
teamId String?
|
||
team Team? @relation("VoteStepTeam", fields: [teamId], references: [id])
|
||
|
||
map String?
|
||
chosenAt DateTime?
|
||
chosenBy String?
|
||
chooser User? @relation("VoteStepChooser", fields: [chosenBy], references: [steamId])
|
||
|
||
vote MapVote @relation(fields: [voteId], references: [id])
|
||
|
||
@@unique([voteId, order])
|
||
@@index([teamId])
|
||
@@index([chosenBy])
|
||
}
|
||
|