Files
jmartgraphix.com/server/prisma/migrations/20260723100000_init/migration.sql
T
jmartin 43928f7a49 Initial portfolio CMS: Fastify API + Vite SPA
Single-container app with Postgres catalog, Typesense search,
Authelia Remote-User admin, portfolio views, resume/PDF, media
uploads, and ArtStation import tooling.
2026-07-23 17:01:34 -04:00

169 lines
6.0 KiB
SQL

-- CreateEnum
CREATE TYPE "Visibility" AS ENUM ('published', 'draft', 'private');
-- CreateEnum
CREATE TYPE "MediaType" AS ENUM ('image', 'video', 'external');
-- CreateEnum
CREATE TYPE "VideoSource" AS ENUM ('youtube', 'vimeo', 'self_hosted', 'external');
-- CreateTable
CREATE TABLE "categories" (
"id" TEXT NOT NULL,
"name" TEXT NOT NULL,
"slug" TEXT NOT NULL,
"description" TEXT,
"sort_order" INTEGER NOT NULL DEFAULT 0,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMP(3) NOT NULL,
CONSTRAINT "categories_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "tags" (
"id" TEXT NOT NULL,
"name" TEXT NOT NULL,
"slug" TEXT NOT NULL,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "tags_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "projects" (
"id" TEXT NOT NULL,
"title" TEXT NOT NULL,
"slug" TEXT NOT NULL,
"description" TEXT NOT NULL DEFAULT '',
"short_description" TEXT,
"date" DATE,
"software" TEXT[] DEFAULT ARRAY[]::TEXT[],
"external_links" JSONB NOT NULL DEFAULT '[]',
"featured" BOOLEAN NOT NULL DEFAULT false,
"display_priority" INTEGER NOT NULL DEFAULT 0,
"visibility" "Visibility" NOT NULL DEFAULT 'draft',
"thumbnail_id" TEXT,
"source_url" TEXT,
"source_platform" TEXT,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMP(3) NOT NULL,
"published_at" TIMESTAMP(3),
CONSTRAINT "projects_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "project_categories" (
"project_id" TEXT NOT NULL,
"category_id" TEXT NOT NULL,
CONSTRAINT "project_categories_pkey" PRIMARY KEY ("project_id","category_id")
);
-- CreateTable
CREATE TABLE "project_tags" (
"project_id" TEXT NOT NULL,
"tag_id" TEXT NOT NULL,
CONSTRAINT "project_tags_pkey" PRIMARY KEY ("project_id","tag_id")
);
-- CreateTable
CREATE TABLE "media" (
"id" TEXT NOT NULL,
"project_id" TEXT,
"type" "MediaType" NOT NULL DEFAULT 'image',
"url" TEXT NOT NULL,
"thumbnail_url" TEXT,
"filename" TEXT,
"mime_type" TEXT,
"width" INTEGER,
"height" INTEGER,
"size_bytes" INTEGER,
"alt" TEXT,
"caption" TEXT,
"sort_order" INTEGER NOT NULL DEFAULT 0,
"video_source" "VideoSource",
"video_id" TEXT,
"external_url" TEXT,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "media_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "portfolio_views" (
"id" TEXT NOT NULL,
"name" TEXT NOT NULL,
"slug" TEXT NOT NULL,
"description" TEXT,
"default_sort" TEXT NOT NULL DEFAULT 'priority',
"show_others" BOOLEAN NOT NULL DEFAULT true,
"is_active" BOOLEAN NOT NULL DEFAULT true,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMP(3) NOT NULL,
CONSTRAINT "portfolio_views_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "portfolio_view_categories" (
"view_id" TEXT NOT NULL,
"category_id" TEXT NOT NULL,
"priority" INTEGER NOT NULL DEFAULT 0,
CONSTRAINT "portfolio_view_categories_pkey" PRIMARY KEY ("view_id","category_id")
);
-- CreateTable
CREATE TABLE "resumes" (
"id" TEXT NOT NULL,
"is_active" BOOLEAN NOT NULL DEFAULT true,
"full_name" TEXT NOT NULL,
"title" TEXT NOT NULL DEFAULT '',
"email" TEXT,
"phone" TEXT,
"location" TEXT,
"website" TEXT,
"summary" TEXT NOT NULL DEFAULT '',
"sections" JSONB NOT NULL DEFAULT '[]',
"html_content" TEXT,
"theme" TEXT NOT NULL DEFAULT 'dark',
"updated_at" TIMESTAMP(3) NOT NULL,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "resumes_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "site_settings" (
"key" TEXT NOT NULL,
"value" JSONB NOT NULL,
"updated_at" TIMESTAMP(3) NOT NULL,
CONSTRAINT "site_settings_pkey" PRIMARY KEY ("key")
);
-- CreateIndex
CREATE UNIQUE INDEX "categories_name_key" ON "categories"("name");
CREATE UNIQUE INDEX "categories_slug_key" ON "categories"("slug");
CREATE UNIQUE INDEX "tags_name_key" ON "tags"("name");
CREATE UNIQUE INDEX "tags_slug_key" ON "tags"("slug");
CREATE UNIQUE INDEX "projects_slug_key" ON "projects"("slug");
CREATE INDEX "projects_visibility_display_priority_idx" ON "projects"("visibility", "display_priority");
CREATE INDEX "projects_featured_idx" ON "projects"("featured");
CREATE INDEX "projects_date_idx" ON "projects"("date");
CREATE INDEX "media_project_id_sort_order_idx" ON "media"("project_id", "sort_order");
CREATE UNIQUE INDEX "portfolio_views_slug_key" ON "portfolio_views"("slug");
-- AddForeignKeys
ALTER TABLE "project_categories" ADD CONSTRAINT "project_categories_project_id_fkey" FOREIGN KEY ("project_id") REFERENCES "projects"("id") ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE "project_categories" ADD CONSTRAINT "project_categories_category_id_fkey" FOREIGN KEY ("category_id") REFERENCES "categories"("id") ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE "project_tags" ADD CONSTRAINT "project_tags_project_id_fkey" FOREIGN KEY ("project_id") REFERENCES "projects"("id") ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE "project_tags" ADD CONSTRAINT "project_tags_tag_id_fkey" FOREIGN KEY ("tag_id") REFERENCES "tags"("id") ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE "media" ADD CONSTRAINT "media_project_id_fkey" FOREIGN KEY ("project_id") REFERENCES "projects"("id") ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE "projects" ADD CONSTRAINT "projects_thumbnail_id_fkey" FOREIGN KEY ("thumbnail_id") REFERENCES "media"("id") ON DELETE SET NULL ON UPDATE CASCADE;
ALTER TABLE "portfolio_view_categories" ADD CONSTRAINT "portfolio_view_categories_view_id_fkey" FOREIGN KEY ("view_id") REFERENCES "portfolio_views"("id") ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE "portfolio_view_categories" ADD CONSTRAINT "portfolio_view_categories_category_id_fkey" FOREIGN KEY ("category_id") REFERENCES "categories"("id") ON DELETE CASCADE ON UPDATE CASCADE;