Add image upload and edit functions

This commit is contained in:
2025-12-20 16:34:50 +01:00
parent 96fa12993b
commit dfb6f7042a
72 changed files with 7413 additions and 81 deletions

View File

@ -0,0 +1,298 @@
-- CreateTable
CREATE TABLE "Artwork" (
"id" TEXT NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
"sortIndex" INTEGER NOT NULL DEFAULT 0,
"name" TEXT NOT NULL,
"slug" TEXT NOT NULL,
"altText" TEXT,
"description" TEXT,
"notes" TEXT,
"month" INTEGER,
"year" INTEGER,
"okLabL" DOUBLE PRECISION,
"okLabA" DOUBLE PRECISION,
"okLabB" DOUBLE PRECISION,
"creationDate" TIMESTAMP(3),
"needsWork" BOOLEAN NOT NULL DEFAULT true,
"nsfw" BOOLEAN NOT NULL DEFAULT false,
"published" BOOLEAN NOT NULL DEFAULT false,
"setAsHeader" BOOLEAN NOT NULL DEFAULT false,
"fileId" TEXT NOT NULL,
"galleryId" TEXT,
CONSTRAINT "Artwork_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "FileData" (
"id" TEXT NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
"fileKey" TEXT NOT NULL,
"originalFile" TEXT NOT NULL,
"fileType" TEXT NOT NULL,
"name" TEXT NOT NULL,
"fileSize" INTEGER NOT NULL,
CONSTRAINT "FileData_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Album" (
"id" TEXT NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
"sortIndex" INTEGER NOT NULL DEFAULT 0,
"name" TEXT NOT NULL,
"slug" TEXT NOT NULL,
"description" TEXT,
CONSTRAINT "Album_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Gallery" (
"id" TEXT NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
"sortIndex" INTEGER NOT NULL DEFAULT 0,
"name" TEXT NOT NULL,
"slug" TEXT NOT NULL,
"description" TEXT,
CONSTRAINT "Gallery_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "ArtCategory" (
"id" TEXT NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
"sortIndex" INTEGER NOT NULL DEFAULT 0,
"name" TEXT NOT NULL,
"slug" TEXT NOT NULL,
"description" TEXT,
CONSTRAINT "ArtCategory_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "ArtTag" (
"id" TEXT NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
"sortIndex" INTEGER NOT NULL DEFAULT 0,
"name" TEXT NOT NULL,
"slug" TEXT NOT NULL,
"description" TEXT,
CONSTRAINT "ArtTag_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Color" (
"id" TEXT NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
"name" TEXT NOT NULL,
"type" TEXT NOT NULL,
"hex" TEXT,
"blue" INTEGER,
"green" INTEGER,
"red" INTEGER,
CONSTRAINT "Color_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "ArtworkColor" (
"id" TEXT NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
"artworkId" TEXT NOT NULL,
"colorId" TEXT NOT NULL,
"type" TEXT NOT NULL,
CONSTRAINT "ArtworkColor_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "ArtworkMetadata" (
"id" TEXT NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
"artworkId" TEXT NOT NULL,
"depth" TEXT NOT NULL,
"format" TEXT NOT NULL,
"space" TEXT NOT NULL,
"channels" INTEGER NOT NULL,
"height" INTEGER NOT NULL,
"width" INTEGER NOT NULL,
"autoOrientH" INTEGER,
"autoOrientW" INTEGER,
"bitsPerSample" INTEGER,
"density" INTEGER,
"hasAlpha" BOOLEAN,
"hasProfile" BOOLEAN,
"isPalette" BOOLEAN,
"isProgressive" BOOLEAN,
CONSTRAINT "ArtworkMetadata_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "FileVariant" (
"id" TEXT NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
"artworkId" TEXT NOT NULL,
"s3Key" TEXT NOT NULL,
"type" TEXT NOT NULL,
"height" INTEGER NOT NULL,
"width" INTEGER NOT NULL,
"fileExtension" TEXT,
"mimeType" TEXT,
"url" TEXT,
"sizeBytes" INTEGER,
CONSTRAINT "FileVariant_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "_AlbumToArtwork" (
"A" TEXT NOT NULL,
"B" TEXT NOT NULL,
CONSTRAINT "_AlbumToArtwork_AB_pkey" PRIMARY KEY ("A","B")
);
-- CreateTable
CREATE TABLE "_ArtCategoryToArtwork" (
"A" TEXT NOT NULL,
"B" TEXT NOT NULL,
CONSTRAINT "_ArtCategoryToArtwork_AB_pkey" PRIMARY KEY ("A","B")
);
-- CreateTable
CREATE TABLE "_ArtCategoryToArtTag" (
"A" TEXT NOT NULL,
"B" TEXT NOT NULL,
CONSTRAINT "_ArtCategoryToArtTag_AB_pkey" PRIMARY KEY ("A","B")
);
-- CreateTable
CREATE TABLE "_ArtTagToArtwork" (
"A" TEXT NOT NULL,
"B" TEXT NOT NULL,
CONSTRAINT "_ArtTagToArtwork_AB_pkey" PRIMARY KEY ("A","B")
);
-- CreateIndex
CREATE UNIQUE INDEX "Artwork_name_key" ON "Artwork"("name");
-- CreateIndex
CREATE UNIQUE INDEX "Artwork_slug_key" ON "Artwork"("slug");
-- CreateIndex
CREATE UNIQUE INDEX "Artwork_fileId_key" ON "Artwork"("fileId");
-- CreateIndex
CREATE UNIQUE INDEX "FileData_fileKey_key" ON "FileData"("fileKey");
-- CreateIndex
CREATE UNIQUE INDEX "FileData_originalFile_key" ON "FileData"("originalFile");
-- CreateIndex
CREATE UNIQUE INDEX "Album_name_key" ON "Album"("name");
-- CreateIndex
CREATE UNIQUE INDEX "Album_slug_key" ON "Album"("slug");
-- CreateIndex
CREATE UNIQUE INDEX "Gallery_name_key" ON "Gallery"("name");
-- CreateIndex
CREATE UNIQUE INDEX "Gallery_slug_key" ON "Gallery"("slug");
-- CreateIndex
CREATE UNIQUE INDEX "ArtCategory_name_key" ON "ArtCategory"("name");
-- CreateIndex
CREATE UNIQUE INDEX "ArtCategory_slug_key" ON "ArtCategory"("slug");
-- CreateIndex
CREATE UNIQUE INDEX "ArtTag_name_key" ON "ArtTag"("name");
-- CreateIndex
CREATE UNIQUE INDEX "ArtTag_slug_key" ON "ArtTag"("slug");
-- CreateIndex
CREATE UNIQUE INDEX "Color_name_key" ON "Color"("name");
-- CreateIndex
CREATE UNIQUE INDEX "ArtworkColor_artworkId_type_key" ON "ArtworkColor"("artworkId", "type");
-- CreateIndex
CREATE UNIQUE INDEX "ArtworkMetadata_artworkId_key" ON "ArtworkMetadata"("artworkId");
-- CreateIndex
CREATE UNIQUE INDEX "FileVariant_artworkId_type_key" ON "FileVariant"("artworkId", "type");
-- CreateIndex
CREATE INDEX "_AlbumToArtwork_B_index" ON "_AlbumToArtwork"("B");
-- CreateIndex
CREATE INDEX "_ArtCategoryToArtwork_B_index" ON "_ArtCategoryToArtwork"("B");
-- CreateIndex
CREATE INDEX "_ArtCategoryToArtTag_B_index" ON "_ArtCategoryToArtTag"("B");
-- CreateIndex
CREATE INDEX "_ArtTagToArtwork_B_index" ON "_ArtTagToArtwork"("B");
-- AddForeignKey
ALTER TABLE "Artwork" ADD CONSTRAINT "Artwork_fileId_fkey" FOREIGN KEY ("fileId") REFERENCES "FileData"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Artwork" ADD CONSTRAINT "Artwork_galleryId_fkey" FOREIGN KEY ("galleryId") REFERENCES "Gallery"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "ArtworkColor" ADD CONSTRAINT "ArtworkColor_artworkId_fkey" FOREIGN KEY ("artworkId") REFERENCES "Artwork"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "ArtworkColor" ADD CONSTRAINT "ArtworkColor_colorId_fkey" FOREIGN KEY ("colorId") REFERENCES "Color"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "ArtworkMetadata" ADD CONSTRAINT "ArtworkMetadata_artworkId_fkey" FOREIGN KEY ("artworkId") REFERENCES "Artwork"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "FileVariant" ADD CONSTRAINT "FileVariant_artworkId_fkey" FOREIGN KEY ("artworkId") REFERENCES "Artwork"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "_AlbumToArtwork" ADD CONSTRAINT "_AlbumToArtwork_A_fkey" FOREIGN KEY ("A") REFERENCES "Album"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "_AlbumToArtwork" ADD CONSTRAINT "_AlbumToArtwork_B_fkey" FOREIGN KEY ("B") REFERENCES "Artwork"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "_ArtCategoryToArtwork" ADD CONSTRAINT "_ArtCategoryToArtwork_A_fkey" FOREIGN KEY ("A") REFERENCES "ArtCategory"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "_ArtCategoryToArtwork" ADD CONSTRAINT "_ArtCategoryToArtwork_B_fkey" FOREIGN KEY ("B") REFERENCES "Artwork"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "_ArtCategoryToArtTag" ADD CONSTRAINT "_ArtCategoryToArtTag_A_fkey" FOREIGN KEY ("A") REFERENCES "ArtCategory"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "_ArtCategoryToArtTag" ADD CONSTRAINT "_ArtCategoryToArtTag_B_fkey" FOREIGN KEY ("B") REFERENCES "ArtTag"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "_ArtTagToArtwork" ADD CONSTRAINT "_ArtTagToArtwork_A_fkey" FOREIGN KEY ("A") REFERENCES "ArtTag"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "_ArtTagToArtwork" ADD CONSTRAINT "_ArtTagToArtwork_B_fkey" FOREIGN KEY ("B") REFERENCES "Artwork"("id") ON DELETE CASCADE ON UPDATE CASCADE;

View File

@ -0,0 +1,8 @@
/*
Warnings:
- Added the required column `uploadDate` to the `FileVariant` table without a default value. This is not possible if the table is not empty.
*/
-- AlterTable
ALTER TABLE "FileVariant" ADD COLUMN "uploadDate" TIMESTAMP(3) NOT NULL;

View File

@ -0,0 +1,12 @@
/*
Warnings:
- You are about to drop the column `uploadDate` on the `FileVariant` table. All the data in the column will be lost.
- Added the required column `uploadDate` to the `FileData` table without a default value. This is not possible if the table is not empty.
*/
-- AlterTable
ALTER TABLE "FileData" ADD COLUMN "uploadDate" TIMESTAMP(3) NOT NULL;
-- AlterTable
ALTER TABLE "FileVariant" DROP COLUMN "uploadDate";

View File

@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE "Artwork" ADD COLUMN "sortKey" INTEGER;

View File

@ -0,0 +1,3 @@
# Please do not edit this file manually
# It should be added in your version-control system (e.g., Git)
provider = "postgresql"

203
prisma/schema.prisma Normal file
View File

@ -0,0 +1,203 @@
// 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)
fileId String @unique
file FileData @relation(fields: [fileId], references: [id])
galleryId String?
gallery Gallery? @relation(fields: [galleryId], references: [id])
metadata ArtworkMetadata?
albums Album[]
categories ArtCategory[]
colors ArtworkColor[]
tags ArtTag[]
variants FileVariant[]
}
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[]
tags ArtTag[]
}
model ArtTag {
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[]
categories ArtCategory[]
}
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 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])
}