// AeThex Auth Service - Prisma Schema // https://aethex.dev generator client { provider = "prisma-client-js" } datasource db { provider = "postgresql" url = env("DATABASE_URL") } model User { id String @id @default(uuid()) email String @unique username String @unique passwordHash String? // Null for OAuth-only users avatarUrl String? // OAuth googleId String? @unique githubId String? @unique discordId String? @unique // Profile displayName String? bio String? // Status isVerified Boolean @default(false) isActive Boolean @default(true) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt lastLoginAt DateTime? // Relations sessions Session[] games UserGame[] friends Friend[] @relation("UserFriends") friendOf Friend[] @relation("FriendOf") profile LauncherProfile? @@map("users") } model Session { id String @id @default(uuid()) userId String user User @relation(fields: [userId], references: [id], onDelete: Cascade) refreshToken String @unique userAgent String? ipAddress String? expiresAt DateTime createdAt DateTime @default(now()) @@map("sessions") } model LauncherProfile { id String @id @default(uuid()) userId String @unique user User @relation(fields: [userId], references: [id], onDelete: Cascade) gamertag String @unique level Int @default(1) xp Int @default(0) totalPlaytime Int @default(0) // seconds gamesPlayed Int @default(0) achievements Int @default(0) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt @@map("launcher_profiles") } model Game { id String @id @default(uuid()) slug String @unique title String description String? developer String publisher String? coverUrl String? backgroundUrl String? iconUrl String? // Metadata releaseDate DateTime? genres String[] // Array of genre tags tags String[] // Store info price Float @default(0) discountPrice Float? isFree Boolean @default(false) // Files downloadUrl String? sizeBytes BigInt @default(0) version String @default("1.0.0") // Status isPublished Boolean @default(false) isFeatured Boolean @default(false) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt // Relations owners UserGame[] @@map("games") } model UserGame { 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) // Ownership purchasedAt DateTime @default(now()) installedAt DateTime? installPath String? // Stats playtime Int @default(0) // seconds lastPlayed DateTime? @@unique([userId, gameId]) @@map("user_games") } model Friend { id String @id @default(uuid()) userId String user User @relation("UserFriends", fields: [userId], references: [id], onDelete: Cascade) friendId String friend User @relation("FriendOf", fields: [friendId], references: [id], onDelete: Cascade) status String @default("pending") // pending, accepted, blocked createdAt DateTime @default(now()) acceptedAt DateTime? @@unique([userId, friendId]) @@map("friends") }