Initial commit: Kalendartool (Next.js, Prisma, Docker)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
Kühn
2026-10-08 14:38:04 +02:00
commit bc49c3074e
94 changed files with 12812 additions and 0 deletions

View File

@@ -0,0 +1,100 @@
-- Initiale Migration (manuell gepflegt, damit `prisma migrate deploy`
-- im Docker-Container ohne Datenbankzugriff zur Build-Zeit funktioniert).
-- Erzeugt aus prisma/schema.prisma mit: npx prisma migrate dev --name init
-- CreateEnum
CREATE TYPE "Role" AS ENUM ('ADMIN', 'USER');
CREATE TYPE "ReservationStatus" AS ENUM ('CONFIRMED', 'CANCELLED');
-- CreateTable
CREATE TABLE "users" (
"id" TEXT NOT NULL,
"email" TEXT NOT NULL,
"password_hash" TEXT NOT NULL,
"role" "Role" NOT NULL DEFAULT 'USER',
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMP(3) NOT NULL,
CONSTRAINT "users_pkey" PRIMARY KEY ("id")
);
CREATE TABLE "calendars" (
"id" TEXT NOT NULL,
"owner_id" TEXT NOT NULL,
"title" TEXT NOT NULL,
"description" TEXT,
"timezone" TEXT NOT NULL DEFAULT 'Europe/Berlin',
"is_active" BOOLEAN NOT NULL DEFAULT true,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMP(3) NOT NULL,
CONSTRAINT "calendars_pkey" PRIMARY KEY ("id")
);
CREATE TABLE "calendar_members" (
"id" TEXT NOT NULL,
"calendar_id" TEXT NOT NULL,
"user_id" TEXT NOT NULL,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "calendar_members_pkey" PRIMARY KEY ("id")
);
CREATE TABLE "reservations" (
"id" TEXT NOT NULL,
"calendar_id" TEXT NOT NULL,
"user_id" TEXT NOT NULL,
"title" TEXT NOT NULL,
"start_at" TIMESTAMP(3) NOT NULL,
"end_at" TIMESTAMP(3) NOT NULL,
"status" "ReservationStatus" NOT NULL DEFAULT 'CONFIRMED',
"notes" TEXT,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMP(3) NOT NULL,
CONSTRAINT "reservations_pkey" PRIMARY KEY ("id")
);
CREATE TABLE "invites" (
"id" TEXT NOT NULL,
"calendar_id" TEXT NOT NULL,
"token_hash" TEXT NOT NULL,
"expires_at" TIMESTAMP(3),
"used_at" TIMESTAMP(3),
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "invites_pkey" PRIMARY KEY ("id")
);
-- CreateIndex
CREATE UNIQUE INDEX "users_email_key" ON "users"("email");
CREATE UNIQUE INDEX "calendar_members_user_id_key" ON "calendar_members"("user_id");
CREATE INDEX "calendars_owner_id_idx" ON "calendars"("owner_id");
CREATE UNIQUE INDEX "calendar_members_calendar_id_user_id_key" ON "calendar_members"("calendar_id", "user_id");
CREATE INDEX "calendar_members_calendar_id_idx" ON "calendar_members"("calendar_id");
CREATE INDEX "reservations_calendar_id_start_at_idx" ON "reservations"("calendar_id", "start_at");
CREATE INDEX "reservations_user_id_idx" ON "reservations"("user_id");
CREATE UNIQUE INDEX "invites_token_hash_key" ON "invites"("token_hash");
CREATE INDEX "invites_calendar_id_idx" ON "invites"("calendar_id");
-- AddForeignKey
ALTER TABLE "calendars" ADD CONSTRAINT "calendars_owner_id_fkey" FOREIGN KEY ("owner_id") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE "calendar_members" ADD CONSTRAINT "calendar_members_calendar_id_fkey" FOREIGN KEY ("calendar_id") REFERENCES "calendars"("id") ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE "calendar_members" ADD CONSTRAINT "calendar_members_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE "reservations" ADD CONSTRAINT "reservations_calendar_id_fkey" FOREIGN KEY ("calendar_id") REFERENCES "calendars"("id") ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE "reservations" ADD CONSTRAINT "reservations_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE "invites" ADD CONSTRAINT "invites_calendar_id_fkey" FOREIGN KEY ("calendar_id") REFERENCES "calendars"("id") ON DELETE CASCADE ON UPDATE CASCADE;

View File

@@ -0,0 +1,14 @@
-- Migration: Kalender-Einstellungen fuer Reservierungsregeln.
-- max_reservation_minutes: maximale Reservierungsdauer in Minuten
-- (15..1440); 0 bedeutet unbegrenzt. Default 240 (4 Stunden).
-- show_title_to_members: duerfen Nicht-Admins die Titel fremder
-- Reservierungen sehen? Default true (bisheriges Verhalten).
-- show_notes_to_members: duerfen Nicht-Admins die Notizen fremder
-- Reservierungen sehen? Default false (bisheriges Verhalten).
-- AlterTable
ALTER TABLE "calendars" ADD COLUMN "max_reservation_minutes" INTEGER NOT NULL DEFAULT 240;
ALTER TABLE "calendars" ADD COLUMN "show_title_to_members" BOOLEAN NOT NULL DEFAULT true;
ALTER TABLE "calendars" ADD COLUMN "show_notes_to_members" BOOLEAN NOT NULL DEFAULT false;

View File

@@ -0,0 +1,10 @@
-- Migration: Username-Spalte fuer Benutzer.
-- username: frei waehlbarer Anzeigename (optional, eindeutig).
-- Im Profil-Badge wird username bevorzugt, sonst email angezeigt.
-- Bestehende Benutzer erhalten NULL; sie koennen den Namen im Profil setzen.
-- AlterTable
ALTER TABLE "users" ADD COLUMN "username" TEXT;
-- CreateIndex
CREATE UNIQUE INDEX "users_username_key" ON "users"("username");

View File

@@ -0,0 +1,12 @@
-- Migration: Case-insensitive Eindeutigkeit fuer Benutzernamen.
-- Bisher war nur "Anna" != "anna" geschuetzt (case-sensitiver Unique-
-- Index). Beide Varianten konnten gleichzeitig existieren und im
-- Profil-Badge/Reservierungslisten als Identitaet verwechselt werden.
-- Der neue funktionale Unique-Index auf lower(username) ist strenger
-- und deckt den alten Fall mit ab.
-- DropIndex
DROP INDEX "users_username_key";
-- CreateIndex (funktional; von Prisma-Introspektion nicht abbildbar)
CREATE UNIQUE INDEX "users_username_lower_key" ON "users"(lower("username"));

View File

@@ -0,0 +1,5 @@
-- Fügt die hub_id-Spalte hinzu: stabile User-ID der MultiToolApp-Plattform.
-- null = rein lokaler Account; unique verhindert doppelte Kopplung.
ALTER TABLE "users" ADD COLUMN "hub_id" TEXT;
CREATE UNIQUE INDEX "users_hub_id_key" ON "users"("hub_id");

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"