// This is your Prisma schema file, // learn more about it in the docs: https://pris.ly/d/prisma-schema generator client { provider = "prisma-client-js" } datasource db { provider = "postgresql" url = env("DATABASE_URL") } // Projects table (for /work) model Project { id Int @id @default(autoincrement()) slug String @unique @db.VarChar(255) title String @db.VarChar(255) subtitle String? @db.VarChar(255) description String? @db.Text year Int client String? @db.VarChar(255) role String? @db.VarChar(255) featuredImage String? @db.VarChar(500) logoUrl String? @db.VarChar(500) gallery Json? // Array of image URLs externalUrl String? @db.VarChar(500) caseStudyContent Json? // BlockNote JSON format backgroundColor String? @db.VarChar(50) // For project card styling highlightColor String? @db.VarChar(50) // For project card accent projectType String @default("work") @db.VarChar(50) // "work" or "labs" displayOrder Int @default(0) status String @default("draft") @db.VarChar(50) // "draft", "published", "list-only", "password-protected" password String? @db.VarChar(255) // Required when status is "password-protected" publishedAt DateTime? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt @@index([slug]) @@index([status]) } // Posts table (for /universe) model Post { id Int @id @default(autoincrement()) slug String @unique @db.VarChar(255) postType String @db.VarChar(50) // post, essay title String? @db.VarChar(255) // Optional for post type content Json? // JSON content for posts and essays featuredImage String? @db.VarChar(500) attachments Json? // Array of media IDs for photo attachments tags Json? // Array of tags status String @default("draft") @db.VarChar(50) publishedAt DateTime? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt @@index([slug]) @@index([status]) @@index([postType]) } // Albums table model Album { id Int @id @default(autoincrement()) slug String @unique @db.VarChar(255) title String @db.VarChar(255) description String? @db.Text date DateTime? location String? @db.VarChar(255) coverPhotoId Int? isPhotography Boolean @default(false) // Show in photos experience status String @default("draft") @db.VarChar(50) showInUniverse Boolean @default(false) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt // Relations photos Photo[] // Will be removed after migration media AlbumMedia[] @@index([slug]) @@index([status]) } // Photos table model Photo { id Int @id @default(autoincrement()) albumId Int? mediaId Int? // Reference to the Media item filename String @db.VarChar(255) url String @db.VarChar(500) thumbnailUrl String? @db.VarChar(500) width Int? height Int? exifData Json? caption String? @db.Text displayOrder Int @default(0) // Individual publishing support slug String? @unique @db.VarChar(255) title String? @db.VarChar(255) description String? @db.Text status String @default("draft") @db.VarChar(50) publishedAt DateTime? showInPhotos Boolean @default(true) createdAt DateTime @default(now()) // Relations album Album? @relation(fields: [albumId], references: [id], onDelete: Cascade) media Media? @relation(fields: [mediaId], references: [id], onDelete: SetNull) @@index([slug]) @@index([status]) @@index([mediaId]) } // Media table (general uploads) model Media { id Int @id @default(autoincrement()) filename String @db.VarChar(255) originalName String? @db.VarChar(255) // Original filename from user (optional for backward compatibility) mimeType String @db.VarChar(100) size Int url String @db.Text thumbnailUrl String? @db.Text width Int? height Int? exifData Json? // EXIF data for photos description String? @db.Text // Description (used for alt text and captions) isPhotography Boolean @default(false) // Star for photos experience // Photo-specific fields (migrated from Photo model) photoCaption String? @db.Text // Caption when used as standalone photo photoTitle String? @db.VarChar(255) // Title when used as standalone photo photoDescription String? @db.Text // Description when used as standalone photo photoSlug String? @unique @db.VarChar(255) // Slug for standalone photo photoPublishedAt DateTime? // Published date for standalone photo usedIn Json @default("[]") // Track where media is used (legacy) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt // Relations usage MediaUsage[] photos Photo[] // Will be removed after migration albums AlbumMedia[] } // Media usage tracking table model MediaUsage { id Int @id @default(autoincrement()) mediaId Int contentType String @db.VarChar(50) // 'project', 'post', 'album' contentId Int fieldName String @db.VarChar(100) // 'featuredImage', 'logoUrl', 'gallery', 'content' createdAt DateTime @default(now()) updatedAt DateTime @updatedAt // Relations media Media @relation(fields: [mediaId], references: [id], onDelete: Cascade) @@unique([mediaId, contentType, contentId, fieldName]) @@index([mediaId]) @@index([contentType, contentId]) } // Album-Media relationship table (many-to-many) model AlbumMedia { id Int @id @default(autoincrement()) albumId Int mediaId Int displayOrder Int @default(0) createdAt DateTime @default(now()) // Relations album Album @relation(fields: [albumId], references: [id], onDelete: Cascade) media Media @relation(fields: [mediaId], references: [id], onDelete: Cascade) @@unique([albumId, mediaId]) @@index([albumId]) @@index([mediaId]) }