238 lines
5.7 KiB
Plaintext
238 lines
5.7 KiB
Plaintext
// This is your Prisma schema file,
|
||
// learn more about it in the docs: https://pris.ly/d/prisma-schema
|
||
|
||
// Looking for ways to speed up your queries, or scale easily with your serverless or edge functions?
|
||
// Try Prisma Accelerate: https://pris.ly/cli/accelerate-init
|
||
|
||
generator client {
|
||
provider = "prisma-client-js"
|
||
}
|
||
|
||
datasource db {
|
||
provider = "postgresql"
|
||
}
|
||
|
||
enum GroupRole {
|
||
ADMIN
|
||
MEMBER
|
||
}
|
||
|
||
enum SetStatus {
|
||
DRAFT
|
||
OPEN
|
||
LOCKED
|
||
REVEALED
|
||
}
|
||
|
||
enum RevealMode {
|
||
MANUAL
|
||
AUTO_WHEN_ALL_GUESSED
|
||
}
|
||
|
||
model User {
|
||
id String @id @default(cuid())
|
||
name String?
|
||
email String? @unique
|
||
emailVerified DateTime?
|
||
image String?
|
||
|
||
accounts Account[]
|
||
sessions Session[]
|
||
|
||
memberships GroupMember[]
|
||
groupsCreated Group[] @relation("groupsCreated")
|
||
setsCreated Set[] @relation("setsCreated")
|
||
photosUploaded Photo[]
|
||
guesses Guess[]
|
||
|
||
invitesCreated Invite[] @relation("invitesCreated")
|
||
invitesUsed Invite[] @relation("invitesUsed")
|
||
|
||
createdAt DateTime @default(now())
|
||
updatedAt DateTime @updatedAt
|
||
}
|
||
|
||
// Auth.js / NextAuth Prisma Adapter models
|
||
model Account {
|
||
id String @id @default(cuid())
|
||
userId String
|
||
type String
|
||
provider String
|
||
providerAccountId String
|
||
refresh_token String?
|
||
access_token String?
|
||
expires_at Int?
|
||
token_type String?
|
||
scope String?
|
||
id_token String?
|
||
session_state String?
|
||
|
||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||
|
||
@@unique([provider, providerAccountId])
|
||
}
|
||
|
||
model Session {
|
||
id String @id @default(cuid())
|
||
sessionToken String @unique
|
||
userId String
|
||
expires DateTime
|
||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||
}
|
||
|
||
model VerificationToken {
|
||
identifier String
|
||
token String @unique
|
||
expires DateTime
|
||
|
||
@@unique([identifier, token])
|
||
}
|
||
|
||
// MirrorMatch domain models
|
||
model Group {
|
||
id String @id @default(cuid())
|
||
name String
|
||
slug String @unique
|
||
createdById String
|
||
createdBy User @relation("groupsCreated", fields: [createdById], references: [id], onDelete: Restrict)
|
||
|
||
members GroupMember[]
|
||
sets Set[]
|
||
invites Invite[]
|
||
|
||
createdAt DateTime @default(now())
|
||
updatedAt DateTime @updatedAt
|
||
}
|
||
|
||
model GroupMember {
|
||
id String @id @default(cuid())
|
||
groupId String
|
||
userId String
|
||
role GroupRole @default(MEMBER)
|
||
|
||
group Group @relation(fields: [groupId], references: [id], onDelete: Cascade)
|
||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||
|
||
joinedAt DateTime @default(now())
|
||
|
||
@@unique([groupId, userId])
|
||
}
|
||
|
||
model Set {
|
||
id String @id @default(cuid())
|
||
groupId String
|
||
createdById String
|
||
|
||
title String?
|
||
instructions String?
|
||
|
||
// Config constraints
|
||
minPhotos Int @default(2)
|
||
maxPhotos Int @default(10)
|
||
minOptions Int @default(2)
|
||
maxOptions Int @default(4)
|
||
|
||
status SetStatus @default(DRAFT)
|
||
revealMode RevealMode @default(MANUAL)
|
||
|
||
// If revealMode == AUTO_WHEN_ALL_GUESSED, app may auto-reveal once every active member has guessed every photo.
|
||
allowManualReveal Boolean @default(true)
|
||
|
||
group Group @relation(fields: [groupId], references: [id], onDelete: Cascade)
|
||
createdBy User @relation("setsCreated", fields: [createdById], references: [id], onDelete: Restrict)
|
||
|
||
options Option[]
|
||
photos Photo[]
|
||
|
||
revealedAt DateTime?
|
||
revealedById String?
|
||
|
||
createdAt DateTime @default(now())
|
||
updatedAt DateTime @updatedAt
|
||
|
||
@@index([groupId, status])
|
||
}
|
||
|
||
model Option {
|
||
id String @id @default(cuid())
|
||
setId String
|
||
label String
|
||
order Int
|
||
|
||
set Set @relation(fields: [setId], references: [id], onDelete: Cascade)
|
||
|
||
photosCorrect Photo[] @relation("correctOption")
|
||
guessesChosen Guess[] @relation("chosenOption")
|
||
|
||
@@unique([setId, label])
|
||
@@index([setId, order])
|
||
}
|
||
|
||
model Photo {
|
||
id String @id @default(cuid())
|
||
setId String
|
||
uploaderId String
|
||
|
||
// Object storage pointer (MinIO / S3)
|
||
storageKey String
|
||
mimeType String?
|
||
|
||
order Int
|
||
points Int @default(1) // 1–10 (enforced by app)
|
||
|
||
correctOptionId String
|
||
|
||
set Set @relation(fields: [setId], references: [id], onDelete: Cascade)
|
||
uploader User @relation(fields: [uploaderId], references: [id], onDelete: Restrict)
|
||
correctOption Option @relation("correctOption", fields: [correctOptionId], references: [id], onDelete: Restrict)
|
||
|
||
guesses Guess[]
|
||
|
||
createdAt DateTime @default(now())
|
||
updatedAt DateTime @updatedAt
|
||
|
||
@@index([setId, order])
|
||
}
|
||
|
||
model Guess {
|
||
id String @id @default(cuid())
|
||
photoId String
|
||
userId String
|
||
chosenOptionId String
|
||
|
||
photo Photo @relation(fields: [photoId], references: [id], onDelete: Cascade)
|
||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||
chosenOption Option @relation("chosenOption", fields: [chosenOptionId], references: [id], onDelete: Restrict)
|
||
|
||
createdAt DateTime @default(now())
|
||
|
||
@@unique([photoId, userId])
|
||
@@index([userId, createdAt])
|
||
}
|
||
|
||
model Invite {
|
||
id String @id @default(cuid())
|
||
groupId String
|
||
email String
|
||
role GroupRole @default(MEMBER)
|
||
|
||
// Store only a hash of the token in DB.
|
||
tokenHash String @unique
|
||
|
||
createdById String
|
||
createdBy User @relation("invitesCreated", fields: [createdById], references: [id], onDelete: Restrict)
|
||
|
||
usedAt DateTime?
|
||
usedById String?
|
||
usedBy User? @relation("invitesUsed", fields: [usedById], references: [id], onDelete: SetNull)
|
||
|
||
expiresAt DateTime
|
||
|
||
group Group @relation(fields: [groupId], references: [id], onDelete: Cascade)
|
||
|
||
createdAt DateTime @default(now())
|
||
|
||
@@index([groupId, expiresAt])
|
||
@@index([email, expiresAt])
|
||
}
|