// 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" output = "../src/generated/prisma" } datasource db { provider = "postgresql" } model Artwork { id String @id @default(cuid()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt sortIndex Int @default(0) name String @unique slug String @unique altText String? description String? notes String? month Int? year Int? sortKey Int? okLabL Float? okLabA Float? okLabB Float? creationDate DateTime? needsWork Boolean @default(true) nsfw Boolean @default(false) published Boolean @default(false) setAsHeader Boolean @default(false) colorStatus String @default("PENDING") // PENDING | PROCESSING | READY | FAILED colorError String? colorsGeneratedAt DateTime? fileId String @unique file FileData @relation(fields: [fileId], references: [id]) galleryId String? gallery Gallery? @relation(fields: [galleryId], references: [id]) metadata ArtworkMetadata? timelapse ArtworkTimelapse? albums Album[] categories ArtCategory[] colors ArtworkColor[] tags Tag[] @relation("ArtworkTags") variants FileVariant[] @@index([colorStatus]) @@index([published, sortKey, id]) @@index([year, published, sortKey, id]) } model Album { id String @id @default(cuid()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt sortIndex Int @default(0) name String @unique slug String @unique description String? artworks Artwork[] } model Gallery { id String @id @default(cuid()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt sortIndex Int @default(0) name String @unique slug String @unique description String? artworks Artwork[] } model ArtCategory { id String @id @default(cuid()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt sortIndex Int @default(0) name String @unique slug String @unique description String? artworks Artwork[] tagLinks TagCategory[] } model Color { id String @id @default(cuid()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt name String @unique type String hex String? blue Int? green Int? red Int? artworks ArtworkColor[] } model ArtworkColor { id String @id @default(cuid()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt artworkId String colorId String type String artwork Artwork @relation(fields: [artworkId], references: [id]) color Color @relation(fields: [colorId], references: [id]) @@unique([artworkId, type]) } model ArtworkMetadata { id String @id @default(cuid()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt artworkId String @unique depth String format String space String channels Int height Int width Int autoOrientH Int? autoOrientW Int? bitsPerSample Int? density Int? hasAlpha Boolean? hasProfile Boolean? isPalette Boolean? isProgressive Boolean? artwork Artwork @relation(fields: [artworkId], references: [id]) } model ArtworkTimelapse { id String @id @default(cuid()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt artworkId String @unique artwork Artwork @relation(fields: [artworkId], references: [id], onDelete: Cascade) enabled Boolean @default(false) s3Key String @unique fileName String? mimeType String? sizeBytes Int? } model FileData { id String @id @default(cuid()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt fileKey String @unique originalFile String @unique fileType String name String fileSize Int uploadDate DateTime artwork Artwork? } model FileVariant { id String @id @default(cuid()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt s3Key String type String height Int width Int fileExtension String? mimeType String? url String? sizeBytes Int? artworkId String artwork Artwork @relation(fields: [artworkId], references: [id]) @@unique([artworkId, type]) } model Tag { id String @id @default(cuid()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt sortIndex Int @default(0) name String @unique slug String @unique isVisible Boolean @default(true) description String? aliases TagAlias[] categoryLinks TagCategory[] categoryParents TagCategory[] @relation("TagCategoryParent") artworks Artwork[] @relation("ArtworkTags") commissionTypes CommissionType[] @relation("CommissionTypeTags") commissionCustomCards CommissionCustomCard[] @relation("CommissionCustomCardTags") miniatures Miniature[] @relation("MiniatureTags") } model TagAlias { id String @id @default(cuid()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt alias String @unique tagId String tag Tag @relation(fields: [tagId], references: [id], onDelete: Cascade) @@unique([tagId, alias]) @@index([alias]) } model TagCategory { id String @id @default(cuid()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt tagId String categoryId String isParent Boolean @default(false) showOnAnimalPage Boolean @default(false) parentTagId String? tag Tag @relation(fields: [tagId], references: [id], onDelete: Cascade) category ArtCategory @relation(fields: [categoryId], references: [id], onDelete: Cascade) parentTag Tag? @relation("TagCategoryParent", fields: [parentTagId], references: [id], onDelete: SetNull) @@unique([tagId, categoryId]) @@index([categoryId]) @@index([tagId]) @@index([parentTagId]) @@index([categoryId, parentTagId]) } model Miniature { id String @id @default(cuid()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt tags Tag[] @relation("MiniatureTags") } model Commission { id String @id @default(cuid()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt sortIndex Int @default(0) } model CommissionType { id String @id @default(cuid()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt sortIndex Int @default(0) name String description String? tags Tag[] @relation("CommissionTypeTags") options CommissionTypeOption[] extras CommissionTypeExtra[] customInputs CommissionTypeCustomInput[] requests CommissionRequest[] } model CommissionCustomCard { id String @id @default(cuid()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt sortIndex Int @default(0) name String description String? referenceImageUrl String? isVisible Boolean @default(true) isSpecialOffer Boolean @default(false) tags Tag[] @relation("CommissionCustomCardTags") options CommissionCustomCardOption[] extras CommissionCustomCardExtra[] requests CommissionRequest[] @@index([isVisible, sortIndex]) } model CommissionOption { id String @id @default(cuid()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt sortIndex Int @default(0) name String description String? types CommissionTypeOption[] customCards CommissionCustomCardOption[] requests CommissionRequest[] } model CommissionTypeOption { id String @id @default(cuid()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt sortIndex Int @default(0) typeId String optionId String priceRange String? pricePercent Float? price Float? type CommissionType @relation(fields: [typeId], references: [id]) option CommissionOption @relation(fields: [optionId], references: [id]) @@unique([typeId, optionId]) } model CommissionExtra { id String @id @default(cuid()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt sortIndex Int @default(0) name String description String? requests CommissionRequest[] types CommissionTypeExtra[] customCards CommissionCustomCardExtra[] } model CommissionTypeExtra { id String @id @default(cuid()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt sortIndex Int @default(0) typeId String extraId String priceRange String? pricePercent Float? price Float? type CommissionType @relation(fields: [typeId], references: [id]) extra CommissionExtra @relation(fields: [extraId], references: [id]) @@unique([typeId, extraId]) } model CommissionCustomCardOption { id String @id @default(cuid()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt sortIndex Int @default(0) cardId String optionId String priceRange String? pricePercent Float? price Float? card CommissionCustomCard @relation(fields: [cardId], references: [id], onDelete: Cascade) option CommissionOption @relation(fields: [optionId], references: [id]) @@unique([cardId, optionId]) } model CommissionCustomInput { id String @id @default(cuid()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt sortIndex Int @default(0) name String @unique fieldId String types CommissionTypeCustomInput[] } model CommissionTypeCustomInput { id String @id @default(cuid()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt sortIndex Int @default(0) typeId String customInputId String inputType String label String required Boolean @default(false) type CommissionType @relation(fields: [typeId], references: [id]) customInput CommissionCustomInput @relation(fields: [customInputId], references: [id]) @@unique([typeId, customInputId]) } model CommissionCustomCardExtra { id String @id @default(cuid()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt sortIndex Int @default(0) cardId String extraId String priceRange String? pricePercent Float? price Float? card CommissionCustomCard @relation(fields: [cardId], references: [id], onDelete: Cascade) extra CommissionExtra @relation(fields: [extraId], references: [id]) @@unique([cardId, extraId]) } model CommissionRequest { id String @id @default(cuid()) index Int @default(autoincrement()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt customerName String customerEmail String message String status String @default("NEW") customerSocials String? ipAddress String? userAgent String? customFields Json? optionId String? typeId String? customCardId String? option CommissionOption? @relation(fields: [optionId], references: [id]) type CommissionType? @relation(fields: [typeId], references: [id]) customCard CommissionCustomCard? @relation(fields: [customCardId], references: [id]) extras CommissionExtra[] files CommissionRequestFile[] } model CommissionGuidelines { id String @id @default(cuid()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt markdown String exampleImageUrl String? isActive Boolean @default(true) @@index([isActive]) } model CommissionRequestFile { id String @id @default(cuid()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt fileKey String @unique originalFile String fileType String fileSize Int uploadDate DateTime requestId String request CommissionRequest @relation(fields: [requestId], references: [id], onDelete: Cascade) } model TermsOfService { id String @id @default(cuid()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt markdown String version Int @default(autoincrement()) } model User { id String @id name String email String emailVerified Boolean @default(false) image String? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt sessions Session[] accounts Account[] role String @default("user") banned Boolean? @default(false) banReason String? banExpires DateTime? @@unique([email]) @@map("user") } model Session { id String @id expiresAt DateTime token String createdAt DateTime @default(now()) updatedAt DateTime @updatedAt ipAddress String? userAgent String? userId String user User @relation(fields: [userId], references: [id], onDelete: Cascade) impersonatedBy String? @@unique([token]) @@index([userId]) @@map("session") } model Account { id String @id accountId String providerId String userId String user User @relation(fields: [userId], references: [id], onDelete: Cascade) accessToken String? refreshToken String? idToken String? accessTokenExpiresAt DateTime? refreshTokenExpiresAt DateTime? scope String? password String? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt @@index([userId]) @@map("account") } model Verification { id String @id identifier String value String expiresAt DateTime createdAt DateTime @default(now()) updatedAt DateTime @updatedAt @@index([identifier]) @@map("verification") }