We had a lot of unnecessary complexity here due to post types that never ended up getting used. We also made the post slug field reactive and bound to the title field. We also fixed filters on the Universe admin page so we can filter by unpublished posts too (WIP) We also fixed the hover state of BackButton
154 lines
No EOL
5.6 KiB
Text
154 lines
No EOL
5.6 KiB
Text
// 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[]
|
|
|
|
@@index([slug])
|
|
@@index([status])
|
|
}
|
|
|
|
// Photos table
|
|
model Photo {
|
|
id Int @id @default(autoincrement())
|
|
albumId Int?
|
|
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)
|
|
|
|
@@index([slug])
|
|
@@index([status])
|
|
}
|
|
|
|
// 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
|
|
altText String? @db.Text // Alt text for accessibility
|
|
description String? @db.Text // Optional description
|
|
isPhotography Boolean @default(false) // Star for photos experience
|
|
usedIn Json @default("[]") // Track where media is used (legacy)
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
// Relations
|
|
usage MediaUsage[]
|
|
}
|
|
|
|
// 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])
|
|
} |