Files
2026-04-18 00:01:57 +01:00

146 lines
3.9 KiB
Plaintext

generator client {
provider = "prisma-client-js"
// Stable location for types + runtime; fixes TS not resolving `@prisma/client` → `.prisma/…` under pnpm + NodeNext
output = "../node_modules/.prisma/client"
}
datasource db {
provider = "postgresql"
}
enum UserRole {
ADMIN
EDITOR
AUTHOR
READER
}
enum ArticleStatus {
DRAFT
PUBLISHED
ARCHIVED
}
model User {
id String @id @default(uuid())
keycloakId String @unique
email String @unique
displayName String?
avatarKey String?
role UserRole @default(READER)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
articles Article[]
comments Comment[]
bookmarks Bookmark[]
}
model Category {
id String @id @default(uuid())
name String
slug String @unique
parentId String?
parent Category? @relation("CategoryTree", fields: [parentId], references: [id], onDelete: SetNull)
children Category[] @relation("CategoryTree")
articles ArticleCategory[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([parentId])
}
model Tag {
id String @id @default(uuid())
name String
slug String @unique
articles ArticleTag[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model Article {
id String @id @default(uuid())
title String
slug String @unique
content String @db.Text
excerpt String? @db.Text
status ArticleStatus @default(DRAFT)
publishedAt DateTime?
authorId String
author User @relation(fields: [authorId], references: [id], onDelete: Cascade)
categories ArticleCategory[]
tags ArticleTag[]
images ArticleImage[]
comments Comment[]
bookmarks Bookmark[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([status, publishedAt])
@@index([authorId])
}
model ArticleCategory {
articleId String
categoryId String
article Article @relation(fields: [articleId], references: [id], onDelete: Cascade)
category Category @relation(fields: [categoryId], references: [id], onDelete: Cascade)
@@id([articleId, categoryId])
}
model ArticleTag {
articleId String
tagId String
article Article @relation(fields: [articleId], references: [id], onDelete: Cascade)
tag Tag @relation(fields: [tagId], references: [id], onDelete: Cascade)
@@id([articleId, tagId])
}
model Image {
id String @id @default(uuid())
fileKey String @unique
articles ArticleImage[]
createdAt DateTime @default(now())
}
model ArticleImage {
articleId String
imageId String
sortOrder Int @default(0)
article Article @relation(fields: [articleId], references: [id], onDelete: Cascade)
image Image @relation(fields: [imageId], references: [id], onDelete: Cascade)
@@id([articleId, imageId])
@@index([articleId, sortOrder])
}
model Comment {
id String @id @default(uuid())
content String @db.Text
articleId String
userId String
parentId String?
article Article @relation(fields: [articleId], references: [id], onDelete: Cascade)
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
parent Comment? @relation("CommentThread", fields: [parentId], references: [id], onDelete: Cascade)
replies Comment[] @relation("CommentThread")
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([articleId])
@@index([parentId])
}
model Bookmark {
userId String
articleId String
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
article Article @relation(fields: [articleId], references: [id], onDelete: Cascade)
createdAt DateTime @default(now())
@@id([userId, articleId])
}