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 readyAcceptances MatchReady[] @relation("MatchReadyUser") pterodactylClientApiKey String? } 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? readyAcceptances MatchReady[] @relation("MatchReadyMatch") cs2MatchId Int? // die in die JSON geschriebene matchid exportedAt DateTime? // wann die JSON exportiert wurde } 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]) } model MatchReady { matchId String steamId String acceptedAt DateTime @default(now()) match Match @relation("MatchReadyMatch", fields: [matchId], references: [id]) user User @relation("MatchReadyUser", fields: [steamId], references: [steamId]) @@id([matchId, steamId]) @@index([steamId]) } // ────────────────────────────────────────────── // 🛠️ Server-Konfiguration & Pterodactyl // ────────────────────────────────────────────── model ServerConfig { id String @id serverIp String serverPassword String? // ⬅️ neu pterodactylServerId String pterodactylServerApiKey String createdAt DateTime @default(now()) updatedAt DateTime @updatedAt }