Add ticketed events, Jitsi meeting integration, social features, and calendar system
- Ticketed events: full CRUD, ticket tiers (free/paid/donation), Stripe checkout, QR-based check-in scanner, public event pages, ticket confirmation emails - Event formats: IN_PERSON/ONLINE/HYBRID with auto Jitsi meeting room lifecycle, ticket-gated meeting access, moderator JWT tokens, feature-flag guarded - Social engagement: challenges with scoring/leaderboards, referral tracking, volunteer spotlight, impact stories, campaign celebrations, wall of fame - Social calendar: personal calendar layers, shared calendar items with recurrence, scheduling polls, mobile day view - MCP server: events tool pack with full admin CRUD + meeting token generation - Unified calendar: eventFormat-aware tags, online event indicators - Updated docs site, pangolin configs, and various admin UI improvements Bunker Admin
This commit is contained in:
@@ -0,0 +1,249 @@
|
||||
-- CreateEnum
|
||||
CREATE TYPE "ImpactStoryType" AS ENUM ('MILESTONE', 'VICTORY', 'RESPONSE', 'CUSTOM');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "ImpactStoryStatus" AS ENUM ('DRAFT', 'PUBLISHED', 'ARCHIVED');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "SpotlightStatus" AS ENUM ('NOMINATED', 'APPROVED', 'FEATURED', 'ARCHIVED');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "ChallengeStatus" AS ENUM ('DRAFT', 'UPCOMING', 'ACTIVE', 'COMPLETED', 'CANCELLED');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "ChallengeMetric" AS ENUM ('DOORS_KNOCKED', 'EMAILS_SENT', 'SHIFTS_ATTENDED', 'RESPONSES_SUBMITTED', 'REFERRALS_MADE');
|
||||
|
||||
-- AlterEnum
|
||||
-- This migration adds more than one value to an enum.
|
||||
-- With PostgreSQL versions 11 and earlier, this is not possible
|
||||
-- in a single migration. This can be worked around by creating
|
||||
-- multiple migrations, each migration adding only one value to
|
||||
-- the enum.
|
||||
|
||||
|
||||
ALTER TYPE "NotificationType" ADD VALUE 'impact_story';
|
||||
ALTER TYPE "NotificationType" ADD VALUE 'referral_completed';
|
||||
ALTER TYPE "NotificationType" ADD VALUE 'challenge_update';
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "privacy_settings" ADD COLUMN "show_on_leaderboard" BOOLEAN DEFAULT true;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "invite_codes" (
|
||||
"id" TEXT NOT NULL,
|
||||
"code" TEXT NOT NULL,
|
||||
"created_by_user_id" TEXT NOT NULL,
|
||||
"max_uses" INTEGER NOT NULL DEFAULT 0,
|
||||
"used_count" INTEGER NOT NULL DEFAULT 0,
|
||||
"expires_at" TIMESTAMP(3),
|
||||
"is_active" BOOLEAN NOT NULL DEFAULT true,
|
||||
"note" TEXT,
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "invite_codes_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "referrals" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"referrer_id" TEXT NOT NULL,
|
||||
"referred_user_id" TEXT NOT NULL,
|
||||
"invite_code_id" TEXT,
|
||||
"referral_source" TEXT,
|
||||
"completed_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "referrals_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "impact_stories" (
|
||||
"id" TEXT NOT NULL,
|
||||
"campaign_id" TEXT NOT NULL,
|
||||
"type" "ImpactStoryType" NOT NULL,
|
||||
"status" "ImpactStoryStatus" NOT NULL DEFAULT 'DRAFT',
|
||||
"title" TEXT NOT NULL,
|
||||
"body" TEXT NOT NULL,
|
||||
"cover_image_url" TEXT,
|
||||
"milestone_value" INTEGER,
|
||||
"milestone_metric" TEXT,
|
||||
"created_by_user_id" TEXT,
|
||||
"published_at" TIMESTAMP(3),
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updated_at" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "impact_stories_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "campaign_milestones" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"campaign_id" TEXT NOT NULL,
|
||||
"metric" TEXT NOT NULL,
|
||||
"threshold" INTEGER NOT NULL,
|
||||
"reached_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"story_generated" BOOLEAN NOT NULL DEFAULT false,
|
||||
|
||||
CONSTRAINT "campaign_milestones_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "volunteer_spotlights" (
|
||||
"id" TEXT NOT NULL,
|
||||
"user_id" TEXT NOT NULL,
|
||||
"status" "SpotlightStatus" NOT NULL DEFAULT 'NOMINATED',
|
||||
"headline" TEXT,
|
||||
"story" TEXT,
|
||||
"featured_month" TEXT,
|
||||
"nominated_by_user_id" TEXT,
|
||||
"approved_by_user_id" TEXT,
|
||||
"approved_at" TIMESTAMP(3),
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updated_at" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "volunteer_spotlights_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "challenges" (
|
||||
"id" TEXT NOT NULL,
|
||||
"title" TEXT NOT NULL,
|
||||
"description" TEXT,
|
||||
"metric" "ChallengeMetric" NOT NULL,
|
||||
"status" "ChallengeStatus" NOT NULL DEFAULT 'DRAFT',
|
||||
"starts_at" TIMESTAMP(3) NOT NULL,
|
||||
"ends_at" TIMESTAMP(3) NOT NULL,
|
||||
"min_team_size" INTEGER NOT NULL DEFAULT 2,
|
||||
"max_team_size" INTEGER NOT NULL DEFAULT 10,
|
||||
"max_teams" INTEGER,
|
||||
"created_by_user_id" TEXT NOT NULL,
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updated_at" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "challenges_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "challenge_teams" (
|
||||
"id" TEXT NOT NULL,
|
||||
"challenge_id" TEXT NOT NULL,
|
||||
"name" TEXT NOT NULL,
|
||||
"captain_user_id" TEXT NOT NULL,
|
||||
"score" INTEGER NOT NULL DEFAULT 0,
|
||||
"last_scored_at" TIMESTAMP(3),
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "challenge_teams_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "challenge_team_members" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"team_id" TEXT NOT NULL,
|
||||
"user_id" TEXT NOT NULL,
|
||||
"score" INTEGER NOT NULL DEFAULT 0,
|
||||
"joined_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "challenge_team_members_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "invite_codes_code_key" ON "invite_codes"("code");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_invite_codes_code" ON "invite_codes"("code");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_invite_codes_created_by" ON "invite_codes"("created_by_user_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "referrals_referred_user_id_key" ON "referrals"("referred_user_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_referrals_referrer" ON "referrals"("referrer_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_impact_stories_campaign" ON "impact_stories"("campaign_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_impact_stories_status" ON "impact_stories"("status");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_impact_stories_type" ON "impact_stories"("type");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "campaign_milestones_campaign_id_metric_threshold_key" ON "campaign_milestones"("campaign_id", "metric", "threshold");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_volunteer_spotlights_user" ON "volunteer_spotlights"("user_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_volunteer_spotlights_status" ON "volunteer_spotlights"("status");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_volunteer_spotlights_month" ON "volunteer_spotlights"("featured_month");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_challenges_status" ON "challenges"("status");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_challenges_starts_at" ON "challenges"("starts_at");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_challenge_teams_challenge" ON "challenge_teams"("challenge_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_challenge_teams_score" ON "challenge_teams"("score");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "challenge_teams_challenge_id_name_key" ON "challenge_teams"("challenge_id", "name");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_challenge_team_members_user" ON "challenge_team_members"("user_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "challenge_team_members_team_id_user_id_key" ON "challenge_team_members"("team_id", "user_id");
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "invite_codes" ADD CONSTRAINT "invite_codes_created_by_user_id_fkey" FOREIGN KEY ("created_by_user_id") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "referrals" ADD CONSTRAINT "referrals_referrer_id_fkey" FOREIGN KEY ("referrer_id") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "referrals" ADD CONSTRAINT "referrals_referred_user_id_fkey" FOREIGN KEY ("referred_user_id") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "referrals" ADD CONSTRAINT "referrals_invite_code_id_fkey" FOREIGN KEY ("invite_code_id") REFERENCES "invite_codes"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "impact_stories" ADD CONSTRAINT "impact_stories_campaign_id_fkey" FOREIGN KEY ("campaign_id") REFERENCES "campaigns"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "impact_stories" ADD CONSTRAINT "impact_stories_created_by_user_id_fkey" FOREIGN KEY ("created_by_user_id") REFERENCES "users"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "campaign_milestones" ADD CONSTRAINT "campaign_milestones_campaign_id_fkey" FOREIGN KEY ("campaign_id") REFERENCES "campaigns"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "volunteer_spotlights" ADD CONSTRAINT "volunteer_spotlights_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "volunteer_spotlights" ADD CONSTRAINT "volunteer_spotlights_nominated_by_user_id_fkey" FOREIGN KEY ("nominated_by_user_id") REFERENCES "users"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "volunteer_spotlights" ADD CONSTRAINT "volunteer_spotlights_approved_by_user_id_fkey" FOREIGN KEY ("approved_by_user_id") REFERENCES "users"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "challenges" ADD CONSTRAINT "challenges_created_by_user_id_fkey" FOREIGN KEY ("created_by_user_id") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "challenge_teams" ADD CONSTRAINT "challenge_teams_challenge_id_fkey" FOREIGN KEY ("challenge_id") REFERENCES "challenges"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "challenge_teams" ADD CONSTRAINT "challenge_teams_captain_user_id_fkey" FOREIGN KEY ("captain_user_id") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "challenge_team_members" ADD CONSTRAINT "challenge_team_members_team_id_fkey" FOREIGN KEY ("team_id") REFERENCES "challenge_teams"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "challenge_team_members" ADD CONSTRAINT "challenge_team_members_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
@@ -0,0 +1,176 @@
|
||||
-- CreateEnum
|
||||
CREATE TYPE "TicketedEventStatus" AS ENUM ('DRAFT', 'PENDING_APPROVAL', 'PUBLISHED', 'CANCELLED', 'COMPLETED');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "TicketedEventVisibility" AS ENUM ('PUBLIC', 'UNLISTED', 'PRIVATE');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "TicketTierType" AS ENUM ('PAID', 'FREE', 'DONATION');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "TicketStatus" AS ENUM ('VALID', 'CHECKED_IN', 'CANCELLED', 'REFUNDED');
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "site_settings" ADD COLUMN "enable_ticketed_events" BOOLEAN NOT NULL DEFAULT false,
|
||||
ADD COLUMN "require_event_approval" BOOLEAN NOT NULL DEFAULT true;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "ticketed_events" (
|
||||
"id" TEXT NOT NULL,
|
||||
"slug" TEXT NOT NULL,
|
||||
"title" TEXT NOT NULL,
|
||||
"description" TEXT,
|
||||
"rich_description" TEXT,
|
||||
"date" DATE NOT NULL,
|
||||
"start_time" TEXT NOT NULL,
|
||||
"end_time" TEXT NOT NULL,
|
||||
"doors_open_time" TEXT,
|
||||
"venue_name" TEXT,
|
||||
"venue_address" TEXT,
|
||||
"latitude" DECIMAL(10,7),
|
||||
"longitude" DECIMAL(10,7),
|
||||
"status" "TicketedEventStatus" NOT NULL DEFAULT 'DRAFT',
|
||||
"visibility" "TicketedEventVisibility" NOT NULL DEFAULT 'PUBLIC',
|
||||
"invite_code" TEXT,
|
||||
"cover_image_url" TEXT,
|
||||
"max_attendees" INTEGER,
|
||||
"current_attendees" INTEGER NOT NULL DEFAULT 0,
|
||||
"gancio_event_id" INTEGER,
|
||||
"created_by_user_id" TEXT NOT NULL,
|
||||
"organizer_name" TEXT,
|
||||
"organizer_email" TEXT,
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updated_at" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "ticketed_events_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "ticket_tiers" (
|
||||
"id" TEXT NOT NULL,
|
||||
"event_id" TEXT NOT NULL,
|
||||
"name" TEXT NOT NULL,
|
||||
"description" TEXT,
|
||||
"tier_type" "TicketTierType" NOT NULL,
|
||||
"price_cad" INTEGER NOT NULL DEFAULT 0,
|
||||
"min_donation_cad" INTEGER,
|
||||
"max_quantity" INTEGER,
|
||||
"sold_count" INTEGER NOT NULL DEFAULT 0,
|
||||
"max_per_order" INTEGER NOT NULL DEFAULT 10,
|
||||
"sales_start_at" TIMESTAMP(3),
|
||||
"sales_end_at" TIMESTAMP(3),
|
||||
"sort_order" INTEGER NOT NULL DEFAULT 0,
|
||||
"is_active" BOOLEAN NOT NULL DEFAULT true,
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updated_at" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "ticket_tiers_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "tickets" (
|
||||
"id" TEXT NOT NULL,
|
||||
"ticket_code" TEXT NOT NULL,
|
||||
"token_hash" TEXT NOT NULL,
|
||||
"event_id" TEXT NOT NULL,
|
||||
"tier_id" TEXT NOT NULL,
|
||||
"order_id" TEXT,
|
||||
"holder_email" TEXT NOT NULL,
|
||||
"holder_name" TEXT,
|
||||
"user_id" TEXT,
|
||||
"status" "TicketStatus" NOT NULL DEFAULT 'VALID',
|
||||
"checked_in_at" TIMESTAMP(3),
|
||||
"checked_in_by_user_id" TEXT,
|
||||
"issued_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updated_at" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "tickets_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "check_ins" (
|
||||
"id" TEXT NOT NULL,
|
||||
"ticket_id" TEXT NOT NULL,
|
||||
"event_id" TEXT NOT NULL,
|
||||
"checked_in_by_user_id" TEXT,
|
||||
"method" TEXT NOT NULL,
|
||||
"checked_in_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"notes" TEXT,
|
||||
|
||||
CONSTRAINT "check_ins_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "ticketed_events_slug_key" ON "ticketed_events"("slug");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "ticketed_events_invite_code_key" ON "ticketed_events"("invite_code");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_ticketed_events_status" ON "ticketed_events"("status");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_ticketed_events_date" ON "ticketed_events"("date");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_ticketed_events_visibility" ON "ticketed_events"("visibility");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_ticketed_events_creator" ON "ticketed_events"("created_by_user_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_ticket_tiers_event" ON "ticket_tiers"("event_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "tickets_ticket_code_key" ON "tickets"("ticket_code");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "tickets_token_hash_key" ON "tickets"("token_hash");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_tickets_event" ON "tickets"("event_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_tickets_tier" ON "tickets"("tier_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_tickets_order" ON "tickets"("order_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_tickets_holder_email" ON "tickets"("holder_email");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_tickets_status" ON "tickets"("status");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_checkins_event" ON "check_ins"("event_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_checkins_ticket" ON "check_ins"("ticket_id");
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "ticketed_events" ADD CONSTRAINT "ticketed_events_created_by_user_id_fkey" FOREIGN KEY ("created_by_user_id") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "ticket_tiers" ADD CONSTRAINT "ticket_tiers_event_id_fkey" FOREIGN KEY ("event_id") REFERENCES "ticketed_events"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "tickets" ADD CONSTRAINT "tickets_event_id_fkey" FOREIGN KEY ("event_id") REFERENCES "ticketed_events"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "tickets" ADD CONSTRAINT "tickets_tier_id_fkey" FOREIGN KEY ("tier_id") REFERENCES "ticket_tiers"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "tickets" ADD CONSTRAINT "tickets_order_id_fkey" FOREIGN KEY ("order_id") REFERENCES "orders"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "tickets" ADD CONSTRAINT "tickets_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "check_ins" ADD CONSTRAINT "check_ins_ticket_id_fkey" FOREIGN KEY ("ticket_id") REFERENCES "tickets"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "check_ins" ADD CONSTRAINT "check_ins_event_id_fkey" FOREIGN KEY ("event_id") REFERENCES "ticketed_events"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "check_ins" ADD CONSTRAINT "check_ins_checked_in_by_user_id_fkey" FOREIGN KEY ("checked_in_by_user_id") REFERENCES "users"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
@@ -0,0 +1,12 @@
|
||||
-- CreateEnum
|
||||
CREATE TYPE "EventFormat" AS ENUM ('IN_PERSON', 'ONLINE', 'HYBRID');
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "ticketed_events" ADD COLUMN "event_format" "EventFormat" NOT NULL DEFAULT 'IN_PERSON',
|
||||
ADD COLUMN "meeting_id" TEXT;
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "ticketed_events_meeting_id_key" ON "ticketed_events"("meeting_id");
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "ticketed_events" ADD CONSTRAINT "ticketed_events_meeting_id_fkey" FOREIGN KEY ("meeting_id") REFERENCES "meetings"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
@@ -0,0 +1,258 @@
|
||||
-- CreateEnum
|
||||
CREATE TYPE "CalendarLayerType" AS ENUM ('SYSTEM', 'USER', 'EXTERNAL');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "CalendarSystemType" AS ENUM ('SHIFTS', 'TICKETS', 'POLLS', 'PUBLIC_EVENTS');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "CalendarVisibility" AS ENUM ('PRIVATE', 'FRIENDS', 'PUBLIC');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "CalendarItemType" AS ENUM ('EVENT', 'TIME_BLOCK', 'REMINDER');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "CalendarBusyStatus" AS ENUM ('BUSY', 'TENTATIVE', 'FREE');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "CalendarShowDetailsTo" AS ENUM ('NOBODY', 'FRIENDS', 'EVERYONE');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "CalendarItemSource" AS ENUM ('MANUAL', 'ICS_FEED');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "CalendarRecurrenceFrequency" AS ENUM ('DAILY', 'WEEKLY', 'BIWEEKLY', 'MONTHLY');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "CalendarFeedStatus" AS ENUM ('OK', 'ERROR', 'PENDING');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "CalendarFeedInterval" AS ENUM ('FIFTEEN_MIN', 'HOURLY', 'SIX_HOUR', 'DAILY');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "SharedViewType" AS ENUM ('MANUAL', 'ROLE_BASED');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "SharedViewScope" AS ENUM ('MEMBERS', 'PUBLIC');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "SharedViewMemberStatus" AS ENUM ('INVITED', 'ACCEPTED', 'DECLINED');
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "site_settings" ADD COLUMN "enable_social_calendar" BOOLEAN NOT NULL DEFAULT false;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "calendar_layers" (
|
||||
"id" TEXT NOT NULL,
|
||||
"user_id" TEXT NOT NULL,
|
||||
"name" TEXT NOT NULL,
|
||||
"layer_type" "CalendarLayerType" NOT NULL,
|
||||
"system_type" "CalendarSystemType",
|
||||
"color" TEXT NOT NULL DEFAULT '#1890ff',
|
||||
"visibility" "CalendarVisibility" NOT NULL DEFAULT 'PRIVATE',
|
||||
"is_enabled" BOOLEAN NOT NULL DEFAULT true,
|
||||
"sort_order" INTEGER NOT NULL DEFAULT 0,
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updated_at" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "calendar_layers_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "calendar_items" (
|
||||
"id" TEXT NOT NULL,
|
||||
"user_id" TEXT NOT NULL,
|
||||
"layer_id" TEXT NOT NULL,
|
||||
"title" TEXT NOT NULL,
|
||||
"description" TEXT,
|
||||
"date" DATE NOT NULL,
|
||||
"start_time" TEXT NOT NULL,
|
||||
"end_time" TEXT NOT NULL,
|
||||
"is_all_day" BOOLEAN NOT NULL DEFAULT false,
|
||||
"item_type" "CalendarItemType" NOT NULL DEFAULT 'EVENT',
|
||||
"location" TEXT,
|
||||
"color" TEXT,
|
||||
"visibility" "CalendarVisibility",
|
||||
"busy_status" "CalendarBusyStatus" NOT NULL DEFAULT 'BUSY',
|
||||
"show_details_to" "CalendarShowDetailsTo" NOT NULL DEFAULT 'FRIENDS',
|
||||
"recurrence_rule" JSONB,
|
||||
"recurrence_end" TIMESTAMP(3),
|
||||
"series_id" TEXT,
|
||||
"is_exception" BOOLEAN NOT NULL DEFAULT false,
|
||||
"source_type" "CalendarItemSource" NOT NULL DEFAULT 'MANUAL',
|
||||
"source_id" TEXT,
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updated_at" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "calendar_items_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "calendar_feeds" (
|
||||
"id" TEXT NOT NULL,
|
||||
"user_id" TEXT NOT NULL,
|
||||
"name" TEXT NOT NULL,
|
||||
"url" TEXT NOT NULL,
|
||||
"layer_id" TEXT NOT NULL,
|
||||
"refresh_interval" "CalendarFeedInterval" NOT NULL DEFAULT 'HOURLY',
|
||||
"last_fetched_at" TIMESTAMP(3),
|
||||
"last_status" "CalendarFeedStatus" NOT NULL DEFAULT 'PENDING',
|
||||
"last_error" TEXT,
|
||||
"item_count" INTEGER NOT NULL DEFAULT 0,
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updated_at" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "calendar_feeds_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "shared_calendar_views" (
|
||||
"id" TEXT NOT NULL,
|
||||
"name" TEXT NOT NULL,
|
||||
"description" TEXT,
|
||||
"owner_id" TEXT NOT NULL,
|
||||
"view_type" "SharedViewType" NOT NULL DEFAULT 'MANUAL',
|
||||
"auto_include_roles" JSONB,
|
||||
"included_layer_types" JSONB NOT NULL DEFAULT '[]',
|
||||
"share_scope" "SharedViewScope" NOT NULL DEFAULT 'MEMBERS',
|
||||
"share_token" TEXT,
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updated_at" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "shared_calendar_views_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "shared_calendar_members" (
|
||||
"id" TEXT NOT NULL,
|
||||
"view_id" TEXT NOT NULL,
|
||||
"user_id" TEXT NOT NULL,
|
||||
"status" "SharedViewMemberStatus" NOT NULL DEFAULT 'INVITED',
|
||||
"color" TEXT NOT NULL DEFAULT '#1890ff',
|
||||
"joined_at" TIMESTAMP(3),
|
||||
|
||||
CONSTRAINT "shared_calendar_members_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "shared_view_comments" (
|
||||
"id" TEXT NOT NULL,
|
||||
"view_id" TEXT NOT NULL,
|
||||
"user_id" TEXT NOT NULL,
|
||||
"item_date" TEXT NOT NULL,
|
||||
"item_id" TEXT,
|
||||
"content" TEXT NOT NULL,
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "shared_view_comments_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "shared_view_reactions" (
|
||||
"id" TEXT NOT NULL,
|
||||
"view_id" TEXT NOT NULL,
|
||||
"user_id" TEXT NOT NULL,
|
||||
"item_id" TEXT NOT NULL,
|
||||
"emoji" TEXT NOT NULL,
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "shared_view_reactions_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "calendar_export_tokens" (
|
||||
"id" TEXT NOT NULL,
|
||||
"user_id" TEXT NOT NULL,
|
||||
"token" TEXT NOT NULL,
|
||||
"include_personal" BOOLEAN NOT NULL DEFAULT false,
|
||||
"include_layers" JSONB,
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "calendar_export_tokens_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_calendar_layers_user" ON "calendar_layers"("user_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "idx_calendar_layers_user_system" ON "calendar_layers"("user_id", "system_type");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_calendar_items_user_date" ON "calendar_items"("user_id", "date");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_calendar_items_layer_date" ON "calendar_items"("layer_id", "date");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_calendar_items_series" ON "calendar_items"("series_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_calendar_items_source" ON "calendar_items"("source_type", "source_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "calendar_feeds_layer_id_key" ON "calendar_feeds"("layer_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_calendar_feeds_user" ON "calendar_feeds"("user_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "shared_calendar_views_share_token_key" ON "shared_calendar_views"("share_token");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_shared_views_owner" ON "shared_calendar_views"("owner_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_shared_members_user" ON "shared_calendar_members"("user_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "idx_shared_members_view_user" ON "shared_calendar_members"("view_id", "user_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_shared_comments_view_date" ON "shared_view_comments"("view_id", "item_date");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "idx_shared_reactions_unique" ON "shared_view_reactions"("view_id", "user_id", "item_id", "emoji");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "calendar_export_tokens_token_key" ON "calendar_export_tokens"("token");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_calendar_export_tokens_user" ON "calendar_export_tokens"("user_id");
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "calendar_layers" ADD CONSTRAINT "calendar_layers_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "calendar_items" ADD CONSTRAINT "calendar_items_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "calendar_items" ADD CONSTRAINT "calendar_items_layer_id_fkey" FOREIGN KEY ("layer_id") REFERENCES "calendar_layers"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "calendar_feeds" ADD CONSTRAINT "calendar_feeds_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "calendar_feeds" ADD CONSTRAINT "calendar_feeds_layer_id_fkey" FOREIGN KEY ("layer_id") REFERENCES "calendar_layers"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "shared_calendar_views" ADD CONSTRAINT "shared_calendar_views_owner_id_fkey" FOREIGN KEY ("owner_id") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "shared_calendar_members" ADD CONSTRAINT "shared_calendar_members_view_id_fkey" FOREIGN KEY ("view_id") REFERENCES "shared_calendar_views"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "shared_calendar_members" ADD CONSTRAINT "shared_calendar_members_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "shared_view_comments" ADD CONSTRAINT "shared_view_comments_view_id_fkey" FOREIGN KEY ("view_id") REFERENCES "shared_calendar_views"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "shared_view_comments" ADD CONSTRAINT "shared_view_comments_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "shared_view_reactions" ADD CONSTRAINT "shared_view_reactions_view_id_fkey" FOREIGN KEY ("view_id") REFERENCES "shared_calendar_views"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "shared_view_reactions" ADD CONSTRAINT "shared_view_reactions_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "calendar_export_tokens" ADD CONSTRAINT "calendar_export_tokens_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
@@ -0,0 +1,11 @@
|
||||
-- AlterEnum
|
||||
-- This migration adds more than one value to an enum.
|
||||
-- With PostgreSQL versions 11 and earlier, this is not possible
|
||||
-- in a single migration. This can be worked around by creating
|
||||
-- multiple migrations, each migration adding only one value to
|
||||
-- the enum.
|
||||
|
||||
|
||||
ALTER TYPE "NotificationType" ADD VALUE 'shared_view_invite';
|
||||
ALTER TYPE "NotificationType" ADD VALUE 'shared_view_accepted';
|
||||
ALTER TYPE "NotificationType" ADD VALUE 'calendar_event_invite';
|
||||
Reference in New Issue
Block a user