Productionize EventSphere platform

This commit is contained in:
Austin A
2026-04-25 21:02:19 +01:00
commit 1f1d30a9f5
171 changed files with 18682 additions and 0 deletions

View File

@@ -0,0 +1,116 @@
-- CreateSchema
CREATE SCHEMA IF NOT EXISTS "public";
-- CreateTable
CREATE TABLE "Tenant" (
"id" TEXT NOT NULL,
"name" TEXT NOT NULL,
"slug" TEXT NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "Tenant_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "User" (
"id" TEXT NOT NULL,
"tenantId" TEXT NOT NULL,
"email" TEXT NOT NULL,
"fullName" TEXT NOT NULL,
"passwordHash" TEXT NOT NULL,
"refreshTokenId" TEXT,
"refreshTokenHash" TEXT,
"refreshTokenExpiresAt" TIMESTAMP(3),
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "User_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Role" (
"id" TEXT NOT NULL,
"tenantId" TEXT NOT NULL,
"name" TEXT NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "Role_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Permission" (
"id" TEXT NOT NULL,
"key" TEXT NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "Permission_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "UserRole" (
"id" TEXT NOT NULL,
"userId" TEXT NOT NULL,
"roleId" TEXT NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "UserRole_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "RolePermission" (
"id" TEXT NOT NULL,
"roleId" TEXT NOT NULL,
"permissionId" TEXT NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "RolePermission_pkey" PRIMARY KEY ("id")
);
-- CreateIndex
CREATE UNIQUE INDEX "Tenant_slug_key" ON "Tenant"("slug");
-- CreateIndex
CREATE UNIQUE INDEX "User_refreshTokenId_key" ON "User"("refreshTokenId");
-- CreateIndex
CREATE INDEX "User_tenantId_idx" ON "User"("tenantId");
-- CreateIndex
CREATE UNIQUE INDEX "User_tenantId_email_key" ON "User"("tenantId", "email");
-- CreateIndex
CREATE INDEX "Role_tenantId_idx" ON "Role"("tenantId");
-- CreateIndex
CREATE UNIQUE INDEX "Role_tenantId_name_key" ON "Role"("tenantId", "name");
-- CreateIndex
CREATE UNIQUE INDEX "Permission_key_key" ON "Permission"("key");
-- CreateIndex
CREATE UNIQUE INDEX "UserRole_userId_roleId_key" ON "UserRole"("userId", "roleId");
-- CreateIndex
CREATE UNIQUE INDEX "RolePermission_roleId_permissionId_key" ON "RolePermission"("roleId", "permissionId");
-- AddForeignKey
ALTER TABLE "User" ADD CONSTRAINT "User_tenantId_fkey" FOREIGN KEY ("tenantId") REFERENCES "Tenant"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Role" ADD CONSTRAINT "Role_tenantId_fkey" FOREIGN KEY ("tenantId") REFERENCES "Tenant"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "UserRole" ADD CONSTRAINT "UserRole_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "UserRole" ADD CONSTRAINT "UserRole_roleId_fkey" FOREIGN KEY ("roleId") REFERENCES "Role"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "RolePermission" ADD CONSTRAINT "RolePermission_roleId_fkey" FOREIGN KEY ("roleId") REFERENCES "Role"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "RolePermission" ADD CONSTRAINT "RolePermission_permissionId_fkey" FOREIGN KEY ("permissionId") REFERENCES "Permission"("id") ON DELETE CASCADE ON UPDATE CASCADE;

View File

@@ -0,0 +1,29 @@
-- CreateEnum
CREATE TYPE "EventStatus" AS ENUM ('draft', 'active', 'closed');
-- CreateTable
CREATE TABLE "Event" (
"id" TEXT NOT NULL,
"tenantId" TEXT NOT NULL,
"name" TEXT NOT NULL,
"slug" TEXT NOT NULL,
"status" "EventStatus" NOT NULL DEFAULT 'draft',
"startsAt" TIMESTAMP(3) NOT NULL,
"venue" TEXT NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "Event_pkey" PRIMARY KEY ("id")
);
-- CreateIndex
CREATE INDEX "Event_tenantId_idx" ON "Event"("tenantId");
-- CreateIndex
CREATE INDEX "Event_tenantId_status_idx" ON "Event"("tenantId", "status");
-- CreateIndex
CREATE UNIQUE INDEX "Event_tenantId_slug_key" ON "Event"("tenantId", "slug");
-- AddForeignKey
ALTER TABLE "Event" ADD CONSTRAINT "Event_tenantId_fkey" FOREIGN KEY ("tenantId") REFERENCES "Tenant"("id") ON DELETE CASCADE ON UPDATE CASCADE;

View File

@@ -0,0 +1,54 @@
-- CreateTable
CREATE TABLE "Attendee" (
"id" TEXT NOT NULL,
"tenantId" TEXT NOT NULL,
"eventId" TEXT,
"fullName" TEXT NOT NULL,
"email" TEXT NOT NULL,
"phone" TEXT,
"tags" TEXT[] NOT NULL DEFAULT ARRAY[]::TEXT[],
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "Attendee_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "AuditLog" (
"id" TEXT NOT NULL,
"tenantId" TEXT,
"actorUserId" TEXT,
"action" TEXT NOT NULL,
"entityType" TEXT,
"entityId" TEXT,
"ip" TEXT,
"userAgent" TEXT,
"metadata" JSONB,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "AuditLog_pkey" PRIMARY KEY ("id")
);
-- CreateIndex
CREATE UNIQUE INDEX "Attendee_tenantId_email_key" ON "Attendee"("tenantId", "email");
-- CreateIndex
CREATE INDEX "Attendee_tenantId_idx" ON "Attendee"("tenantId");
-- CreateIndex
CREATE INDEX "Attendee_tenantId_eventId_idx" ON "Attendee"("tenantId", "eventId");
-- CreateIndex
CREATE INDEX "AuditLog_tenantId_idx" ON "AuditLog"("tenantId");
-- CreateIndex
CREATE INDEX "AuditLog_actorUserId_idx" ON "AuditLog"("actorUserId");
-- CreateIndex
CREATE INDEX "AuditLog_entityType_entityId_idx" ON "AuditLog"("entityType", "entityId");
-- AddForeignKey
ALTER TABLE "Attendee" ADD CONSTRAINT "Attendee_tenantId_fkey" FOREIGN KEY ("tenantId") REFERENCES "Tenant"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Attendee" ADD CONSTRAINT "Attendee_eventId_fkey" FOREIGN KEY ("eventId") REFERENCES "Event"("id") ON DELETE SET NULL ON UPDATE CASCADE;

View File

@@ -0,0 +1,40 @@
-- CreateEnum
CREATE TYPE "RegistrationStatus" AS ENUM ('pending', 'confirmed', 'cancelled');
-- CreateTable
CREATE TABLE "Registration" (
"id" TEXT NOT NULL,
"tenantId" TEXT NOT NULL,
"eventId" TEXT NOT NULL,
"attendeeId" TEXT NOT NULL,
"status" "RegistrationStatus" NOT NULL DEFAULT 'pending',
"code" TEXT NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "Registration_pkey" PRIMARY KEY ("id")
);
-- CreateIndex
CREATE UNIQUE INDEX "Registration_code_key" ON "Registration"("code");
-- CreateIndex
CREATE UNIQUE INDEX "Registration_tenantId_eventId_attendeeId_key" ON "Registration"("tenantId", "eventId", "attendeeId");
-- CreateIndex
CREATE INDEX "Registration_tenantId_idx" ON "Registration"("tenantId");
-- CreateIndex
CREATE INDEX "Registration_tenantId_eventId_idx" ON "Registration"("tenantId", "eventId");
-- CreateIndex
CREATE INDEX "Registration_eventId_idx" ON "Registration"("eventId");
-- AddForeignKey
ALTER TABLE "Registration" ADD CONSTRAINT "Registration_tenantId_fkey" FOREIGN KEY ("tenantId") REFERENCES "Tenant"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Registration" ADD CONSTRAINT "Registration_eventId_fkey" FOREIGN KEY ("eventId") REFERENCES "Event"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Registration" ADD CONSTRAINT "Registration_attendeeId_fkey" FOREIGN KEY ("attendeeId") REFERENCES "Attendee"("id") ON DELETE CASCADE ON UPDATE CASCADE;

View File

@@ -0,0 +1,109 @@
-- CreateEnum
CREATE TYPE "InviteeStatus" AS ENUM ('invited', 'delivered', 'opened', 'rsvped', 'bounced');
-- CreateEnum
CREATE TYPE "RSVPResponse" AS ENUM ('yes', 'no', 'maybe');
-- CreateEnum
CREATE TYPE "PaymentStatus" AS ENUM ('initialized', 'success', 'failed');
-- CreateTable
CREATE TABLE "Invitee" (
"id" TEXT NOT NULL,
"tenantId" TEXT NOT NULL,
"eventId" TEXT NOT NULL,
"fullName" TEXT NOT NULL,
"email" TEXT NOT NULL,
"phone" TEXT,
"status" "InviteeStatus" NOT NULL DEFAULT 'invited',
"code" TEXT NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "Invitee_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "RSVP" (
"id" TEXT NOT NULL,
"tenantId" TEXT NOT NULL,
"eventId" TEXT NOT NULL,
"inviteeId" TEXT,
"response" "RSVPResponse" NOT NULL,
"note" TEXT,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "RSVP_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "PaymentTransaction" (
"id" TEXT NOT NULL,
"tenantId" TEXT NOT NULL,
"eventId" TEXT NOT NULL,
"email" TEXT NOT NULL,
"amountKobo" INTEGER NOT NULL,
"currency" TEXT NOT NULL DEFAULT 'NGN',
"provider" TEXT NOT NULL DEFAULT 'paystack',
"reference" TEXT NOT NULL,
"status" "PaymentStatus" NOT NULL DEFAULT 'initialized',
"raw" JSONB,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "PaymentTransaction_pkey" PRIMARY KEY ("id")
);
-- CreateIndex
CREATE UNIQUE INDEX "Invitee_code_key" ON "Invitee"("code");
-- CreateIndex
CREATE UNIQUE INDEX "Invitee_tenantId_eventId_email_key" ON "Invitee"("tenantId", "eventId", "email");
-- CreateIndex
CREATE INDEX "Invitee_tenantId_idx" ON "Invitee"("tenantId");
-- CreateIndex
CREATE INDEX "Invitee_tenantId_eventId_idx" ON "Invitee"("tenantId", "eventId");
-- CreateIndex
CREATE INDEX "RSVP_tenantId_idx" ON "RSVP"("tenantId");
-- CreateIndex
CREATE INDEX "RSVP_tenantId_eventId_idx" ON "RSVP"("tenantId", "eventId");
-- CreateIndex
CREATE INDEX "RSVP_inviteeId_idx" ON "RSVP"("inviteeId");
-- CreateIndex
CREATE UNIQUE INDEX "PaymentTransaction_reference_key" ON "PaymentTransaction"("reference");
-- CreateIndex
CREATE INDEX "PaymentTransaction_tenantId_idx" ON "PaymentTransaction"("tenantId");
-- CreateIndex
CREATE INDEX "PaymentTransaction_tenantId_eventId_idx" ON "PaymentTransaction"("tenantId", "eventId");
-- CreateIndex
CREATE INDEX "PaymentTransaction_eventId_idx" ON "PaymentTransaction"("eventId");
-- AddForeignKey
ALTER TABLE "Invitee" ADD CONSTRAINT "Invitee_tenantId_fkey" FOREIGN KEY ("tenantId") REFERENCES "Tenant"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Invitee" ADD CONSTRAINT "Invitee_eventId_fkey" FOREIGN KEY ("eventId") REFERENCES "Event"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "RSVP" ADD CONSTRAINT "RSVP_tenantId_fkey" FOREIGN KEY ("tenantId") REFERENCES "Tenant"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "RSVP" ADD CONSTRAINT "RSVP_eventId_fkey" FOREIGN KEY ("eventId") REFERENCES "Event"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "RSVP" ADD CONSTRAINT "RSVP_inviteeId_fkey" FOREIGN KEY ("inviteeId") REFERENCES "Invitee"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "PaymentTransaction" ADD CONSTRAINT "PaymentTransaction_tenantId_fkey" FOREIGN KEY ("tenantId") REFERENCES "Tenant"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "PaymentTransaction" ADD CONSTRAINT "PaymentTransaction_eventId_fkey" FOREIGN KEY ("eventId") REFERENCES "Event"("id") ON DELETE CASCADE ON UPDATE CASCADE;

View File

@@ -0,0 +1,50 @@
-- CreateTable
CREATE TABLE "TenantSetting" (
"id" TEXT NOT NULL,
"tenantId" TEXT NOT NULL,
"appName" TEXT,
"logoUrl" TEXT,
"modules" JSONB,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "TenantSetting_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "IntegrationSetting" (
"id" TEXT NOT NULL,
"tenantId" TEXT NOT NULL,
"key" TEXT NOT NULL,
"value" TEXT,
"isSecret" BOOLEAN NOT NULL DEFAULT false,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "IntegrationSetting_pkey" PRIMARY KEY ("id")
);
-- CreateIndex
CREATE UNIQUE INDEX "TenantSetting_tenantId_key" ON "TenantSetting"("tenantId");
-- CreateIndex
CREATE UNIQUE INDEX "IntegrationSetting_tenantId_key_key" ON "IntegrationSetting"("tenantId", "key");
-- CreateIndex
CREATE INDEX "IntegrationSetting_tenantId_idx" ON "IntegrationSetting"("tenantId");
-- AddForeignKey
ALTER TABLE "TenantSetting" ADD CONSTRAINT "TenantSetting_tenantId_fkey" FOREIGN KEY ("tenantId") REFERENCES "Tenant"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "IntegrationSetting" ADD CONSTRAINT "IntegrationSetting_tenantId_fkey" FOREIGN KEY ("tenantId") REFERENCES "Tenant"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AlterTable
ALTER TABLE "User" ADD COLUMN "phone" TEXT,
ADD COLUMN "addressLine1" TEXT,
ADD COLUMN "addressLine2" TEXT,
ADD COLUMN "city" TEXT,
ADD COLUMN "state" TEXT,
ADD COLUMN "country" TEXT,
ADD COLUMN "avatarUrl" TEXT,
ADD COLUMN "mustChangePassword" BOOLEAN NOT NULL DEFAULT false;

View File

@@ -0,0 +1,671 @@
-- CreateEnum
CREATE TYPE "QRCodeStatus" AS ENUM ('active', 'revoked');
-- CreateEnum
CREATE TYPE "CheckInResult" AS ENUM ('checked_in', 'duplicate', 'rejected');
-- CreateEnum
CREATE TYPE "CommunicationChannel" AS ENUM ('email', 'sms', 'whatsapp');
-- CreateEnum
CREATE TYPE "CommunicationStatus" AS ENUM ('queued', 'sent', 'failed');
-- AlterTable
ALTER TABLE "Registration" ADD COLUMN "checkedInAt" TIMESTAMP(3),
ADD COLUMN "source" TEXT NOT NULL DEFAULT 'admin',
ADD COLUMN "ticketTypeId" TEXT;
-- AlterTable
ALTER TABLE "PaymentTransaction" ADD COLUMN "registrationId" TEXT,
ADD COLUMN "ticketTypeId" TEXT;
-- CreateTable
CREATE TABLE "EventPage" (
"id" TEXT NOT NULL,
"tenantId" TEXT NOT NULL,
"eventId" TEXT NOT NULL,
"title" TEXT NOT NULL,
"heroTitle" TEXT,
"description" TEXT,
"content" JSONB,
"theme" JSONB,
"publishedAt" TIMESTAMP(3),
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "EventPage_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "TicketType" (
"id" TEXT NOT NULL,
"tenantId" TEXT NOT NULL,
"eventId" TEXT NOT NULL,
"name" TEXT NOT NULL,
"description" TEXT,
"priceKobo" INTEGER NOT NULL DEFAULT 0,
"currency" TEXT NOT NULL DEFAULT 'NGN',
"capacity" INTEGER,
"soldCount" INTEGER NOT NULL DEFAULT 0,
"isActive" BOOLEAN NOT NULL DEFAULT true,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "TicketType_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Form" (
"id" TEXT NOT NULL,
"tenantId" TEXT NOT NULL,
"eventId" TEXT,
"name" TEXT NOT NULL,
"slug" TEXT NOT NULL,
"description" TEXT,
"isPublic" BOOLEAN NOT NULL DEFAULT false,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "Form_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "FormField" (
"id" TEXT NOT NULL,
"tenantId" TEXT NOT NULL,
"formId" TEXT NOT NULL,
"label" TEXT NOT NULL,
"key" TEXT NOT NULL,
"type" TEXT NOT NULL,
"required" BOOLEAN NOT NULL DEFAULT false,
"options" JSONB,
"sortOrder" INTEGER NOT NULL DEFAULT 0,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "FormField_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "FormSubmission" (
"id" TEXT NOT NULL,
"tenantId" TEXT NOT NULL,
"formId" TEXT NOT NULL,
"eventId" TEXT,
"attendeeId" TEXT,
"registrationId" TEXT,
"data" JSONB NOT NULL,
"source" TEXT NOT NULL DEFAULT 'admin',
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "FormSubmission_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "QRCode" (
"id" TEXT NOT NULL,
"tenantId" TEXT NOT NULL,
"registrationId" TEXT NOT NULL,
"code" TEXT NOT NULL,
"payload" JSONB NOT NULL,
"status" "QRCodeStatus" NOT NULL DEFAULT 'active',
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "QRCode_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "CheckIn" (
"id" TEXT NOT NULL,
"tenantId" TEXT NOT NULL,
"eventId" TEXT NOT NULL,
"registrationId" TEXT NOT NULL,
"attendeeId" TEXT,
"checkedInByUserId" TEXT,
"code" TEXT NOT NULL,
"result" "CheckInResult" NOT NULL DEFAULT 'checked_in',
"note" TEXT,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "CheckIn_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "CommunicationTemplate" (
"id" TEXT NOT NULL,
"tenantId" TEXT NOT NULL,
"name" TEXT NOT NULL,
"channel" "CommunicationChannel" NOT NULL,
"subject" TEXT,
"body" TEXT NOT NULL,
"variables" JSONB,
"isActive" BOOLEAN NOT NULL DEFAULT true,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "CommunicationTemplate_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "CommunicationLog" (
"id" TEXT NOT NULL,
"tenantId" TEXT NOT NULL,
"templateId" TEXT,
"inviteeId" TEXT,
"registrationId" TEXT,
"channel" "CommunicationChannel" NOT NULL,
"to" TEXT NOT NULL,
"subject" TEXT,
"body" TEXT NOT NULL,
"status" "CommunicationStatus" NOT NULL DEFAULT 'queued',
"providerMessageId" TEXT,
"error" TEXT,
"raw" JSONB,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "CommunicationLog_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "PaystackWebhookEvent" (
"id" TEXT NOT NULL,
"tenantId" TEXT,
"event" TEXT NOT NULL,
"reference" TEXT,
"status" TEXT NOT NULL DEFAULT 'received',
"raw" JSONB NOT NULL,
"receivedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"processedAt" TIMESTAMP(3),
CONSTRAINT "PaystackWebhookEvent_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "CRMLead" (
"id" TEXT NOT NULL,
"tenantId" TEXT NOT NULL,
"eventId" TEXT,
"attendeeId" TEXT,
"fullName" TEXT NOT NULL,
"email" TEXT NOT NULL,
"phone" TEXT,
"source" TEXT NOT NULL DEFAULT 'manual',
"status" TEXT NOT NULL DEFAULT 'new',
"valueKobo" INTEGER NOT NULL DEFAULT 0,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "CRMLead_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "CRMDeal" (
"id" TEXT NOT NULL,
"tenantId" TEXT NOT NULL,
"leadId" TEXT,
"eventId" TEXT,
"title" TEXT NOT NULL,
"stage" TEXT NOT NULL DEFAULT 'new',
"valueKobo" INTEGER NOT NULL DEFAULT 0,
"probability" INTEGER NOT NULL DEFAULT 0,
"ownerUserId" TEXT,
"expectedCloseAt" TIMESTAMP(3),
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "CRMDeal_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "CRMActivity" (
"id" TEXT NOT NULL,
"tenantId" TEXT NOT NULL,
"leadId" TEXT,
"dealId" TEXT,
"userId" TEXT,
"type" TEXT NOT NULL DEFAULT 'note',
"note" TEXT NOT NULL,
"dueAt" TIMESTAMP(3),
"completedAt" TIMESTAMP(3),
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "CRMActivity_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Workflow" (
"id" TEXT NOT NULL,
"tenantId" TEXT NOT NULL,
"name" TEXT NOT NULL,
"description" TEXT,
"enabled" BOOLEAN NOT NULL DEFAULT true,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "Workflow_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "WorkflowTrigger" (
"id" TEXT NOT NULL,
"tenantId" TEXT NOT NULL,
"workflowId" TEXT NOT NULL,
"type" TEXT NOT NULL,
"config" JSONB,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "WorkflowTrigger_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "WorkflowAction" (
"id" TEXT NOT NULL,
"tenantId" TEXT NOT NULL,
"workflowId" TEXT NOT NULL,
"type" TEXT NOT NULL,
"config" JSONB,
"sortOrder" INTEGER NOT NULL DEFAULT 0,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "WorkflowAction_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "CalendarRoutingForm" (
"id" TEXT NOT NULL,
"tenantId" TEXT NOT NULL,
"eventId" TEXT,
"name" TEXT NOT NULL,
"slug" TEXT NOT NULL,
"description" TEXT,
"durationMinutes" INTEGER NOT NULL DEFAULT 30,
"active" BOOLEAN NOT NULL DEFAULT true,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "CalendarRoutingForm_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "CalendarSlot" (
"id" TEXT NOT NULL,
"tenantId" TEXT NOT NULL,
"routingFormId" TEXT NOT NULL,
"startsAt" TIMESTAMP(3) NOT NULL,
"endsAt" TIMESTAMP(3) NOT NULL,
"capacity" INTEGER NOT NULL DEFAULT 1,
"bookedCount" INTEGER NOT NULL DEFAULT 0,
"active" BOOLEAN NOT NULL DEFAULT true,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "CalendarSlot_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Booking" (
"id" TEXT NOT NULL,
"tenantId" TEXT NOT NULL,
"routingFormId" TEXT NOT NULL,
"eventId" TEXT,
"attendeeId" TEXT,
"fullName" TEXT NOT NULL,
"email" TEXT NOT NULL,
"phone" TEXT,
"startsAt" TIMESTAMP(3) NOT NULL,
"endsAt" TIMESTAMP(3) NOT NULL,
"status" TEXT NOT NULL DEFAULT 'booked',
"notes" TEXT,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "Booking_pkey" PRIMARY KEY ("id")
);
-- CreateIndex
CREATE UNIQUE INDEX "EventPage_eventId_key" ON "EventPage"("eventId");
-- CreateIndex
CREATE INDEX "EventPage_tenantId_idx" ON "EventPage"("tenantId");
-- CreateIndex
CREATE INDEX "TicketType_tenantId_idx" ON "TicketType"("tenantId");
-- CreateIndex
CREATE INDEX "TicketType_tenantId_eventId_idx" ON "TicketType"("tenantId", "eventId");
-- CreateIndex
CREATE UNIQUE INDEX "TicketType_tenantId_eventId_name_key" ON "TicketType"("tenantId", "eventId", "name");
-- CreateIndex
CREATE INDEX "Form_tenantId_idx" ON "Form"("tenantId");
-- CreateIndex
CREATE INDEX "Form_tenantId_eventId_idx" ON "Form"("tenantId", "eventId");
-- CreateIndex
CREATE UNIQUE INDEX "Form_tenantId_slug_key" ON "Form"("tenantId", "slug");
-- CreateIndex
CREATE INDEX "FormField_tenantId_idx" ON "FormField"("tenantId");
-- CreateIndex
CREATE INDEX "FormField_formId_idx" ON "FormField"("formId");
-- CreateIndex
CREATE UNIQUE INDEX "FormField_formId_key_key" ON "FormField"("formId", "key");
-- CreateIndex
CREATE INDEX "FormSubmission_tenantId_idx" ON "FormSubmission"("tenantId");
-- CreateIndex
CREATE INDEX "FormSubmission_formId_idx" ON "FormSubmission"("formId");
-- CreateIndex
CREATE INDEX "FormSubmission_eventId_idx" ON "FormSubmission"("eventId");
-- CreateIndex
CREATE INDEX "FormSubmission_attendeeId_idx" ON "FormSubmission"("attendeeId");
-- CreateIndex
CREATE INDEX "FormSubmission_registrationId_idx" ON "FormSubmission"("registrationId");
-- CreateIndex
CREATE UNIQUE INDEX "QRCode_registrationId_key" ON "QRCode"("registrationId");
-- CreateIndex
CREATE UNIQUE INDEX "QRCode_code_key" ON "QRCode"("code");
-- CreateIndex
CREATE INDEX "QRCode_tenantId_idx" ON "QRCode"("tenantId");
-- CreateIndex
CREATE INDEX "CheckIn_tenantId_idx" ON "CheckIn"("tenantId");
-- CreateIndex
CREATE INDEX "CheckIn_tenantId_eventId_idx" ON "CheckIn"("tenantId", "eventId");
-- CreateIndex
CREATE INDEX "CheckIn_registrationId_idx" ON "CheckIn"("registrationId");
-- CreateIndex
CREATE INDEX "CheckIn_attendeeId_idx" ON "CheckIn"("attendeeId");
-- CreateIndex
CREATE INDEX "CommunicationTemplate_tenantId_idx" ON "CommunicationTemplate"("tenantId");
-- CreateIndex
CREATE UNIQUE INDEX "CommunicationTemplate_tenantId_name_channel_key" ON "CommunicationTemplate"("tenantId", "name", "channel");
-- CreateIndex
CREATE INDEX "CommunicationLog_tenantId_idx" ON "CommunicationLog"("tenantId");
-- CreateIndex
CREATE INDEX "CommunicationLog_templateId_idx" ON "CommunicationLog"("templateId");
-- CreateIndex
CREATE INDEX "CommunicationLog_inviteeId_idx" ON "CommunicationLog"("inviteeId");
-- CreateIndex
CREATE INDEX "CommunicationLog_registrationId_idx" ON "CommunicationLog"("registrationId");
-- CreateIndex
CREATE INDEX "PaystackWebhookEvent_tenantId_idx" ON "PaystackWebhookEvent"("tenantId");
-- CreateIndex
CREATE INDEX "PaystackWebhookEvent_reference_idx" ON "PaystackWebhookEvent"("reference");
-- CreateIndex
CREATE INDEX "CRMLead_tenantId_idx" ON "CRMLead"("tenantId");
-- CreateIndex
CREATE INDEX "CRMLead_eventId_idx" ON "CRMLead"("eventId");
-- CreateIndex
CREATE INDEX "CRMLead_attendeeId_idx" ON "CRMLead"("attendeeId");
-- CreateIndex
CREATE UNIQUE INDEX "CRMLead_tenantId_email_key" ON "CRMLead"("tenantId", "email");
-- CreateIndex
CREATE INDEX "CRMDeal_tenantId_idx" ON "CRMDeal"("tenantId");
-- CreateIndex
CREATE INDEX "CRMDeal_leadId_idx" ON "CRMDeal"("leadId");
-- CreateIndex
CREATE INDEX "CRMDeal_eventId_idx" ON "CRMDeal"("eventId");
-- CreateIndex
CREATE INDEX "CRMActivity_tenantId_idx" ON "CRMActivity"("tenantId");
-- CreateIndex
CREATE INDEX "CRMActivity_leadId_idx" ON "CRMActivity"("leadId");
-- CreateIndex
CREATE INDEX "CRMActivity_dealId_idx" ON "CRMActivity"("dealId");
-- CreateIndex
CREATE INDEX "CRMActivity_userId_idx" ON "CRMActivity"("userId");
-- CreateIndex
CREATE INDEX "Workflow_tenantId_idx" ON "Workflow"("tenantId");
-- CreateIndex
CREATE UNIQUE INDEX "Workflow_tenantId_name_key" ON "Workflow"("tenantId", "name");
-- CreateIndex
CREATE INDEX "WorkflowTrigger_tenantId_idx" ON "WorkflowTrigger"("tenantId");
-- CreateIndex
CREATE INDEX "WorkflowTrigger_workflowId_idx" ON "WorkflowTrigger"("workflowId");
-- CreateIndex
CREATE INDEX "WorkflowAction_tenantId_idx" ON "WorkflowAction"("tenantId");
-- CreateIndex
CREATE INDEX "WorkflowAction_workflowId_idx" ON "WorkflowAction"("workflowId");
-- CreateIndex
CREATE INDEX "CalendarRoutingForm_tenantId_idx" ON "CalendarRoutingForm"("tenantId");
-- CreateIndex
CREATE INDEX "CalendarRoutingForm_eventId_idx" ON "CalendarRoutingForm"("eventId");
-- CreateIndex
CREATE UNIQUE INDEX "CalendarRoutingForm_tenantId_slug_key" ON "CalendarRoutingForm"("tenantId", "slug");
-- CreateIndex
CREATE INDEX "CalendarSlot_tenantId_idx" ON "CalendarSlot"("tenantId");
-- CreateIndex
CREATE INDEX "CalendarSlot_routingFormId_idx" ON "CalendarSlot"("routingFormId");
-- CreateIndex
CREATE INDEX "CalendarSlot_startsAt_idx" ON "CalendarSlot"("startsAt");
-- CreateIndex
CREATE INDEX "Booking_tenantId_idx" ON "Booking"("tenantId");
-- CreateIndex
CREATE INDEX "Booking_routingFormId_idx" ON "Booking"("routingFormId");
-- CreateIndex
CREATE INDEX "Booking_eventId_idx" ON "Booking"("eventId");
-- CreateIndex
CREATE INDEX "Booking_attendeeId_idx" ON "Booking"("attendeeId");
-- CreateIndex
CREATE INDEX "Booking_startsAt_idx" ON "Booking"("startsAt");
-- CreateIndex
CREATE INDEX "Registration_ticketTypeId_idx" ON "Registration"("ticketTypeId");
-- CreateIndex
CREATE INDEX "PaymentTransaction_registrationId_idx" ON "PaymentTransaction"("registrationId");
-- CreateIndex
CREATE INDEX "PaymentTransaction_ticketTypeId_idx" ON "PaymentTransaction"("ticketTypeId");
-- AddForeignKey
ALTER TABLE "Registration" ADD CONSTRAINT "Registration_ticketTypeId_fkey" FOREIGN KEY ("ticketTypeId") REFERENCES "TicketType"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "PaymentTransaction" ADD CONSTRAINT "PaymentTransaction_registrationId_fkey" FOREIGN KEY ("registrationId") REFERENCES "Registration"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "PaymentTransaction" ADD CONSTRAINT "PaymentTransaction_ticketTypeId_fkey" FOREIGN KEY ("ticketTypeId") REFERENCES "TicketType"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "EventPage" ADD CONSTRAINT "EventPage_tenantId_fkey" FOREIGN KEY ("tenantId") REFERENCES "Tenant"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "EventPage" ADD CONSTRAINT "EventPage_eventId_fkey" FOREIGN KEY ("eventId") REFERENCES "Event"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "TicketType" ADD CONSTRAINT "TicketType_tenantId_fkey" FOREIGN KEY ("tenantId") REFERENCES "Tenant"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "TicketType" ADD CONSTRAINT "TicketType_eventId_fkey" FOREIGN KEY ("eventId") REFERENCES "Event"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Form" ADD CONSTRAINT "Form_tenantId_fkey" FOREIGN KEY ("tenantId") REFERENCES "Tenant"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Form" ADD CONSTRAINT "Form_eventId_fkey" FOREIGN KEY ("eventId") REFERENCES "Event"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "FormField" ADD CONSTRAINT "FormField_tenantId_fkey" FOREIGN KEY ("tenantId") REFERENCES "Tenant"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "FormField" ADD CONSTRAINT "FormField_formId_fkey" FOREIGN KEY ("formId") REFERENCES "Form"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "FormSubmission" ADD CONSTRAINT "FormSubmission_tenantId_fkey" FOREIGN KEY ("tenantId") REFERENCES "Tenant"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "FormSubmission" ADD CONSTRAINT "FormSubmission_formId_fkey" FOREIGN KEY ("formId") REFERENCES "Form"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "FormSubmission" ADD CONSTRAINT "FormSubmission_eventId_fkey" FOREIGN KEY ("eventId") REFERENCES "Event"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "FormSubmission" ADD CONSTRAINT "FormSubmission_attendeeId_fkey" FOREIGN KEY ("attendeeId") REFERENCES "Attendee"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "FormSubmission" ADD CONSTRAINT "FormSubmission_registrationId_fkey" FOREIGN KEY ("registrationId") REFERENCES "Registration"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "QRCode" ADD CONSTRAINT "QRCode_tenantId_fkey" FOREIGN KEY ("tenantId") REFERENCES "Tenant"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "QRCode" ADD CONSTRAINT "QRCode_registrationId_fkey" FOREIGN KEY ("registrationId") REFERENCES "Registration"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "CheckIn" ADD CONSTRAINT "CheckIn_tenantId_fkey" FOREIGN KEY ("tenantId") REFERENCES "Tenant"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "CheckIn" ADD CONSTRAINT "CheckIn_eventId_fkey" FOREIGN KEY ("eventId") REFERENCES "Event"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "CheckIn" ADD CONSTRAINT "CheckIn_registrationId_fkey" FOREIGN KEY ("registrationId") REFERENCES "Registration"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "CheckIn" ADD CONSTRAINT "CheckIn_attendeeId_fkey" FOREIGN KEY ("attendeeId") REFERENCES "Attendee"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "CheckIn" ADD CONSTRAINT "CheckIn_checkedInByUserId_fkey" FOREIGN KEY ("checkedInByUserId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "CommunicationTemplate" ADD CONSTRAINT "CommunicationTemplate_tenantId_fkey" FOREIGN KEY ("tenantId") REFERENCES "Tenant"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "CommunicationLog" ADD CONSTRAINT "CommunicationLog_tenantId_fkey" FOREIGN KEY ("tenantId") REFERENCES "Tenant"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "CommunicationLog" ADD CONSTRAINT "CommunicationLog_templateId_fkey" FOREIGN KEY ("templateId") REFERENCES "CommunicationTemplate"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "CommunicationLog" ADD CONSTRAINT "CommunicationLog_inviteeId_fkey" FOREIGN KEY ("inviteeId") REFERENCES "Invitee"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "CommunicationLog" ADD CONSTRAINT "CommunicationLog_registrationId_fkey" FOREIGN KEY ("registrationId") REFERENCES "Registration"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "PaystackWebhookEvent" ADD CONSTRAINT "PaystackWebhookEvent_tenantId_fkey" FOREIGN KEY ("tenantId") REFERENCES "Tenant"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "CRMLead" ADD CONSTRAINT "CRMLead_tenantId_fkey" FOREIGN KEY ("tenantId") REFERENCES "Tenant"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "CRMLead" ADD CONSTRAINT "CRMLead_eventId_fkey" FOREIGN KEY ("eventId") REFERENCES "Event"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "CRMLead" ADD CONSTRAINT "CRMLead_attendeeId_fkey" FOREIGN KEY ("attendeeId") REFERENCES "Attendee"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "CRMDeal" ADD CONSTRAINT "CRMDeal_tenantId_fkey" FOREIGN KEY ("tenantId") REFERENCES "Tenant"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "CRMDeal" ADD CONSTRAINT "CRMDeal_leadId_fkey" FOREIGN KEY ("leadId") REFERENCES "CRMLead"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "CRMDeal" ADD CONSTRAINT "CRMDeal_eventId_fkey" FOREIGN KEY ("eventId") REFERENCES "Event"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "CRMActivity" ADD CONSTRAINT "CRMActivity_tenantId_fkey" FOREIGN KEY ("tenantId") REFERENCES "Tenant"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "CRMActivity" ADD CONSTRAINT "CRMActivity_leadId_fkey" FOREIGN KEY ("leadId") REFERENCES "CRMLead"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "CRMActivity" ADD CONSTRAINT "CRMActivity_dealId_fkey" FOREIGN KEY ("dealId") REFERENCES "CRMDeal"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "CRMActivity" ADD CONSTRAINT "CRMActivity_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Workflow" ADD CONSTRAINT "Workflow_tenantId_fkey" FOREIGN KEY ("tenantId") REFERENCES "Tenant"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "WorkflowTrigger" ADD CONSTRAINT "WorkflowTrigger_tenantId_fkey" FOREIGN KEY ("tenantId") REFERENCES "Tenant"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "WorkflowTrigger" ADD CONSTRAINT "WorkflowTrigger_workflowId_fkey" FOREIGN KEY ("workflowId") REFERENCES "Workflow"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "WorkflowAction" ADD CONSTRAINT "WorkflowAction_tenantId_fkey" FOREIGN KEY ("tenantId") REFERENCES "Tenant"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "WorkflowAction" ADD CONSTRAINT "WorkflowAction_workflowId_fkey" FOREIGN KEY ("workflowId") REFERENCES "Workflow"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "CalendarRoutingForm" ADD CONSTRAINT "CalendarRoutingForm_tenantId_fkey" FOREIGN KEY ("tenantId") REFERENCES "Tenant"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "CalendarRoutingForm" ADD CONSTRAINT "CalendarRoutingForm_eventId_fkey" FOREIGN KEY ("eventId") REFERENCES "Event"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "CalendarSlot" ADD CONSTRAINT "CalendarSlot_tenantId_fkey" FOREIGN KEY ("tenantId") REFERENCES "Tenant"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "CalendarSlot" ADD CONSTRAINT "CalendarSlot_routingFormId_fkey" FOREIGN KEY ("routingFormId") REFERENCES "CalendarRoutingForm"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Booking" ADD CONSTRAINT "Booking_tenantId_fkey" FOREIGN KEY ("tenantId") REFERENCES "Tenant"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Booking" ADD CONSTRAINT "Booking_routingFormId_fkey" FOREIGN KEY ("routingFormId") REFERENCES "CalendarRoutingForm"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Booking" ADD CONSTRAINT "Booking_eventId_fkey" FOREIGN KEY ("eventId") REFERENCES "Event"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Booking" ADD CONSTRAINT "Booking_attendeeId_fkey" FOREIGN KEY ("attendeeId") REFERENCES "Attendee"("id") ON DELETE SET NULL ON UPDATE CASCADE;

View File

@@ -0,0 +1 @@
provider = "postgresql"

View File

@@ -0,0 +1,782 @@
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model Tenant {
id String @id @default(cuid())
name String
slug String @unique
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
users User[]
roles Role[]
events Event[]
attendees Attendee[]
registrations Registration[]
invitees Invitee[]
rsvps RSVP[]
payments PaymentTransaction[]
settings TenantSetting?
integrations IntegrationSetting[]
eventPages EventPage[]
ticketTypes TicketType[]
forms Form[]
formSubmissions FormSubmission[]
qrCodes QRCode[]
checkIns CheckIn[]
communicationTemplates CommunicationTemplate[]
communicationLogs CommunicationLog[]
paystackWebhookEvents PaystackWebhookEvent[]
crmLeads CRMLead[]
crmDeals CRMDeal[]
crmActivities CRMActivity[]
workflows Workflow[]
workflowTriggers WorkflowTrigger[]
workflowActions WorkflowAction[]
calendarRoutingForms CalendarRoutingForm[]
calendarSlots CalendarSlot[]
bookings Booking[]
formFields FormField[]
}
model User {
id String @id @default(cuid())
tenantId String
email String
fullName String
phone String?
addressLine1 String?
addressLine2 String?
city String?
state String?
country String?
avatarUrl String?
mustChangePassword Boolean @default(false)
passwordHash String
refreshTokenId String? @unique
refreshTokenHash String?
refreshTokenExpiresAt DateTime?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
roles UserRole[]
performedCheckIns CheckIn[] @relation("CheckInUser")
crmActivities CRMActivity[] @relation("CRMActivityUser")
@@unique([tenantId, email])
@@index([tenantId])
}
model TenantSetting {
id String @id @default(cuid())
tenantId String @unique
appName String?
logoUrl String?
modules Json?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
}
model IntegrationSetting {
id String @id @default(cuid())
tenantId String
key String
value String?
isSecret Boolean @default(false)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
@@unique([tenantId, key])
@@index([tenantId])
}
model Role {
id String @id @default(cuid())
tenantId String
name String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
users UserRole[]
permissions RolePermission[]
@@unique([tenantId, name])
@@index([tenantId])
}
model Permission {
id String @id @default(cuid())
key String @unique
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
roles RolePermission[]
}
model UserRole {
id String @id @default(cuid())
userId String
roleId String
createdAt DateTime @default(now())
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
role Role @relation(fields: [roleId], references: [id], onDelete: Cascade)
@@unique([userId, roleId])
}
model RolePermission {
id String @id @default(cuid())
roleId String
permissionId String
createdAt DateTime @default(now())
role Role @relation(fields: [roleId], references: [id], onDelete: Cascade)
permission Permission @relation(fields: [permissionId], references: [id], onDelete: Cascade)
@@unique([roleId, permissionId])
}
enum EventStatus {
draft
active
closed
}
model Event {
id String @id @default(cuid())
tenantId String
name String
slug String
status EventStatus @default(draft)
startsAt DateTime
venue String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
attendees Attendee[]
registrations Registration[]
invitees Invitee[]
rsvps RSVP[]
payments PaymentTransaction[]
eventPage EventPage?
ticketTypes TicketType[]
forms Form[]
formSubmissions FormSubmission[]
checkIns CheckIn[]
crmLeads CRMLead[]
crmDeals CRMDeal[]
calendarRoutingForms CalendarRoutingForm[]
bookings Booking[]
@@unique([tenantId, slug])
@@index([tenantId])
@@index([tenantId, status])
}
enum RegistrationStatus {
pending
confirmed
cancelled
}
model Registration {
id String @id @default(cuid())
tenantId String
eventId String
attendeeId String
ticketTypeId String?
status RegistrationStatus @default(pending)
code String @unique
source String @default("admin")
checkedInAt DateTime?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
event Event @relation(fields: [eventId], references: [id], onDelete: Cascade)
attendee Attendee @relation(fields: [attendeeId], references: [id], onDelete: Cascade)
ticketType TicketType? @relation(fields: [ticketTypeId], references: [id], onDelete: SetNull)
qrCode QRCode?
checkIns CheckIn[]
formSubmissions FormSubmission[]
communicationLogs CommunicationLog[]
payments PaymentTransaction[]
@@unique([tenantId, eventId, attendeeId])
@@index([tenantId])
@@index([tenantId, eventId])
@@index([eventId])
@@index([ticketTypeId])
}
enum InviteeStatus {
invited
delivered
opened
rsvped
bounced
}
model Invitee {
id String @id @default(cuid())
tenantId String
eventId String
fullName String
email String
phone String?
status InviteeStatus @default(invited)
code String @unique
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
event Event @relation(fields: [eventId], references: [id], onDelete: Cascade)
rsvps RSVP[]
communicationLogs CommunicationLog[]
@@unique([tenantId, eventId, email])
@@index([tenantId])
@@index([tenantId, eventId])
}
enum RSVPResponse {
yes
no
maybe
}
model RSVP {
id String @id @default(cuid())
tenantId String
eventId String
inviteeId String?
response RSVPResponse
note String?
createdAt DateTime @default(now())
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
event Event @relation(fields: [eventId], references: [id], onDelete: Cascade)
invitee Invitee? @relation(fields: [inviteeId], references: [id], onDelete: SetNull)
@@index([tenantId])
@@index([tenantId, eventId])
@@index([inviteeId])
}
enum PaymentStatus {
initialized
success
failed
}
model PaymentTransaction {
id String @id @default(cuid())
tenantId String
eventId String
registrationId String?
ticketTypeId String?
email String
amountKobo Int
currency String @default("NGN")
provider String @default("paystack")
reference String @unique
status PaymentStatus @default(initialized)
raw Json?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
event Event @relation(fields: [eventId], references: [id], onDelete: Cascade)
registration Registration? @relation(fields: [registrationId], references: [id], onDelete: SetNull)
ticketType TicketType? @relation(fields: [ticketTypeId], references: [id], onDelete: SetNull)
@@index([tenantId])
@@index([tenantId, eventId])
@@index([eventId])
@@index([registrationId])
@@index([ticketTypeId])
}
model Attendee {
id String @id @default(cuid())
tenantId String
eventId String?
fullName String
email String
phone String?
tags String[] @default([])
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
event Event? @relation(fields: [eventId], references: [id], onDelete: SetNull)
registrations Registration[]
formSubmissions FormSubmission[]
checkIns CheckIn[]
crmLeads CRMLead[]
bookings Booking[]
@@unique([tenantId, email])
@@index([tenantId])
@@index([tenantId, eventId])
}
model AuditLog {
id String @id @default(cuid())
tenantId String?
actorUserId String?
action String
entityType String?
entityId String?
ip String?
userAgent String?
metadata Json?
createdAt DateTime @default(now())
@@index([tenantId])
@@index([actorUserId])
@@index([entityType, entityId])
}
model EventPage {
id String @id @default(cuid())
tenantId String
eventId String @unique
title String
heroTitle String?
description String?
content Json?
theme Json?
publishedAt DateTime?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
event Event @relation(fields: [eventId], references: [id], onDelete: Cascade)
@@index([tenantId])
}
model TicketType {
id String @id @default(cuid())
tenantId String
eventId String
name String
description String?
priceKobo Int @default(0)
currency String @default("NGN")
capacity Int?
soldCount Int @default(0)
isActive Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
event Event @relation(fields: [eventId], references: [id], onDelete: Cascade)
registrations Registration[]
payments PaymentTransaction[]
@@unique([tenantId, eventId, name])
@@index([tenantId])
@@index([tenantId, eventId])
}
model Form {
id String @id @default(cuid())
tenantId String
eventId String?
name String
slug String
description String?
isPublic Boolean @default(false)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
event Event? @relation(fields: [eventId], references: [id], onDelete: SetNull)
fields FormField[]
submissions FormSubmission[]
@@unique([tenantId, slug])
@@index([tenantId])
@@index([tenantId, eventId])
}
model FormField {
id String @id @default(cuid())
tenantId String
formId String
label String
key String
type String
required Boolean @default(false)
options Json?
sortOrder Int @default(0)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
form Form @relation(fields: [formId], references: [id], onDelete: Cascade)
@@unique([formId, key])
@@index([tenantId])
@@index([formId])
}
model FormSubmission {
id String @id @default(cuid())
tenantId String
formId String
eventId String?
attendeeId String?
registrationId String?
data Json
source String @default("admin")
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
form Form @relation(fields: [formId], references: [id], onDelete: Cascade)
event Event? @relation(fields: [eventId], references: [id], onDelete: SetNull)
attendee Attendee? @relation(fields: [attendeeId], references: [id], onDelete: SetNull)
registration Registration? @relation(fields: [registrationId], references: [id], onDelete: SetNull)
@@index([tenantId])
@@index([formId])
@@index([eventId])
@@index([attendeeId])
@@index([registrationId])
}
model QRCode {
id String @id @default(cuid())
tenantId String
registrationId String @unique
code String @unique
payload Json
status QRCodeStatus @default(active)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
registration Registration @relation(fields: [registrationId], references: [id], onDelete: Cascade)
@@index([tenantId])
}
enum QRCodeStatus {
active
revoked
}
model CheckIn {
id String @id @default(cuid())
tenantId String
eventId String
registrationId String
attendeeId String?
checkedInByUserId String?
code String
result CheckInResult @default(checked_in)
note String?
createdAt DateTime @default(now())
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
event Event @relation(fields: [eventId], references: [id], onDelete: Cascade)
registration Registration @relation(fields: [registrationId], references: [id], onDelete: Cascade)
attendee Attendee? @relation(fields: [attendeeId], references: [id], onDelete: SetNull)
checkedInBy User? @relation("CheckInUser", fields: [checkedInByUserId], references: [id], onDelete: SetNull)
@@index([tenantId])
@@index([tenantId, eventId])
@@index([registrationId])
@@index([attendeeId])
}
enum CheckInResult {
checked_in
duplicate
rejected
}
model CommunicationTemplate {
id String @id @default(cuid())
tenantId String
name String
channel CommunicationChannel
subject String?
body String
variables Json?
isActive Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
logs CommunicationLog[]
@@unique([tenantId, name, channel])
@@index([tenantId])
}
model CommunicationLog {
id String @id @default(cuid())
tenantId String
templateId String?
inviteeId String?
registrationId String?
channel CommunicationChannel
to String
subject String?
body String
status CommunicationStatus @default(queued)
providerMessageId String?
error String?
raw Json?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
template CommunicationTemplate? @relation(fields: [templateId], references: [id], onDelete: SetNull)
invitee Invitee? @relation(fields: [inviteeId], references: [id], onDelete: SetNull)
registration Registration? @relation(fields: [registrationId], references: [id], onDelete: SetNull)
@@index([tenantId])
@@index([templateId])
@@index([inviteeId])
@@index([registrationId])
}
enum CommunicationChannel {
email
sms
whatsapp
}
enum CommunicationStatus {
queued
sent
failed
}
model PaystackWebhookEvent {
id String @id @default(cuid())
tenantId String?
event String
reference String?
status String @default("received")
raw Json
receivedAt DateTime @default(now())
processedAt DateTime?
tenant Tenant? @relation(fields: [tenantId], references: [id], onDelete: SetNull)
@@index([tenantId])
@@index([reference])
}
model CRMLead {
id String @id @default(cuid())
tenantId String
eventId String?
attendeeId String?
fullName String
email String
phone String?
source String @default("manual")
status String @default("new")
valueKobo Int @default(0)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
event Event? @relation(fields: [eventId], references: [id], onDelete: SetNull)
attendee Attendee? @relation(fields: [attendeeId], references: [id], onDelete: SetNull)
deals CRMDeal[]
activities CRMActivity[]
@@unique([tenantId, email])
@@index([tenantId])
@@index([eventId])
@@index([attendeeId])
}
model CRMDeal {
id String @id @default(cuid())
tenantId String
leadId String?
eventId String?
title String
stage String @default("new")
valueKobo Int @default(0)
probability Int @default(0)
ownerUserId String?
expectedCloseAt DateTime?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
lead CRMLead? @relation(fields: [leadId], references: [id], onDelete: SetNull)
event Event? @relation(fields: [eventId], references: [id], onDelete: SetNull)
activities CRMActivity[]
@@index([tenantId])
@@index([leadId])
@@index([eventId])
}
model CRMActivity {
id String @id @default(cuid())
tenantId String
leadId String?
dealId String?
userId String?
type String @default("note")
note String
dueAt DateTime?
completedAt DateTime?
createdAt DateTime @default(now())
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
lead CRMLead? @relation(fields: [leadId], references: [id], onDelete: SetNull)
deal CRMDeal? @relation(fields: [dealId], references: [id], onDelete: SetNull)
user User? @relation("CRMActivityUser", fields: [userId], references: [id], onDelete: SetNull)
@@index([tenantId])
@@index([leadId])
@@index([dealId])
@@index([userId])
}
model Workflow {
id String @id @default(cuid())
tenantId String
name String
description String?
enabled Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
triggers WorkflowTrigger[]
actions WorkflowAction[]
@@unique([tenantId, name])
@@index([tenantId])
}
model WorkflowTrigger {
id String @id @default(cuid())
tenantId String
workflowId String
type String
config Json?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
workflow Workflow @relation(fields: [workflowId], references: [id], onDelete: Cascade)
@@index([tenantId])
@@index([workflowId])
}
model WorkflowAction {
id String @id @default(cuid())
tenantId String
workflowId String
type String
config Json?
sortOrder Int @default(0)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
workflow Workflow @relation(fields: [workflowId], references: [id], onDelete: Cascade)
@@index([tenantId])
@@index([workflowId])
}
model CalendarRoutingForm {
id String @id @default(cuid())
tenantId String
eventId String?
name String
slug String
description String?
durationMinutes Int @default(30)
active Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
event Event? @relation(fields: [eventId], references: [id], onDelete: SetNull)
slots CalendarSlot[]
bookings Booking[]
@@unique([tenantId, slug])
@@index([tenantId])
@@index([eventId])
}
model CalendarSlot {
id String @id @default(cuid())
tenantId String
routingFormId String
startsAt DateTime
endsAt DateTime
capacity Int @default(1)
bookedCount Int @default(0)
active Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
routingForm CalendarRoutingForm @relation(fields: [routingFormId], references: [id], onDelete: Cascade)
@@index([tenantId])
@@index([routingFormId])
@@index([startsAt])
}
model Booking {
id String @id @default(cuid())
tenantId String
routingFormId String
eventId String?
attendeeId String?
fullName String
email String
phone String?
startsAt DateTime
endsAt DateTime
status String @default("booked")
notes String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
routingForm CalendarRoutingForm @relation(fields: [routingFormId], references: [id], onDelete: Cascade)
event Event? @relation(fields: [eventId], references: [id], onDelete: SetNull)
attendee Attendee? @relation(fields: [attendeeId], references: [id], onDelete: SetNull)
@@index([tenantId])
@@index([routingFormId])
@@index([eventId])
@@index([attendeeId])
@@index([startsAt])
}