TreasureTrails/backend/prisma/schema.prisma

207 lines
5.8 KiB
Text
Raw Permalink Normal View History

2026-03-18 09:02:21 -05:00
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model User {
id String @id @default(uuid())
email String @unique
passwordHash String
name String
screenName String?
avatarUrl String?
unitPreference UnitPreference @default(METRIC)
isAdmin Boolean @default(false)
isApiEnabled Boolean @default(false)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
games Game[] @relation("GameMaster")
teams TeamMember[]
captainOf Team? @relation("TeamCaptain")
chatMessages ChatMessage[]
2026-03-21 12:23:20 -05:00
locationHistory LocationHistory[]
apiKeys ApiKey[]
2026-03-18 09:02:21 -05:00
}
enum UnitPreference {
METRIC
IMPERIAL
}
2026-03-18 09:02:21 -05:00
model Game {
2026-03-21 12:23:20 -05:00
id String @id @default(uuid())
name String
description String?
prizeDetails String?
visibility Visibility @default(PUBLIC)
startDate DateTime?
locationLat Float?
locationLng Float?
searchRadius Float?
rules String?
randomizeRoutes Boolean @default(false)
status GameStatus @default(DRAFT)
inviteCode String? @unique
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
gameMasterId String
gameMaster User @relation("GameMaster", fields: [gameMasterId], references: [id])
routes Route[]
teams Team[]
chatMessages ChatMessage[]
locationHistory LocationHistory[]
2026-03-18 09:02:21 -05:00
}
2026-03-21 12:23:20 -05:00
model Route {
id String @id @default(uuid())
gameId String
game Game @relation(fields: [gameId], references: [id], onDelete: Cascade)
name String
description String?
color String @default("#3498db")
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
routeLegs RouteLeg[]
teamRoutes TeamRoute[]
}
model RouteLeg {
2026-03-18 09:02:21 -05:00
id String @id @default(uuid())
2026-03-21 12:23:20 -05:00
routeId String
route Route @relation(fields: [routeId], references: [id], onDelete: Cascade)
2026-03-18 09:02:21 -05:00
sequenceNumber Int
description String
conditionType String @default("photo")
conditionDetails String?
locationLat Float?
locationLng Float?
timeLimit Int?
}
model Team {
id String @id @default(uuid())
gameId String
game Game @relation(fields: [gameId], references: [id], onDelete: Cascade)
name String
2026-03-21 12:23:20 -05:00
captainId String? @unique
captain User? @relation("TeamCaptain", fields: [captainId], references: [id])
currentLegIndex Int @default(0)
status TeamStatus @default(ACTIVE)
totalTimeDeduction Int @default(0)
2026-03-18 09:02:21 -05:00
lat Float?
lng Float?
rank Int?
2026-03-21 12:23:20 -05:00
createdAt DateTime @default(now())
2026-03-18 09:02:21 -05:00
members TeamMember[]
photoSubmissions PhotoSubmission[]
chatMessages ChatMessage[]
2026-03-21 12:23:20 -05:00
teamRoutes TeamRoute[]
}
model TeamRoute {
id String @id @default(uuid())
teamId String
team Team @relation(fields: [teamId], references: [id], onDelete: Cascade)
routeId String
route Route @relation(fields: [routeId], references: [id])
assignedAt DateTime @default(now())
@@unique([teamId])
2026-03-18 09:02:21 -05:00
}
model TeamMember {
id String @id @default(uuid())
teamId String
team Team @relation(fields: [teamId], references: [id], onDelete: Cascade)
userId String
user User @relation(fields: [userId], references: [id])
joinedAt DateTime @default(now())
@@unique([teamId, userId])
}
model PhotoSubmission {
id String @id @default(uuid())
teamId String
team Team @relation(fields: [teamId], references: [id], onDelete: Cascade)
2026-03-21 12:23:20 -05:00
routeId String
routeLegId String
2026-03-18 09:02:21 -05:00
photoUrl String
approved Boolean @default(false)
submittedAt DateTime @default(now())
}
model ChatMessage {
id String @id @default(uuid())
gameId String
game Game @relation(fields: [gameId], references: [id], onDelete: Cascade)
2026-03-18 09:02:21 -05:00
teamId String?
team Team? @relation(fields: [teamId], references: [id])
2026-03-18 09:02:21 -05:00
userId String
user User @relation(fields: [userId], references: [id])
2026-03-18 09:02:21 -05:00
message String
isDirect Boolean @default(false)
2026-03-18 09:02:21 -05:00
sentAt DateTime @default(now())
}
2026-03-21 12:23:20 -05:00
model LocationHistory {
id String @id @default(uuid())
userId String
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
gameId String
game Game @relation(fields: [gameId], references: [id], onDelete: Cascade)
teamId String
lat Float
lng Float
accuracy Float?
recordedAt DateTime @default(now())
}
model SystemSettings {
id String @id @default("default")
registrationEnabled Boolean @default(true)
inviteCode String? @unique
updatedAt DateTime @updatedAt
}
model BannedEmail {
id String @id @default(uuid())
email String @unique
reason String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model ApiKey {
id String @id @default(uuid())
key String @unique
name String
userId String
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
expiresAt DateTime?
lastUsed DateTime?
createdAt DateTime @default(now())
}
2026-03-18 09:02:21 -05:00
enum Visibility {
PUBLIC
PRIVATE
}
enum GameStatus {
DRAFT
LIVE
ENDED
2026-03-19 06:10:30 -05:00
ARCHIVED
2026-03-18 09:02:21 -05:00
}
enum TeamStatus {
ACTIVE
DISQUALIFIED
FINISHED
}