Phase 1-14 complete: - Unified Express.js API (TypeScript, Prisma ORM, PostgreSQL 16) - React Admin GUI (Vite + Ant Design + Zustand) - JWT auth with refresh tokens - Influence: Campaigns, Representatives, Responses, Email Queue - Map: Locations, Cuts, Shifts, Canvassing System - NAR data import infrastructure (2025 format) - Listmonk newsletter integration - Landing page builder (GrapesJS) - MkDocs + Code Server integration - Volunteer portal with GPS tracking - Monitoring stack (Prometheus, Grafana, Alertmanager) - Pangolin tunnel integration Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
510 lines
16 KiB
SQL
510 lines
16 KiB
SQL
-- CreateEnum
|
|
CREATE TYPE "UserRole" AS ENUM ('SUPER_ADMIN', 'INFLUENCE_ADMIN', 'MAP_ADMIN', 'USER', 'TEMP');
|
|
|
|
-- CreateEnum
|
|
CREATE TYPE "UserStatus" AS ENUM ('ACTIVE', 'INACTIVE', 'SUSPENDED', 'EXPIRED');
|
|
|
|
-- CreateEnum
|
|
CREATE TYPE "UserCreatedVia" AS ENUM ('ADMIN', 'PUBLIC_SHIFT_SIGNUP', 'STANDARD');
|
|
|
|
-- CreateEnum
|
|
CREATE TYPE "CampaignStatus" AS ENUM ('DRAFT', 'ACTIVE', 'PAUSED', 'ARCHIVED');
|
|
|
|
-- CreateEnum
|
|
CREATE TYPE "GovernmentLevel" AS ENUM ('FEDERAL', 'PROVINCIAL', 'MUNICIPAL', 'SCHOOL_BOARD');
|
|
|
|
-- CreateEnum
|
|
CREATE TYPE "EmailMethod" AS ENUM ('SMTP', 'MAILTO');
|
|
|
|
-- CreateEnum
|
|
CREATE TYPE "CampaignEmailStatus" AS ENUM ('SENT', 'FAILED', 'CLICKED', 'USER_INFO_CAPTURED');
|
|
|
|
-- CreateEnum
|
|
CREATE TYPE "ResponseType" AS ENUM ('EMAIL', 'LETTER', 'PHONE_CALL', 'MEETING', 'SOCIAL_MEDIA', 'OTHER');
|
|
|
|
-- CreateEnum
|
|
CREATE TYPE "ResponseStatus" AS ENUM ('PENDING', 'APPROVED', 'REJECTED');
|
|
|
|
-- CreateEnum
|
|
CREATE TYPE "SupportLevel" AS ENUM ('1', '2', '3', '4');
|
|
|
|
-- CreateEnum
|
|
CREATE TYPE "GeocodeProvider" AS ENUM ('MAPBOX', 'NOMINATIM', 'PHOTON', 'LOCATIONIQ', 'ARCGIS', 'UNKNOWN');
|
|
|
|
-- CreateEnum
|
|
CREATE TYPE "ShiftStatus" AS ENUM ('OPEN', 'FULL', 'CANCELLED');
|
|
|
|
-- CreateEnum
|
|
CREATE TYPE "SignupStatus" AS ENUM ('CONFIRMED', 'CANCELLED');
|
|
|
|
-- CreateEnum
|
|
CREATE TYPE "SignupSource" AS ENUM ('AUTHENTICATED', 'PUBLIC', 'ADMIN');
|
|
|
|
-- CreateEnum
|
|
CREATE TYPE "CutCategory" AS ENUM ('CUSTOM', 'WARD', 'NEIGHBORHOOD', 'DISTRICT');
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "users" (
|
|
"id" TEXT NOT NULL,
|
|
"email" TEXT NOT NULL,
|
|
"password" TEXT NOT NULL,
|
|
"name" TEXT,
|
|
"phone" TEXT,
|
|
"role" "UserRole" NOT NULL DEFAULT 'USER',
|
|
"status" "UserStatus" NOT NULL DEFAULT 'ACTIVE',
|
|
"permissions" JSONB,
|
|
"createdVia" "UserCreatedVia" NOT NULL DEFAULT 'STANDARD',
|
|
"expiresAt" TIMESTAMP(3),
|
|
"expireDays" INTEGER,
|
|
"lastLoginAt" TIMESTAMP(3),
|
|
"emailVerified" BOOLEAN NOT NULL DEFAULT false,
|
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
"updatedAt" TIMESTAMP(3) NOT NULL,
|
|
|
|
CONSTRAINT "users_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "refresh_tokens" (
|
|
"id" TEXT NOT NULL,
|
|
"token" TEXT NOT NULL,
|
|
"userId" TEXT NOT NULL,
|
|
"expiresAt" TIMESTAMP(3) NOT NULL,
|
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
|
|
CONSTRAINT "refresh_tokens_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "campaigns" (
|
|
"id" TEXT NOT NULL,
|
|
"slug" TEXT NOT NULL,
|
|
"title" TEXT NOT NULL,
|
|
"description" TEXT,
|
|
"emailSubject" TEXT NOT NULL,
|
|
"emailBody" TEXT NOT NULL,
|
|
"callToAction" TEXT,
|
|
"coverPhoto" TEXT,
|
|
"status" "CampaignStatus" NOT NULL DEFAULT 'DRAFT',
|
|
"allowSmtpEmail" BOOLEAN NOT NULL DEFAULT true,
|
|
"allowMailtoLink" BOOLEAN NOT NULL DEFAULT true,
|
|
"collectUserInfo" BOOLEAN NOT NULL DEFAULT true,
|
|
"showEmailCount" BOOLEAN NOT NULL DEFAULT true,
|
|
"showCallCount" BOOLEAN NOT NULL DEFAULT true,
|
|
"allowEmailEditing" BOOLEAN NOT NULL DEFAULT false,
|
|
"allowCustomRecipients" BOOLEAN NOT NULL DEFAULT false,
|
|
"showResponseWall" BOOLEAN NOT NULL DEFAULT false,
|
|
"highlightCampaign" BOOLEAN NOT NULL DEFAULT false,
|
|
"targetGovernmentLevels" "GovernmentLevel"[],
|
|
"createdByUserId" TEXT,
|
|
"createdByUserEmail" TEXT,
|
|
"createdByUserName" TEXT,
|
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
"updatedAt" TIMESTAMP(3) NOT NULL,
|
|
|
|
CONSTRAINT "campaigns_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "representatives" (
|
|
"id" TEXT NOT NULL,
|
|
"postalCode" TEXT NOT NULL,
|
|
"name" TEXT,
|
|
"email" TEXT,
|
|
"districtName" TEXT,
|
|
"electedOffice" TEXT,
|
|
"partyName" TEXT,
|
|
"representativeSetName" TEXT,
|
|
"url" TEXT,
|
|
"photoUrl" TEXT,
|
|
"offices" JSONB,
|
|
"cachedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
|
|
CONSTRAINT "representatives_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "campaign_emails" (
|
|
"id" TEXT NOT NULL,
|
|
"campaignId" TEXT NOT NULL,
|
|
"campaignSlug" TEXT NOT NULL,
|
|
"userId" TEXT,
|
|
"userEmail" TEXT,
|
|
"userName" TEXT,
|
|
"userPostalCode" TEXT,
|
|
"recipientEmail" TEXT NOT NULL,
|
|
"recipientName" TEXT,
|
|
"recipientTitle" TEXT,
|
|
"recipientLevel" "GovernmentLevel",
|
|
"emailMethod" "EmailMethod" NOT NULL,
|
|
"subject" TEXT NOT NULL,
|
|
"message" TEXT NOT NULL,
|
|
"status" "CampaignEmailStatus" NOT NULL DEFAULT 'SENT',
|
|
"senderIp" TEXT,
|
|
"sentAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
|
|
CONSTRAINT "campaign_emails_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "representative_responses" (
|
|
"id" TEXT NOT NULL,
|
|
"campaignId" TEXT NOT NULL,
|
|
"campaignSlug" TEXT NOT NULL,
|
|
"representativeName" TEXT NOT NULL,
|
|
"representativeTitle" TEXT,
|
|
"representativeLevel" "GovernmentLevel" NOT NULL,
|
|
"representativeEmail" TEXT,
|
|
"responseType" "ResponseType" NOT NULL,
|
|
"responseText" TEXT NOT NULL,
|
|
"userComment" TEXT,
|
|
"screenshotUrl" TEXT,
|
|
"submittedByUserId" TEXT,
|
|
"submittedByName" TEXT,
|
|
"submittedByEmail" TEXT,
|
|
"isAnonymous" BOOLEAN NOT NULL DEFAULT false,
|
|
"status" "ResponseStatus" NOT NULL DEFAULT 'PENDING',
|
|
"isVerified" BOOLEAN NOT NULL DEFAULT false,
|
|
"verificationToken" TEXT,
|
|
"verificationSentAt" TIMESTAMP(3),
|
|
"verifiedAt" TIMESTAMP(3),
|
|
"verifiedBy" TEXT,
|
|
"upvoteCount" INTEGER NOT NULL DEFAULT 0,
|
|
"submittedIp" TEXT,
|
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
"updatedAt" TIMESTAMP(3) NOT NULL,
|
|
|
|
CONSTRAINT "representative_responses_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "response_upvotes" (
|
|
"id" TEXT NOT NULL,
|
|
"responseId" TEXT NOT NULL,
|
|
"userId" TEXT,
|
|
"userEmail" TEXT,
|
|
"upvotedIp" TEXT,
|
|
|
|
CONSTRAINT "response_upvotes_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "custom_recipients" (
|
|
"id" TEXT NOT NULL,
|
|
"campaignId" TEXT NOT NULL,
|
|
"campaignSlug" TEXT NOT NULL,
|
|
"recipientName" TEXT NOT NULL,
|
|
"recipientEmail" TEXT NOT NULL,
|
|
"recipientTitle" TEXT,
|
|
"recipientOrganization" TEXT,
|
|
"notes" TEXT,
|
|
"isActive" BOOLEAN NOT NULL DEFAULT true,
|
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
"updatedAt" TIMESTAMP(3) NOT NULL,
|
|
|
|
CONSTRAINT "custom_recipients_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "postal_code_cache" (
|
|
"id" TEXT NOT NULL,
|
|
"postalCode" TEXT NOT NULL,
|
|
"city" TEXT,
|
|
"province" TEXT,
|
|
"centroidLat" DECIMAL(10,8),
|
|
"centroidLng" DECIMAL(11,8),
|
|
"lastUpdated" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
|
|
CONSTRAINT "postal_code_cache_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "email_logs" (
|
|
"id" TEXT NOT NULL,
|
|
"recipientEmail" TEXT NOT NULL,
|
|
"senderName" TEXT NOT NULL,
|
|
"senderEmail" TEXT NOT NULL,
|
|
"subject" TEXT,
|
|
"message" TEXT,
|
|
"postalCode" TEXT,
|
|
"status" TEXT NOT NULL DEFAULT 'sent',
|
|
"senderIp" TEXT,
|
|
"sentAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
|
|
CONSTRAINT "email_logs_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "email_verifications" (
|
|
"id" TEXT NOT NULL,
|
|
"token" TEXT NOT NULL,
|
|
"email" TEXT NOT NULL,
|
|
"tempCampaignData" TEXT,
|
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
"expiresAt" TIMESTAMP(3) NOT NULL,
|
|
"used" BOOLEAN NOT NULL DEFAULT false,
|
|
|
|
CONSTRAINT "email_verifications_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "calls" (
|
|
"id" TEXT NOT NULL,
|
|
"representativeName" TEXT NOT NULL,
|
|
"representativeTitle" TEXT,
|
|
"phoneNumber" TEXT NOT NULL,
|
|
"officeType" TEXT,
|
|
"callerName" TEXT,
|
|
"callerEmail" TEXT,
|
|
"postalCode" TEXT,
|
|
"campaignId" TEXT,
|
|
"campaignSlug" TEXT,
|
|
"callerIp" TEXT,
|
|
"calledAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
|
|
CONSTRAINT "calls_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "locations" (
|
|
"id" TEXT NOT NULL,
|
|
"latitude" DECIMAL(10,8),
|
|
"longitude" DECIMAL(11,8),
|
|
"firstName" TEXT,
|
|
"lastName" TEXT,
|
|
"email" TEXT,
|
|
"phone" TEXT,
|
|
"unitNumber" TEXT,
|
|
"supportLevel" "SupportLevel",
|
|
"address" TEXT,
|
|
"sign" BOOLEAN NOT NULL DEFAULT false,
|
|
"signSize" TEXT,
|
|
"notes" TEXT,
|
|
"geocodeConfidence" INTEGER,
|
|
"geocodeProvider" "GeocodeProvider",
|
|
"createdByUserId" TEXT,
|
|
"updatedByUserId" TEXT,
|
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
"updatedAt" TIMESTAMP(3) NOT NULL,
|
|
|
|
CONSTRAINT "locations_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "shifts" (
|
|
"id" TEXT NOT NULL,
|
|
"title" TEXT NOT NULL,
|
|
"description" TEXT,
|
|
"date" DATE NOT NULL,
|
|
"startTime" TEXT NOT NULL,
|
|
"endTime" TEXT NOT NULL,
|
|
"location" TEXT,
|
|
"maxVolunteers" INTEGER NOT NULL,
|
|
"currentVolunteers" INTEGER NOT NULL DEFAULT 0,
|
|
"status" "ShiftStatus" NOT NULL DEFAULT 'OPEN',
|
|
"isPublic" BOOLEAN NOT NULL DEFAULT false,
|
|
"createdBy" TEXT,
|
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
"updatedAt" TIMESTAMP(3) NOT NULL,
|
|
|
|
CONSTRAINT "shifts_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "shift_signups" (
|
|
"id" TEXT NOT NULL,
|
|
"shiftId" TEXT NOT NULL,
|
|
"shiftTitle" TEXT,
|
|
"userId" TEXT,
|
|
"userEmail" TEXT NOT NULL,
|
|
"userName" TEXT,
|
|
"userPhone" TEXT,
|
|
"signupDate" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
"status" "SignupStatus" NOT NULL DEFAULT 'CONFIRMED',
|
|
"signupSource" "SignupSource" NOT NULL DEFAULT 'AUTHENTICATED',
|
|
|
|
CONSTRAINT "shift_signups_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "cuts" (
|
|
"id" TEXT NOT NULL,
|
|
"name" TEXT NOT NULL,
|
|
"description" TEXT,
|
|
"color" TEXT NOT NULL DEFAULT '#3388ff',
|
|
"opacity" DECIMAL(3,2) NOT NULL DEFAULT 0.3,
|
|
"category" "CutCategory",
|
|
"isPublic" BOOLEAN NOT NULL DEFAULT false,
|
|
"isOfficial" BOOLEAN NOT NULL DEFAULT false,
|
|
"geojson" TEXT NOT NULL,
|
|
"bounds" TEXT,
|
|
"showLocations" BOOLEAN NOT NULL DEFAULT true,
|
|
"exportEnabled" BOOLEAN NOT NULL DEFAULT true,
|
|
"assignedTo" TEXT,
|
|
"filterSettings" JSONB,
|
|
"lastCanvassed" TIMESTAMP(3),
|
|
"completionPercentage" INTEGER NOT NULL DEFAULT 0,
|
|
"createdByUserId" TEXT,
|
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
"updatedAt" TIMESTAMP(3) NOT NULL,
|
|
|
|
CONSTRAINT "cuts_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "map_settings" (
|
|
"id" TEXT NOT NULL,
|
|
"latitude" DECIMAL(10,8),
|
|
"longitude" DECIMAL(11,8),
|
|
"zoom" INTEGER,
|
|
"walkSheetTitle" TEXT,
|
|
"walkSheetSubtitle" TEXT,
|
|
"walkSheetFooter" TEXT,
|
|
"qrCode1Url" TEXT,
|
|
"qrCode1Label" TEXT,
|
|
"qrCode2Url" TEXT,
|
|
"qrCode2Label" TEXT,
|
|
"qrCode3Url" TEXT,
|
|
"qrCode3Label" TEXT,
|
|
"createdBy" TEXT,
|
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
"updatedAt" TIMESTAMP(3) NOT NULL,
|
|
|
|
CONSTRAINT "map_settings_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "landing_pages" (
|
|
"id" TEXT NOT NULL,
|
|
"slug" TEXT NOT NULL,
|
|
"title" TEXT NOT NULL,
|
|
"description" TEXT,
|
|
"blocks" JSONB NOT NULL,
|
|
"htmlOutput" TEXT,
|
|
"cssOutput" TEXT,
|
|
"mkdocsPath" TEXT,
|
|
"published" BOOLEAN NOT NULL DEFAULT false,
|
|
"seoTitle" TEXT,
|
|
"seoDescription" TEXT,
|
|
"seoImage" TEXT,
|
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
"updatedAt" TIMESTAMP(3) NOT NULL,
|
|
|
|
CONSTRAINT "landing_pages_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "page_blocks" (
|
|
"id" TEXT NOT NULL,
|
|
"type" TEXT NOT NULL,
|
|
"label" TEXT NOT NULL,
|
|
"schema" JSONB NOT NULL,
|
|
"defaults" JSONB NOT NULL,
|
|
"thumbnail" TEXT,
|
|
"category" TEXT,
|
|
"sortOrder" INTEGER NOT NULL DEFAULT 0,
|
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
"updatedAt" TIMESTAMP(3) NOT NULL,
|
|
|
|
CONSTRAINT "page_blocks_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateIndex
|
|
CREATE UNIQUE INDEX "users_email_key" ON "users"("email");
|
|
|
|
-- CreateIndex
|
|
CREATE UNIQUE INDEX "refresh_tokens_token_key" ON "refresh_tokens"("token");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "refresh_tokens_userId_idx" ON "refresh_tokens"("userId");
|
|
|
|
-- CreateIndex
|
|
CREATE UNIQUE INDEX "campaigns_slug_key" ON "campaigns"("slug");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "representatives_postalCode_idx" ON "representatives"("postalCode");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "campaign_emails_campaignId_idx" ON "campaign_emails"("campaignId");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "campaign_emails_campaignSlug_idx" ON "campaign_emails"("campaignSlug");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "representative_responses_campaignId_idx" ON "representative_responses"("campaignId");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "representative_responses_campaignSlug_idx" ON "representative_responses"("campaignSlug");
|
|
|
|
-- CreateIndex
|
|
CREATE UNIQUE INDEX "response_upvotes_responseId_userId_key" ON "response_upvotes"("responseId", "userId");
|
|
|
|
-- CreateIndex
|
|
CREATE UNIQUE INDEX "response_upvotes_responseId_upvotedIp_key" ON "response_upvotes"("responseId", "upvotedIp");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "custom_recipients_campaignId_idx" ON "custom_recipients"("campaignId");
|
|
|
|
-- CreateIndex
|
|
CREATE UNIQUE INDEX "postal_code_cache_postalCode_key" ON "postal_code_cache"("postalCode");
|
|
|
|
-- CreateIndex
|
|
CREATE UNIQUE INDEX "email_verifications_token_key" ON "email_verifications"("token");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "calls_campaignId_idx" ON "calls"("campaignId");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "shift_signups_shiftId_idx" ON "shift_signups"("shiftId");
|
|
|
|
-- CreateIndex
|
|
CREATE UNIQUE INDEX "shift_signups_shiftId_userEmail_key" ON "shift_signups"("shiftId", "userEmail");
|
|
|
|
-- CreateIndex
|
|
CREATE UNIQUE INDEX "landing_pages_slug_key" ON "landing_pages"("slug");
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "refresh_tokens" ADD CONSTRAINT "refresh_tokens_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "campaigns" ADD CONSTRAINT "campaigns_createdByUserId_fkey" FOREIGN KEY ("createdByUserId") REFERENCES "users"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "campaign_emails" ADD CONSTRAINT "campaign_emails_campaignId_fkey" FOREIGN KEY ("campaignId") REFERENCES "campaigns"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "campaign_emails" ADD CONSTRAINT "campaign_emails_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "representative_responses" ADD CONSTRAINT "representative_responses_campaignId_fkey" FOREIGN KEY ("campaignId") REFERENCES "campaigns"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "representative_responses" ADD CONSTRAINT "representative_responses_submittedByUserId_fkey" FOREIGN KEY ("submittedByUserId") REFERENCES "users"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "response_upvotes" ADD CONSTRAINT "response_upvotes_responseId_fkey" FOREIGN KEY ("responseId") REFERENCES "representative_responses"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "response_upvotes" ADD CONSTRAINT "response_upvotes_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "custom_recipients" ADD CONSTRAINT "custom_recipients_campaignId_fkey" FOREIGN KEY ("campaignId") REFERENCES "campaigns"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "calls" ADD CONSTRAINT "calls_campaignId_fkey" FOREIGN KEY ("campaignId") REFERENCES "campaigns"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "locations" ADD CONSTRAINT "locations_createdByUserId_fkey" FOREIGN KEY ("createdByUserId") REFERENCES "users"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "locations" ADD CONSTRAINT "locations_updatedByUserId_fkey" FOREIGN KEY ("updatedByUserId") REFERENCES "users"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "shift_signups" ADD CONSTRAINT "shift_signups_shiftId_fkey" FOREIGN KEY ("shiftId") REFERENCES "shifts"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "shift_signups" ADD CONSTRAINT "shift_signups_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "cuts" ADD CONSTRAINT "cuts_createdByUserId_fkey" FOREIGN KEY ("createdByUserId") REFERENCES "users"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|