Harden authentication, tenant isolation and security boundaries
This commit is contained in:
@@ -0,0 +1,713 @@
|
||||
-- CreateSchema
|
||||
CREATE SCHEMA IF NOT EXISTS "public";
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "UserRole" AS ENUM ('SUPERADMIN', 'ADMIN', 'KOORDINATOR', 'ERZIEHER', 'ELTERN');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "InvitationStatus" AS ENUM ('PENDING', 'ACCEPTED', 'EXPIRED', 'REVOKED');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "TerminType" AS ENUM ('KITA_FEST', 'SCHLIESSTAG', 'TEAMTAG', 'MITMACH_TAG', 'ELTERNABEND', 'MITGLIEDERVERSAMMLUNG', 'ELTERNCAFE', 'GEBURTSTAG_INTERN', 'GEBURTSTAG_EXTERN', 'SONSTIGES');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "TerminStatus" AS ENUM ('PENDING', 'CONFIRMED', 'REJECTED', 'CANCELLED');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "EventParticipationStatus" AS ENUM ('ATTENDING', 'NOT_ATTENDING');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "AuditTargetType" AS ENUM ('KITA', 'USER');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "NotdienstPlanStatus" AS ENUM ('DRAFT', 'PUBLISHED');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "NotdienstAlertStatus" AS ENUM ('PENDING', 'CONFIRMED', 'CANCELLED');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "NotdienstSwapStatus" AS ENUM ('PENDING', 'ACCEPTED', 'DECLINED', 'CANCELLED');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "DutyAssignmentStatus" AS ENUM ('PLANNED', 'DONE', 'CANCELLED');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "AbsenceReason" AS ENUM ('ILLNESS', 'VACATION', 'OTHER');
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "kitas" (
|
||||
"id" TEXT NOT NULL,
|
||||
"name" TEXT NOT NULL,
|
||||
"slug" TEXT NOT NULL,
|
||||
"notdienstModuleEnabled" BOOLEAN NOT NULL DEFAULT true,
|
||||
"terminModuleEnabled" BOOLEAN NOT NULL DEFAULT true,
|
||||
"adressbuchModuleEnabled" BOOLEAN NOT NULL DEFAULT true,
|
||||
"notdienstMinPerChildPerMonth" INTEGER NOT NULL DEFAULT 2,
|
||||
"notdienstReminderDaysBefore" INTEGER NOT NULL DEFAULT 7,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "kitas_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "families" (
|
||||
"id" TEXT NOT NULL,
|
||||
"kitaId" TEXT NOT NULL,
|
||||
"name" TEXT NOT NULL,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "families_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "users" (
|
||||
"id" TEXT NOT NULL,
|
||||
"kitaId" TEXT,
|
||||
"familyId" TEXT,
|
||||
"email" TEXT NOT NULL,
|
||||
"passwordHash" TEXT NOT NULL,
|
||||
"firstName" TEXT NOT NULL,
|
||||
"lastName" TEXT NOT NULL,
|
||||
"role" "UserRole" NOT NULL DEFAULT 'ELTERN',
|
||||
"phone" TEXT,
|
||||
"street" TEXT,
|
||||
"postalCode" TEXT,
|
||||
"city" TEXT,
|
||||
"privacyPolicyAcceptedAt" TIMESTAMP(3),
|
||||
"privacyPolicyVersion" TEXT,
|
||||
"directoryOptInAt" TIMESTAMP(3),
|
||||
"emailVerifiedAt" TIMESTAMP(3),
|
||||
"lastLoginAt" TIMESTAMP(3),
|
||||
"failedLoginAttempts" INTEGER NOT NULL DEFAULT 0,
|
||||
"lockedUntil" TIMESTAMP(3),
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "users_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "children" (
|
||||
"id" TEXT NOT NULL,
|
||||
"kitaId" TEXT NOT NULL,
|
||||
"familyId" TEXT NOT NULL,
|
||||
"firstName" TEXT NOT NULL,
|
||||
"lastName" TEXT NOT NULL,
|
||||
"dateOfBirth" TIMESTAMP(3),
|
||||
"notes" TEXT,
|
||||
"active" BOOLEAN NOT NULL DEFAULT true,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "children_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "educators" (
|
||||
"id" TEXT NOT NULL,
|
||||
"kitaId" TEXT NOT NULL,
|
||||
"firstName" TEXT NOT NULL,
|
||||
"lastName" TEXT NOT NULL,
|
||||
"active" BOOLEAN NOT NULL DEFAULT true,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "educators_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "parent_duties" (
|
||||
"id" TEXT NOT NULL,
|
||||
"kitaId" TEXT NOT NULL,
|
||||
"name" TEXT NOT NULL,
|
||||
"description" TEXT,
|
||||
"active" BOOLEAN NOT NULL DEFAULT true,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "parent_duties_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "parent_duty_assignments" (
|
||||
"id" TEXT NOT NULL,
|
||||
"kitaId" TEXT NOT NULL,
|
||||
"dutyId" TEXT NOT NULL,
|
||||
"userId" TEXT NOT NULL,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "parent_duty_assignments_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "duty_types" (
|
||||
"id" TEXT NOT NULL,
|
||||
"kitaId" TEXT NOT NULL,
|
||||
"name" TEXT NOT NULL,
|
||||
"description" TEXT,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "duty_types_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "duty_assignments" (
|
||||
"id" TEXT NOT NULL,
|
||||
"kitaId" TEXT NOT NULL,
|
||||
"familyId" TEXT NOT NULL,
|
||||
"dutyTypeId" TEXT NOT NULL,
|
||||
"startDate" DATE NOT NULL,
|
||||
"endDate" DATE NOT NULL,
|
||||
"status" "DutyAssignmentStatus" NOT NULL DEFAULT 'PLANNED',
|
||||
"reminderSentAt" TIMESTAMP(3),
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "duty_assignments_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "absences" (
|
||||
"id" TEXT NOT NULL,
|
||||
"kitaId" TEXT NOT NULL,
|
||||
"childId" TEXT NOT NULL,
|
||||
"startDate" DATE NOT NULL,
|
||||
"endDate" DATE NOT NULL,
|
||||
"reason" "AbsenceReason" NOT NULL,
|
||||
"note" TEXT,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "absences_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "announcements" (
|
||||
"id" TEXT NOT NULL,
|
||||
"kitaId" TEXT NOT NULL,
|
||||
"title" TEXT NOT NULL,
|
||||
"content" TEXT NOT NULL,
|
||||
"authorId" TEXT NOT NULL,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "announcements_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "attachments" (
|
||||
"id" TEXT NOT NULL,
|
||||
"announcementId" TEXT NOT NULL,
|
||||
"fileName" TEXT NOT NULL,
|
||||
"fileUrl" TEXT NOT NULL,
|
||||
"fileType" TEXT NOT NULL,
|
||||
|
||||
CONSTRAINT "attachments_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "announcement_reads" (
|
||||
"id" TEXT NOT NULL,
|
||||
"userId" TEXT NOT NULL,
|
||||
"announcementId" TEXT NOT NULL,
|
||||
"readAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "announcement_reads_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "invitations" (
|
||||
"id" TEXT NOT NULL,
|
||||
"kitaId" TEXT NOT NULL,
|
||||
"email" TEXT NOT NULL,
|
||||
"role" "UserRole" NOT NULL DEFAULT 'ELTERN',
|
||||
"token" TEXT NOT NULL,
|
||||
"status" "InvitationStatus" NOT NULL DEFAULT 'PENDING',
|
||||
"expiresAt" TIMESTAMP(3) NOT NULL,
|
||||
"acceptedAt" TIMESTAMP(3),
|
||||
"invitedById" TEXT,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "invitations_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "termine" (
|
||||
"id" TEXT NOT NULL,
|
||||
"kitaId" TEXT NOT NULL,
|
||||
"title" TEXT NOT NULL,
|
||||
"description" TEXT,
|
||||
"type" "TerminType" NOT NULL,
|
||||
"status" "TerminStatus" NOT NULL DEFAULT 'PENDING',
|
||||
"startDate" TIMESTAMP(3) NOT NULL,
|
||||
"endDate" TIMESTAMP(3) NOT NULL,
|
||||
"allDay" BOOLEAN NOT NULL DEFAULT false,
|
||||
"mitbringselListEnabled" BOOLEAN NOT NULL DEFAULT false,
|
||||
"requiresRsvp" BOOLEAN NOT NULL DEFAULT false,
|
||||
"rsvpDeadline" TIMESTAMP(3),
|
||||
"participantInfo" TEXT,
|
||||
"createdById" TEXT,
|
||||
"approvedById" TEXT,
|
||||
"approvedAt" TIMESTAMP(3),
|
||||
"rejectionReason" TEXT,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "termine_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "event_participations" (
|
||||
"id" TEXT NOT NULL,
|
||||
"kitaId" TEXT NOT NULL,
|
||||
"eventId" TEXT NOT NULL,
|
||||
"childId" TEXT NOT NULL,
|
||||
"status" "EventParticipationStatus" NOT NULL,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "event_participations_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "mitbringsel_items" (
|
||||
"id" TEXT NOT NULL,
|
||||
"kitaId" TEXT NOT NULL,
|
||||
"terminId" TEXT NOT NULL,
|
||||
"userId" TEXT NOT NULL,
|
||||
"content" TEXT NOT NULL,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "mitbringsel_items_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "notdienst_plans" (
|
||||
"id" TEXT NOT NULL,
|
||||
"kitaId" TEXT NOT NULL,
|
||||
"year" INTEGER NOT NULL,
|
||||
"month" INTEGER NOT NULL,
|
||||
"status" "NotdienstPlanStatus" NOT NULL DEFAULT 'DRAFT',
|
||||
"createdById" TEXT,
|
||||
"publishedAt" TIMESTAMP(3),
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "notdienst_plans_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "notdienst_availabilities" (
|
||||
"id" TEXT NOT NULL,
|
||||
"kitaId" TEXT NOT NULL,
|
||||
"childId" TEXT NOT NULL,
|
||||
"userId" TEXT NOT NULL,
|
||||
"date" DATE NOT NULL,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "notdienst_availabilities_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "notdienst_assignments" (
|
||||
"id" TEXT NOT NULL,
|
||||
"kitaId" TEXT NOT NULL,
|
||||
"planId" TEXT NOT NULL,
|
||||
"childId" TEXT NOT NULL,
|
||||
"date" DATE NOT NULL,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "notdienst_assignments_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "notdienst_swap_requests" (
|
||||
"id" TEXT NOT NULL,
|
||||
"kitaId" TEXT NOT NULL,
|
||||
"requesterUserId" TEXT NOT NULL,
|
||||
"requesterFamilyId" TEXT NOT NULL,
|
||||
"targetAssignmentId" TEXT NOT NULL,
|
||||
"offeredAssignmentId" TEXT NOT NULL,
|
||||
"status" "NotdienstSwapStatus" NOT NULL DEFAULT 'PENDING',
|
||||
"message" TEXT,
|
||||
"respondedById" TEXT,
|
||||
"respondedAt" TIMESTAMP(3),
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "notdienst_swap_requests_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "notdienst_alerts" (
|
||||
"id" TEXT NOT NULL,
|
||||
"kitaId" TEXT NOT NULL,
|
||||
"assignmentId" TEXT NOT NULL,
|
||||
"parentUserId" TEXT NOT NULL,
|
||||
"triggeredById" TEXT,
|
||||
"educatorId" TEXT,
|
||||
"status" "NotdienstAlertStatus" NOT NULL DEFAULT 'PENDING',
|
||||
"confirmationToken" TEXT NOT NULL,
|
||||
"triggeredAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"confirmedAt" TIMESTAMP(3),
|
||||
"notes" TEXT,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "notdienst_alerts_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "audit_logs" (
|
||||
"id" TEXT NOT NULL,
|
||||
"actorUserId" TEXT,
|
||||
"actorEmail" TEXT NOT NULL,
|
||||
"action" TEXT NOT NULL,
|
||||
"targetType" "AuditTargetType" NOT NULL,
|
||||
"targetId" TEXT NOT NULL,
|
||||
"targetLabel" TEXT NOT NULL,
|
||||
"targetKitaId" TEXT,
|
||||
"metadata" JSONB,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "audit_logs_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "verification_tokens" (
|
||||
"identifier" TEXT NOT NULL,
|
||||
"token" TEXT NOT NULL,
|
||||
"expires" TIMESTAMP(3) NOT NULL
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "kitas_slug_key" ON "kitas"("slug");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "families_kitaId_idx" ON "families"("kitaId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "users_email_key" ON "users"("email");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "users_kitaId_idx" ON "users"("kitaId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "users_familyId_idx" ON "users"("familyId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "users_kitaId_role_idx" ON "users"("kitaId", "role");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "children_kitaId_idx" ON "children"("kitaId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "children_familyId_idx" ON "children"("familyId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "educators_kitaId_idx" ON "educators"("kitaId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "parent_duties_kitaId_idx" ON "parent_duties"("kitaId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "parent_duties_kitaId_name_key" ON "parent_duties"("kitaId", "name");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "parent_duty_assignments_kitaId_idx" ON "parent_duty_assignments"("kitaId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "parent_duty_assignments_userId_idx" ON "parent_duty_assignments"("userId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "parent_duty_assignments_dutyId_userId_key" ON "parent_duty_assignments"("dutyId", "userId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "duty_types_kitaId_idx" ON "duty_types"("kitaId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "duty_types_kitaId_name_key" ON "duty_types"("kitaId", "name");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "duty_assignments_kitaId_startDate_idx" ON "duty_assignments"("kitaId", "startDate");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "duty_assignments_familyId_startDate_idx" ON "duty_assignments"("familyId", "startDate");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "duty_assignments_kitaId_dutyTypeId_startDate_key" ON "duty_assignments"("kitaId", "dutyTypeId", "startDate");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "absences_kitaId_startDate_endDate_idx" ON "absences"("kitaId", "startDate", "endDate");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "absences_childId_startDate_idx" ON "absences"("childId", "startDate");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "announcements_kitaId_createdAt_idx" ON "announcements"("kitaId", "createdAt");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "announcements_authorId_idx" ON "announcements"("authorId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "attachments_announcementId_idx" ON "attachments"("announcementId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "announcement_reads_announcementId_idx" ON "announcement_reads"("announcementId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "announcement_reads_userId_announcementId_key" ON "announcement_reads"("userId", "announcementId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "invitations_token_key" ON "invitations"("token");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "invitations_kitaId_idx" ON "invitations"("kitaId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "invitations_kitaId_email_key" ON "invitations"("kitaId", "email");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "termine_kitaId_startDate_idx" ON "termine"("kitaId", "startDate");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "termine_kitaId_status_idx" ON "termine"("kitaId", "status");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "event_participations_kitaId_idx" ON "event_participations"("kitaId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "event_participations_childId_idx" ON "event_participations"("childId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "event_participations_eventId_childId_key" ON "event_participations"("eventId", "childId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "mitbringsel_items_kitaId_idx" ON "mitbringsel_items"("kitaId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "mitbringsel_items_terminId_idx" ON "mitbringsel_items"("terminId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "notdienst_plans_kitaId_idx" ON "notdienst_plans"("kitaId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "notdienst_plans_kitaId_year_month_key" ON "notdienst_plans"("kitaId", "year", "month");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "notdienst_availabilities_kitaId_date_idx" ON "notdienst_availabilities"("kitaId", "date");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "notdienst_availabilities_userId_idx" ON "notdienst_availabilities"("userId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "notdienst_availabilities_childId_date_key" ON "notdienst_availabilities"("childId", "date");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "notdienst_assignments_kitaId_date_idx" ON "notdienst_assignments"("kitaId", "date");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "notdienst_assignments_planId_date_key" ON "notdienst_assignments"("planId", "date");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "notdienst_swap_requests_kitaId_status_idx" ON "notdienst_swap_requests"("kitaId", "status");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "notdienst_swap_requests_requesterFamilyId_status_idx" ON "notdienst_swap_requests"("requesterFamilyId", "status");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "notdienst_swap_requests_targetAssignmentId_status_idx" ON "notdienst_swap_requests"("targetAssignmentId", "status");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "notdienst_swap_requests_offeredAssignmentId_status_idx" ON "notdienst_swap_requests"("offeredAssignmentId", "status");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "notdienst_alerts_confirmationToken_key" ON "notdienst_alerts"("confirmationToken");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "notdienst_alerts_kitaId_idx" ON "notdienst_alerts"("kitaId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "notdienst_alerts_assignmentId_idx" ON "notdienst_alerts"("assignmentId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "notdienst_alerts_parentUserId_idx" ON "notdienst_alerts"("parentUserId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "audit_logs_actorUserId_idx" ON "audit_logs"("actorUserId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "audit_logs_targetType_targetId_idx" ON "audit_logs"("targetType", "targetId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "audit_logs_targetKitaId_idx" ON "audit_logs"("targetKitaId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "audit_logs_createdAt_idx" ON "audit_logs"("createdAt");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "verification_tokens_token_key" ON "verification_tokens"("token");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "verification_tokens_identifier_token_key" ON "verification_tokens"("identifier", "token");
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "families" ADD CONSTRAINT "families_kitaId_fkey" FOREIGN KEY ("kitaId") REFERENCES "kitas"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "users" ADD CONSTRAINT "users_kitaId_fkey" FOREIGN KEY ("kitaId") REFERENCES "kitas"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "users" ADD CONSTRAINT "users_familyId_fkey" FOREIGN KEY ("familyId") REFERENCES "families"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "children" ADD CONSTRAINT "children_kitaId_fkey" FOREIGN KEY ("kitaId") REFERENCES "kitas"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "children" ADD CONSTRAINT "children_familyId_fkey" FOREIGN KEY ("familyId") REFERENCES "families"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "educators" ADD CONSTRAINT "educators_kitaId_fkey" FOREIGN KEY ("kitaId") REFERENCES "kitas"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "parent_duties" ADD CONSTRAINT "parent_duties_kitaId_fkey" FOREIGN KEY ("kitaId") REFERENCES "kitas"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "parent_duty_assignments" ADD CONSTRAINT "parent_duty_assignments_kitaId_fkey" FOREIGN KEY ("kitaId") REFERENCES "kitas"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "parent_duty_assignments" ADD CONSTRAINT "parent_duty_assignments_dutyId_fkey" FOREIGN KEY ("dutyId") REFERENCES "parent_duties"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "parent_duty_assignments" ADD CONSTRAINT "parent_duty_assignments_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "duty_types" ADD CONSTRAINT "duty_types_kitaId_fkey" FOREIGN KEY ("kitaId") REFERENCES "kitas"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "duty_assignments" ADD CONSTRAINT "duty_assignments_kitaId_fkey" FOREIGN KEY ("kitaId") REFERENCES "kitas"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "duty_assignments" ADD CONSTRAINT "duty_assignments_familyId_fkey" FOREIGN KEY ("familyId") REFERENCES "families"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "duty_assignments" ADD CONSTRAINT "duty_assignments_dutyTypeId_fkey" FOREIGN KEY ("dutyTypeId") REFERENCES "duty_types"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "absences" ADD CONSTRAINT "absences_kitaId_fkey" FOREIGN KEY ("kitaId") REFERENCES "kitas"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "absences" ADD CONSTRAINT "absences_childId_fkey" FOREIGN KEY ("childId") REFERENCES "children"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "announcements" ADD CONSTRAINT "announcements_kitaId_fkey" FOREIGN KEY ("kitaId") REFERENCES "kitas"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "announcements" ADD CONSTRAINT "announcements_authorId_fkey" FOREIGN KEY ("authorId") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "attachments" ADD CONSTRAINT "attachments_announcementId_fkey" FOREIGN KEY ("announcementId") REFERENCES "announcements"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "announcement_reads" ADD CONSTRAINT "announcement_reads_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "announcement_reads" ADD CONSTRAINT "announcement_reads_announcementId_fkey" FOREIGN KEY ("announcementId") REFERENCES "announcements"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "invitations" ADD CONSTRAINT "invitations_kitaId_fkey" FOREIGN KEY ("kitaId") REFERENCES "kitas"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "invitations" ADD CONSTRAINT "invitations_invitedById_fkey" FOREIGN KEY ("invitedById") REFERENCES "users"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "termine" ADD CONSTRAINT "termine_kitaId_fkey" FOREIGN KEY ("kitaId") REFERENCES "kitas"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "termine" ADD CONSTRAINT "termine_createdById_fkey" FOREIGN KEY ("createdById") REFERENCES "users"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "termine" ADD CONSTRAINT "termine_approvedById_fkey" FOREIGN KEY ("approvedById") REFERENCES "users"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "event_participations" ADD CONSTRAINT "event_participations_kitaId_fkey" FOREIGN KEY ("kitaId") REFERENCES "kitas"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "event_participations" ADD CONSTRAINT "event_participations_eventId_fkey" FOREIGN KEY ("eventId") REFERENCES "termine"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "event_participations" ADD CONSTRAINT "event_participations_childId_fkey" FOREIGN KEY ("childId") REFERENCES "children"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "mitbringsel_items" ADD CONSTRAINT "mitbringsel_items_kitaId_fkey" FOREIGN KEY ("kitaId") REFERENCES "kitas"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "mitbringsel_items" ADD CONSTRAINT "mitbringsel_items_terminId_fkey" FOREIGN KEY ("terminId") REFERENCES "termine"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "mitbringsel_items" ADD CONSTRAINT "mitbringsel_items_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "notdienst_plans" ADD CONSTRAINT "notdienst_plans_kitaId_fkey" FOREIGN KEY ("kitaId") REFERENCES "kitas"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "notdienst_plans" ADD CONSTRAINT "notdienst_plans_createdById_fkey" FOREIGN KEY ("createdById") REFERENCES "users"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "notdienst_availabilities" ADD CONSTRAINT "notdienst_availabilities_kitaId_fkey" FOREIGN KEY ("kitaId") REFERENCES "kitas"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "notdienst_availabilities" ADD CONSTRAINT "notdienst_availabilities_childId_fkey" FOREIGN KEY ("childId") REFERENCES "children"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "notdienst_availabilities" ADD CONSTRAINT "notdienst_availabilities_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "notdienst_assignments" ADD CONSTRAINT "notdienst_assignments_kitaId_fkey" FOREIGN KEY ("kitaId") REFERENCES "kitas"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "notdienst_assignments" ADD CONSTRAINT "notdienst_assignments_planId_fkey" FOREIGN KEY ("planId") REFERENCES "notdienst_plans"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "notdienst_assignments" ADD CONSTRAINT "notdienst_assignments_childId_fkey" FOREIGN KEY ("childId") REFERENCES "children"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "notdienst_swap_requests" ADD CONSTRAINT "notdienst_swap_requests_kitaId_fkey" FOREIGN KEY ("kitaId") REFERENCES "kitas"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "notdienst_swap_requests" ADD CONSTRAINT "notdienst_swap_requests_requesterUserId_fkey" FOREIGN KEY ("requesterUserId") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "notdienst_swap_requests" ADD CONSTRAINT "notdienst_swap_requests_requesterFamilyId_fkey" FOREIGN KEY ("requesterFamilyId") REFERENCES "families"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "notdienst_swap_requests" ADD CONSTRAINT "notdienst_swap_requests_targetAssignmentId_fkey" FOREIGN KEY ("targetAssignmentId") REFERENCES "notdienst_assignments"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "notdienst_swap_requests" ADD CONSTRAINT "notdienst_swap_requests_offeredAssignmentId_fkey" FOREIGN KEY ("offeredAssignmentId") REFERENCES "notdienst_assignments"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "notdienst_swap_requests" ADD CONSTRAINT "notdienst_swap_requests_respondedById_fkey" FOREIGN KEY ("respondedById") REFERENCES "users"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "notdienst_alerts" ADD CONSTRAINT "notdienst_alerts_kitaId_fkey" FOREIGN KEY ("kitaId") REFERENCES "kitas"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "notdienst_alerts" ADD CONSTRAINT "notdienst_alerts_assignmentId_fkey" FOREIGN KEY ("assignmentId") REFERENCES "notdienst_assignments"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "notdienst_alerts" ADD CONSTRAINT "notdienst_alerts_parentUserId_fkey" FOREIGN KEY ("parentUserId") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "notdienst_alerts" ADD CONSTRAINT "notdienst_alerts_triggeredById_fkey" FOREIGN KEY ("triggeredById") REFERENCES "users"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "notdienst_alerts" ADD CONSTRAINT "notdienst_alerts_educatorId_fkey" FOREIGN KEY ("educatorId") REFERENCES "educators"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "audit_logs" ADD CONSTRAINT "audit_logs_actorUserId_fkey" FOREIGN KEY ("actorUserId") REFERENCES "users"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
@@ -0,0 +1,102 @@
|
||||
BEGIN;
|
||||
-- AlterTable
|
||||
ALTER TABLE "users" ADD COLUMN "disabledAt" TIMESTAMP(3),
|
||||
ADD COLUMN "sessionVersion" INTEGER NOT NULL DEFAULT 0;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "rate_limit_buckets" (
|
||||
"key" TEXT NOT NULL,
|
||||
"count" INTEGER NOT NULL,
|
||||
"resetAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "rate_limit_buckets_pkey" PRIMARY KEY ("key")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "pending_registrations" (
|
||||
"email" TEXT NOT NULL,
|
||||
"firstName" TEXT NOT NULL,
|
||||
"lastName" TEXT NOT NULL,
|
||||
"tokenHash" TEXT NOT NULL,
|
||||
"expiresAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "pending_registrations_pkey" PRIMARY KEY ("email")
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "rate_limit_buckets_resetAt_idx" ON "rate_limit_buckets"("resetAt");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "pending_registrations_tokenHash_key" ON "pending_registrations"("tokenHash");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "pending_registrations_expiresAt_idx" ON "pending_registrations"("expiresAt");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "families_id_kitaId_key" ON "families"("id", "kitaId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "users_id_kitaId_key" ON "users"("id", "kitaId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "children_id_kitaId_key" ON "children"("id", "kitaId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "educators_id_kitaId_key" ON "educators"("id", "kitaId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "parent_duties_id_kitaId_key" ON "parent_duties"("id", "kitaId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "duty_types_id_kitaId_key" ON "duty_types"("id", "kitaId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "termine_id_kitaId_key" ON "termine"("id", "kitaId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "notdienst_plans_id_kitaId_key" ON "notdienst_plans"("id", "kitaId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "notdienst_assignments_id_kitaId_key" ON "notdienst_assignments"("id", "kitaId");
|
||||
|
||||
|
||||
-- Additional composite tenant foreign keys deliberately supplement the Prisma single-ID relations.
|
||||
-- NO ACTION preserves their existing Cascade/SetNull behavior; validation rejects inconsistent legacy rows.
|
||||
ALTER TABLE "users" ADD CONSTRAINT "users_familyId_tenant_fkey" FOREIGN KEY ("familyId", "kitaId") REFERENCES "families"("id", "kitaId") ON DELETE NO ACTION ON UPDATE NO ACTION;
|
||||
ALTER TABLE "children" ADD CONSTRAINT "children_familyId_tenant_fkey" FOREIGN KEY ("familyId", "kitaId") REFERENCES "families"("id", "kitaId") ON DELETE NO ACTION ON UPDATE NO ACTION;
|
||||
ALTER TABLE "parent_duty_assignments" ADD CONSTRAINT "parent_duty_assignments_dutyId_tenant_fkey" FOREIGN KEY ("dutyId", "kitaId") REFERENCES "parent_duties"("id", "kitaId") ON DELETE NO ACTION ON UPDATE NO ACTION;
|
||||
ALTER TABLE "parent_duty_assignments" ADD CONSTRAINT "parent_duty_assignments_userId_tenant_fkey" FOREIGN KEY ("userId", "kitaId") REFERENCES "users"("id", "kitaId") ON DELETE NO ACTION ON UPDATE NO ACTION;
|
||||
ALTER TABLE "duty_assignments" ADD CONSTRAINT "duty_assignments_familyId_tenant_fkey" FOREIGN KEY ("familyId", "kitaId") REFERENCES "families"("id", "kitaId") ON DELETE NO ACTION ON UPDATE NO ACTION;
|
||||
ALTER TABLE "duty_assignments" ADD CONSTRAINT "duty_assignments_dutyTypeId_tenant_fkey" FOREIGN KEY ("dutyTypeId", "kitaId") REFERENCES "duty_types"("id", "kitaId") ON DELETE NO ACTION ON UPDATE NO ACTION;
|
||||
ALTER TABLE "absences" ADD CONSTRAINT "absences_childId_tenant_fkey" FOREIGN KEY ("childId", "kitaId") REFERENCES "children"("id", "kitaId") ON DELETE NO ACTION ON UPDATE NO ACTION;
|
||||
ALTER TABLE "announcements" ADD CONSTRAINT "announcements_authorId_tenant_fkey" FOREIGN KEY ("authorId", "kitaId") REFERENCES "users"("id", "kitaId") ON DELETE NO ACTION ON UPDATE NO ACTION;
|
||||
ALTER TABLE "invitations" ADD CONSTRAINT "invitations_invitedById_tenant_fkey" FOREIGN KEY ("invitedById", "kitaId") REFERENCES "users"("id", "kitaId") ON DELETE NO ACTION ON UPDATE NO ACTION;
|
||||
ALTER TABLE "termine" ADD CONSTRAINT "termine_createdById_tenant_fkey" FOREIGN KEY ("createdById", "kitaId") REFERENCES "users"("id", "kitaId") ON DELETE NO ACTION ON UPDATE NO ACTION;
|
||||
ALTER TABLE "termine" ADD CONSTRAINT "termine_approvedById_tenant_fkey" FOREIGN KEY ("approvedById", "kitaId") REFERENCES "users"("id", "kitaId") ON DELETE NO ACTION ON UPDATE NO ACTION;
|
||||
ALTER TABLE "event_participations" ADD CONSTRAINT "event_participations_eventId_tenant_fkey" FOREIGN KEY ("eventId", "kitaId") REFERENCES "termine"("id", "kitaId") ON DELETE NO ACTION ON UPDATE NO ACTION;
|
||||
ALTER TABLE "event_participations" ADD CONSTRAINT "event_participations_childId_tenant_fkey" FOREIGN KEY ("childId", "kitaId") REFERENCES "children"("id", "kitaId") ON DELETE NO ACTION ON UPDATE NO ACTION;
|
||||
ALTER TABLE "mitbringsel_items" ADD CONSTRAINT "mitbringsel_items_terminId_tenant_fkey" FOREIGN KEY ("terminId", "kitaId") REFERENCES "termine"("id", "kitaId") ON DELETE NO ACTION ON UPDATE NO ACTION;
|
||||
ALTER TABLE "mitbringsel_items" ADD CONSTRAINT "mitbringsel_items_userId_tenant_fkey" FOREIGN KEY ("userId", "kitaId") REFERENCES "users"("id", "kitaId") ON DELETE NO ACTION ON UPDATE NO ACTION;
|
||||
ALTER TABLE "notdienst_plans" ADD CONSTRAINT "notdienst_plans_createdById_tenant_fkey" FOREIGN KEY ("createdById", "kitaId") REFERENCES "users"("id", "kitaId") ON DELETE NO ACTION ON UPDATE NO ACTION;
|
||||
ALTER TABLE "notdienst_availabilities" ADD CONSTRAINT "notdienst_availabilities_childId_tenant_fkey" FOREIGN KEY ("childId", "kitaId") REFERENCES "children"("id", "kitaId") ON DELETE NO ACTION ON UPDATE NO ACTION;
|
||||
ALTER TABLE "notdienst_availabilities" ADD CONSTRAINT "notdienst_availabilities_userId_tenant_fkey" FOREIGN KEY ("userId", "kitaId") REFERENCES "users"("id", "kitaId") ON DELETE NO ACTION ON UPDATE NO ACTION;
|
||||
ALTER TABLE "notdienst_assignments" ADD CONSTRAINT "notdienst_assignments_planId_tenant_fkey" FOREIGN KEY ("planId", "kitaId") REFERENCES "notdienst_plans"("id", "kitaId") ON DELETE NO ACTION ON UPDATE NO ACTION;
|
||||
ALTER TABLE "notdienst_assignments" ADD CONSTRAINT "notdienst_assignments_childId_tenant_fkey" FOREIGN KEY ("childId", "kitaId") REFERENCES "children"("id", "kitaId") ON DELETE NO ACTION ON UPDATE NO ACTION;
|
||||
ALTER TABLE "notdienst_swap_requests" ADD CONSTRAINT "notdienst_swap_requests_requesterUserId_tenant_fkey" FOREIGN KEY ("requesterUserId", "kitaId") REFERENCES "users"("id", "kitaId") ON DELETE NO ACTION ON UPDATE NO ACTION;
|
||||
ALTER TABLE "notdienst_swap_requests" ADD CONSTRAINT "notdienst_swap_requests_requesterFamilyId_tenant_fkey" FOREIGN KEY ("requesterFamilyId", "kitaId") REFERENCES "families"("id", "kitaId") ON DELETE NO ACTION ON UPDATE NO ACTION;
|
||||
ALTER TABLE "notdienst_swap_requests" ADD CONSTRAINT "notdienst_swap_requests_targetAssignmentId_tenant_fkey" FOREIGN KEY ("targetAssignmentId", "kitaId") REFERENCES "notdienst_assignments"("id", "kitaId") ON DELETE NO ACTION ON UPDATE NO ACTION;
|
||||
ALTER TABLE "notdienst_swap_requests" ADD CONSTRAINT "notdienst_swap_requests_offeredAssignmentId_tenant_fkey" FOREIGN KEY ("offeredAssignmentId", "kitaId") REFERENCES "notdienst_assignments"("id", "kitaId") ON DELETE NO ACTION ON UPDATE NO ACTION;
|
||||
ALTER TABLE "notdienst_swap_requests" ADD CONSTRAINT "notdienst_swap_requests_respondedById_tenant_fkey" FOREIGN KEY ("respondedById", "kitaId") REFERENCES "users"("id", "kitaId") ON DELETE NO ACTION ON UPDATE NO ACTION;
|
||||
ALTER TABLE "notdienst_alerts" ADD CONSTRAINT "notdienst_alerts_assignmentId_tenant_fkey" FOREIGN KEY ("assignmentId", "kitaId") REFERENCES "notdienst_assignments"("id", "kitaId") ON DELETE NO ACTION ON UPDATE NO ACTION;
|
||||
ALTER TABLE "notdienst_alerts" ADD CONSTRAINT "notdienst_alerts_parentUserId_tenant_fkey" FOREIGN KEY ("parentUserId", "kitaId") REFERENCES "users"("id", "kitaId") ON DELETE NO ACTION ON UPDATE NO ACTION;
|
||||
ALTER TABLE "notdienst_alerts" ADD CONSTRAINT "notdienst_alerts_triggeredById_tenant_fkey" FOREIGN KEY ("triggeredById", "kitaId") REFERENCES "users"("id", "kitaId") ON DELETE NO ACTION ON UPDATE NO ACTION;
|
||||
ALTER TABLE "notdienst_alerts" ADD CONSTRAINT "notdienst_alerts_educatorId_tenant_fkey" FOREIGN KEY ("educatorId", "kitaId") REFERENCES "educators"("id", "kitaId") ON DELETE NO ACTION ON UPDATE NO ACTION;
|
||||
|
||||
-- Existing founder registrations previously set this timestamp without verification.
|
||||
UPDATE users SET "emailVerifiedAt" = NULL, "sessionVersion" = "sessionVersion" + 1
|
||||
WHERE role = 'ADMIN' AND "kitaId" IS NULL;
|
||||
-- Preserve existing administrative account locks separately from temporary brute-force lockouts.
|
||||
UPDATE users SET "disabledAt" = NOW(), "sessionVersion" = "sessionVersion" + 1
|
||||
WHERE "lockedUntil" >= TIMESTAMP '2099-01-01';
|
||||
|
||||
COMMIT;
|
||||
@@ -0,0 +1,20 @@
|
||||
BEGIN;
|
||||
-- AlterTable
|
||||
ALTER TABLE "announcement_reads" ADD COLUMN "kitaId" TEXT;
|
||||
UPDATE announcement_reads AS r SET "kitaId" = a."kitaId" FROM announcements AS a WHERE a.id = r."announcementId";
|
||||
ALTER TABLE announcement_reads ALTER COLUMN "kitaId" SET NOT NULL;
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "announcements_id_kitaId_key" ON "announcements"("id", "kitaId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "announcement_reads_kitaId_idx" ON "announcement_reads"("kitaId");
|
||||
|
||||
|
||||
ALTER TABLE users ADD CONSTRAINT users_family_requires_tenant CHECK ("familyId" IS NULL OR "kitaId" IS NOT NULL);
|
||||
ALTER TABLE announcement_reads ADD CONSTRAINT announcement_reads_user_tenant_fkey
|
||||
FOREIGN KEY ("userId", "kitaId") REFERENCES users(id, "kitaId") ON DELETE NO ACTION ON UPDATE NO ACTION;
|
||||
ALTER TABLE announcement_reads ADD CONSTRAINT announcement_reads_announcement_tenant_fkey
|
||||
FOREIGN KEY ("announcementId", "kitaId") REFERENCES announcements(id, "kitaId") ON DELETE NO ACTION ON UPDATE NO ACTION;
|
||||
|
||||
COMMIT;
|
||||
@@ -0,0 +1,2 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "attachments" ADD COLUMN "sizeBytes" INTEGER;
|
||||
@@ -0,0 +1 @@
|
||||
provider = "postgresql"
|
||||
@@ -170,6 +170,7 @@ model Family {
|
||||
|
||||
@@index([kitaId])
|
||||
@@map("families")
|
||||
@@unique([id, kitaId])
|
||||
}
|
||||
|
||||
// =====================================================================
|
||||
@@ -217,6 +218,8 @@ model User {
|
||||
lastLoginAt DateTime?
|
||||
failedLoginAttempts Int @default(0)
|
||||
lockedUntil DateTime?
|
||||
disabledAt DateTime?
|
||||
sessionVersion Int @default(0)
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
@@ -244,6 +247,7 @@ model User {
|
||||
@@index([familyId])
|
||||
@@index([kitaId, role])
|
||||
@@map("users")
|
||||
@@unique([id, kitaId])
|
||||
}
|
||||
|
||||
// =====================================================================
|
||||
@@ -276,6 +280,7 @@ model Child {
|
||||
@@index([kitaId])
|
||||
@@index([familyId])
|
||||
@@map("children")
|
||||
@@unique([id, kitaId])
|
||||
}
|
||||
|
||||
// =====================================================================
|
||||
@@ -298,6 +303,7 @@ model Educator {
|
||||
|
||||
@@index([kitaId])
|
||||
@@map("educators")
|
||||
@@unique([id, kitaId])
|
||||
}
|
||||
|
||||
// =====================================================================
|
||||
@@ -321,6 +327,7 @@ model ParentDuty {
|
||||
@@unique([kitaId, name])
|
||||
@@index([kitaId])
|
||||
@@map("parent_duties")
|
||||
@@unique([id, kitaId])
|
||||
}
|
||||
|
||||
model ParentDutyAssignment {
|
||||
@@ -360,6 +367,7 @@ model DutyType {
|
||||
@@unique([kitaId, name])
|
||||
@@index([kitaId])
|
||||
@@map("duty_types")
|
||||
@@unique([id, kitaId])
|
||||
}
|
||||
|
||||
model DutyAssignment {
|
||||
@@ -435,6 +443,7 @@ model Announcement {
|
||||
|
||||
@@index([kitaId, createdAt])
|
||||
@@index([authorId])
|
||||
@@unique([id, kitaId])
|
||||
@@map("announcements")
|
||||
}
|
||||
|
||||
@@ -446,12 +455,14 @@ model Attachment {
|
||||
fileName String
|
||||
fileUrl String
|
||||
fileType String
|
||||
sizeBytes Int?
|
||||
|
||||
@@index([announcementId])
|
||||
@@map("attachments")
|
||||
}
|
||||
|
||||
model AnnouncementRead {
|
||||
kitaId String
|
||||
id String @id @default(cuid())
|
||||
userId String
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
@@ -462,6 +473,7 @@ model AnnouncementRead {
|
||||
|
||||
@@unique([userId, announcementId])
|
||||
@@index([announcementId])
|
||||
@@index([kitaId])
|
||||
@@map("announcement_reads")
|
||||
}
|
||||
|
||||
@@ -536,6 +548,7 @@ model Termin {
|
||||
@@index([kitaId, startDate])
|
||||
@@index([kitaId, status])
|
||||
@@map("termine")
|
||||
@@unique([id, kitaId])
|
||||
}
|
||||
|
||||
model EventParticipation {
|
||||
@@ -612,6 +625,7 @@ model NotdienstPlan {
|
||||
@@unique([kitaId, year, month])
|
||||
@@index([kitaId])
|
||||
@@map("notdienst_plans")
|
||||
@@unique([id, kitaId])
|
||||
}
|
||||
|
||||
/// Verfügbarkeits-Eintrag eines Elternteils für ein Kind an einem Tag.
|
||||
@@ -664,6 +678,7 @@ model NotdienstAssignment {
|
||||
@@unique([planId, date])
|
||||
@@index([kitaId, date])
|
||||
@@map("notdienst_assignments")
|
||||
@@unique([id, kitaId])
|
||||
}
|
||||
|
||||
/// Tauschanfrage zwischen Eltern fuer zwei bereits veroeffentlichte
|
||||
@@ -786,3 +801,21 @@ model VerificationToken {
|
||||
@@unique([identifier, token])
|
||||
@@map("verification_tokens")
|
||||
}
|
||||
|
||||
model RateLimitBucket {
|
||||
key String @id
|
||||
count Int
|
||||
resetAt DateTime
|
||||
@@index([resetAt])
|
||||
@@map("rate_limit_buckets")
|
||||
}
|
||||
|
||||
model PendingRegistration {
|
||||
email String @id
|
||||
firstName String
|
||||
lastName String
|
||||
tokenHash String @unique
|
||||
expiresAt DateTime
|
||||
@@index([expiresAt])
|
||||
@@map("pending_registrations")
|
||||
}
|
||||
|
||||
+7
-15
@@ -19,7 +19,7 @@ import { hash } from "bcryptjs";
|
||||
// noch keine Kita und keine User enthaelt.
|
||||
//
|
||||
// Reset: `npm run db:seed:reset` loescht gezielt die Demo-Daten und baut
|
||||
// sie neu auf. Production wird nur mit ALLOW_DATABASE_SEED=true erlaubt.
|
||||
// sie neu auf. Production-Seeding ist grundsätzlich deaktiviert.
|
||||
// =====================================================================
|
||||
|
||||
const prisma = new PrismaClient();
|
||||
@@ -101,16 +101,8 @@ function getWorkingDays(year: number, month: number, limit?: number) {
|
||||
}
|
||||
|
||||
function isSeedAllowed() {
|
||||
if (
|
||||
process.env.NODE_ENV === "development" ||
|
||||
process.env.ALLOW_DATABASE_SEED === "true"
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
console.log(
|
||||
"Seed uebersprungen: NODE_ENV ist nicht development. Setze ALLOW_DATABASE_SEED=true, wenn das bewusst gewuenscht ist.",
|
||||
);
|
||||
if (process.env.NODE_ENV !== "production" && process.env.ALLOW_DATABASE_SEED === "true") return true;
|
||||
console.log("Seed deaktiviert. Nur außerhalb der Produktion mit ALLOW_DATABASE_SEED=true erlaubt.");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -688,10 +680,10 @@ async function createAnnouncements(context: SeedContext) {
|
||||
|
||||
await prisma.announcementRead.createMany({
|
||||
data: [
|
||||
{ userId: koordinator.id, announcementId: sommerfest.id },
|
||||
{ userId: elternSchmidt.id, announcementId: sommerfest.id },
|
||||
{ userId: elternYilmaz.id, announcementId: sommerfest.id },
|
||||
{ userId: elternFischer.id, announcementId: garderobe.id },
|
||||
{ kitaId: kita.id, userId: koordinator.id, announcementId: sommerfest.id },
|
||||
{ kitaId: kita.id, userId: elternSchmidt.id, announcementId: sommerfest.id },
|
||||
{ kitaId: kita.id, userId: elternYilmaz.id, announcementId: sommerfest.id },
|
||||
{ kitaId: kita.id, userId: elternFischer.id, announcementId: garderobe.id },
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user