@@ -25,6 +25,7 @@ model User {
|
||||
// Relations
|
||||
roles UserRole[]
|
||||
refreshTokens RefreshToken[]
|
||||
subscriptions Subscription[]
|
||||
|
||||
// Multi-tenancy (optional)
|
||||
tenantId String?
|
||||
@@ -160,3 +161,128 @@ model Translation {
|
||||
@@index([locale])
|
||||
@@index([namespace])
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// Game Calendar Domain Models
|
||||
// ============================================
|
||||
|
||||
model Game {
|
||||
id String @id @default(uuid())
|
||||
slug String @unique // igdb slug or generated
|
||||
title String
|
||||
coverImage String? // URL to cover art
|
||||
description String? @db.Text
|
||||
releaseDate DateTime? // Nullable if TBD
|
||||
isTBD Boolean @default(false)
|
||||
releaseDateText String? // "Q3 2026", "2026", etc for display if exact date unknown
|
||||
|
||||
// External Data
|
||||
igdbId Int? @unique
|
||||
rawgId Int? @unique
|
||||
|
||||
// Relations
|
||||
platforms GamePlatform[]
|
||||
subscriptions Subscription[]
|
||||
|
||||
// Timestamps
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
deletedAt DateTime?
|
||||
|
||||
@@index([releaseDate])
|
||||
@@index([slug])
|
||||
}
|
||||
|
||||
model Platform {
|
||||
id String @id @default(uuid())
|
||||
name String @unique // "PlayStation 5", "PC", "Xbox Series X"
|
||||
slug String @unique
|
||||
icon String? // URL/Phosphor icon name
|
||||
|
||||
// Relations
|
||||
games GamePlatform[]
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
}
|
||||
|
||||
model GamePlatform {
|
||||
gameId String
|
||||
platformId String
|
||||
game Game @relation(fields: [gameId], references: [id], onDelete: Cascade)
|
||||
platform Platform @relation(fields: [platformId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@id([gameId, platformId])
|
||||
}
|
||||
|
||||
model Event {
|
||||
id String @id @default(uuid())
|
||||
title String
|
||||
slug String @unique
|
||||
description String? @db.Text
|
||||
startTime DateTime
|
||||
endTime DateTime?
|
||||
streamUrl String?
|
||||
coverImage String?
|
||||
|
||||
type EventType @default(SHOWCASE)
|
||||
|
||||
// External
|
||||
source String? // "igdb", "manual"
|
||||
|
||||
// Relations
|
||||
subscriptions Subscription[]
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
deletedAt DateTime?
|
||||
|
||||
@@index([startTime])
|
||||
}
|
||||
|
||||
enum EventType {
|
||||
SHOWCASE
|
||||
RELEASE
|
||||
TOURNAMENT
|
||||
OTHER
|
||||
}
|
||||
|
||||
model Subscription {
|
||||
id String @id @default(uuid())
|
||||
userId String
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
|
||||
// Target (Either Game or Event)
|
||||
gameId String?
|
||||
game Game? @relation(fields: [gameId], references: [id], onDelete: Cascade)
|
||||
|
||||
eventId String?
|
||||
event Event? @relation(fields: [eventId], references: [id], onDelete: Cascade)
|
||||
|
||||
// Notification Preferences for this subscription
|
||||
notifyEmail Boolean @default(false)
|
||||
notifyPush Boolean @default(true)
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
@@index([userId])
|
||||
@@unique([userId, gameId]) // One sub per game
|
||||
@@unique([userId, eventId]) // One sub per event
|
||||
}
|
||||
|
||||
model ThemeConfig {
|
||||
id String @id @default(uuid())
|
||||
key String @unique @default("current_theme") // Singleton-ish
|
||||
isActive Boolean @default(true)
|
||||
|
||||
// Visuals
|
||||
gameTitle String // "Elden Ring"
|
||||
primaryColor String // Hex
|
||||
secondaryColor String // Hex
|
||||
backgroundColor String // Hex
|
||||
backgroundImage String? // URL
|
||||
logoImage String? // URL
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user