cm_whatsapp_bot_v1/packages/db/migrations/0000_conscious_tarantula.sql
yiekheng fa4970a76c feat(db): add drizzle schema for all tables + initial migration
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-09 15:19:36 +08:00

201 lines
8.3 KiB
SQL

CREATE TABLE IF NOT EXISTS "audit_log" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"operator_id" uuid,
"source" text NOT NULL,
"action" text NOT NULL,
"target_type" text,
"target_id" uuid,
"payload" jsonb DEFAULT '{}'::jsonb NOT NULL,
"created_at" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE IF NOT EXISTS "auth_sessions" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"operator_id" uuid NOT NULL,
"token_hash" text NOT NULL,
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
"expires_at" timestamp with time zone NOT NULL,
"last_used_at" timestamp with time zone DEFAULT now() NOT NULL,
"ip_address" "inet",
"user_agent" text,
CONSTRAINT "auth_sessions_token_hash_unique" UNIQUE("token_hash")
);
--> statement-breakpoint
CREATE TABLE IF NOT EXISTS "media_files" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"operator_id" uuid NOT NULL,
"filename_original" text NOT NULL,
"mime_type" text NOT NULL,
"size_bytes" bigint NOT NULL,
"sha256" text NOT NULL,
"storage_path" text NOT NULL,
"created_at" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE IF NOT EXISTS "operators" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"telegram_user_id" bigint NOT NULL,
"display_name" text NOT NULL,
"role" text DEFAULT 'admin' NOT NULL,
"default_timezone" text DEFAULT 'Asia/Kuala_Lumpur' NOT NULL,
"created_at" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE IF NOT EXISTS "reminder_messages" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"reminder_id" uuid NOT NULL,
"position" integer NOT NULL,
"kind" text NOT NULL,
"text_content" text,
"media_id" uuid
);
--> statement-breakpoint
CREATE TABLE IF NOT EXISTS "reminder_run_targets" (
"run_id" uuid NOT NULL,
"group_id" uuid NOT NULL,
"status" text NOT NULL,
"wa_message_id" text,
"error" text,
"latency_ms" integer,
CONSTRAINT "reminder_run_targets_run_id_group_id_pk" PRIMARY KEY("run_id","group_id")
);
--> statement-breakpoint
CREATE TABLE IF NOT EXISTS "reminder_runs" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"reminder_id" uuid NOT NULL,
"fired_at" timestamp with time zone DEFAULT now() NOT NULL,
"status" text NOT NULL,
"error_summary" text
);
--> statement-breakpoint
CREATE TABLE IF NOT EXISTS "reminder_targets" (
"reminder_id" uuid NOT NULL,
"group_id" uuid NOT NULL,
"position" integer DEFAULT 0 NOT NULL,
CONSTRAINT "reminder_targets_reminder_id_group_id_pk" PRIMARY KEY("reminder_id","group_id")
);
--> statement-breakpoint
CREATE TABLE IF NOT EXISTS "reminders" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"account_id" uuid NOT NULL,
"name" text NOT NULL,
"schedule_kind" text NOT NULL,
"scheduled_at" timestamp with time zone,
"rrule" text,
"timezone" text NOT NULL,
"ends_at" timestamp with time zone,
"max_runs" integer,
"status" text DEFAULT 'active' NOT NULL,
"created_by" uuid NOT NULL,
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
"updated_at" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE IF NOT EXISTS "whatsapp_accounts" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"operator_id" uuid NOT NULL,
"label" text NOT NULL,
"phone_number" text,
"status" text DEFAULT 'pending' NOT NULL,
"last_connected_at" timestamp with time zone,
"last_qr_at" timestamp with time zone,
"created_at" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE IF NOT EXISTS "whatsapp_groups" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"account_id" uuid NOT NULL,
"wa_group_jid" text NOT NULL,
"name" text NOT NULL,
"participant_count" integer DEFAULT 0 NOT NULL,
"is_archived" boolean DEFAULT false NOT NULL,
"last_synced_at" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
DO $$ BEGIN
ALTER TABLE "audit_log" ADD CONSTRAINT "audit_log_operator_id_operators_id_fk" FOREIGN KEY ("operator_id") REFERENCES "public"."operators"("id") ON DELETE no action ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
--> statement-breakpoint
DO $$ BEGIN
ALTER TABLE "auth_sessions" ADD CONSTRAINT "auth_sessions_operator_id_operators_id_fk" FOREIGN KEY ("operator_id") REFERENCES "public"."operators"("id") ON DELETE no action ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
--> statement-breakpoint
DO $$ BEGIN
ALTER TABLE "media_files" ADD CONSTRAINT "media_files_operator_id_operators_id_fk" FOREIGN KEY ("operator_id") REFERENCES "public"."operators"("id") ON DELETE no action ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
--> statement-breakpoint
DO $$ BEGIN
ALTER TABLE "reminder_messages" ADD CONSTRAINT "reminder_messages_reminder_id_reminders_id_fk" FOREIGN KEY ("reminder_id") REFERENCES "public"."reminders"("id") ON DELETE cascade ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
--> statement-breakpoint
DO $$ BEGIN
ALTER TABLE "reminder_messages" ADD CONSTRAINT "reminder_messages_media_id_media_files_id_fk" FOREIGN KEY ("media_id") REFERENCES "public"."media_files"("id") ON DELETE no action ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
--> statement-breakpoint
DO $$ BEGIN
ALTER TABLE "reminder_run_targets" ADD CONSTRAINT "reminder_run_targets_run_id_reminder_runs_id_fk" FOREIGN KEY ("run_id") REFERENCES "public"."reminder_runs"("id") ON DELETE cascade ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
--> statement-breakpoint
DO $$ BEGIN
ALTER TABLE "reminder_run_targets" ADD CONSTRAINT "reminder_run_targets_group_id_whatsapp_groups_id_fk" FOREIGN KEY ("group_id") REFERENCES "public"."whatsapp_groups"("id") ON DELETE no action ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
--> statement-breakpoint
DO $$ BEGIN
ALTER TABLE "reminder_runs" ADD CONSTRAINT "reminder_runs_reminder_id_reminders_id_fk" FOREIGN KEY ("reminder_id") REFERENCES "public"."reminders"("id") ON DELETE no action ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
--> statement-breakpoint
DO $$ BEGIN
ALTER TABLE "reminder_targets" ADD CONSTRAINT "reminder_targets_reminder_id_reminders_id_fk" FOREIGN KEY ("reminder_id") REFERENCES "public"."reminders"("id") ON DELETE cascade ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
--> statement-breakpoint
DO $$ BEGIN
ALTER TABLE "reminder_targets" ADD CONSTRAINT "reminder_targets_group_id_whatsapp_groups_id_fk" FOREIGN KEY ("group_id") REFERENCES "public"."whatsapp_groups"("id") ON DELETE no action ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
--> statement-breakpoint
DO $$ BEGIN
ALTER TABLE "reminders" ADD CONSTRAINT "reminders_account_id_whatsapp_accounts_id_fk" FOREIGN KEY ("account_id") REFERENCES "public"."whatsapp_accounts"("id") ON DELETE no action ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
--> statement-breakpoint
DO $$ BEGIN
ALTER TABLE "reminders" ADD CONSTRAINT "reminders_created_by_operators_id_fk" FOREIGN KEY ("created_by") REFERENCES "public"."operators"("id") ON DELETE no action ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
--> statement-breakpoint
DO $$ BEGIN
ALTER TABLE "whatsapp_accounts" ADD CONSTRAINT "whatsapp_accounts_operator_id_operators_id_fk" FOREIGN KEY ("operator_id") REFERENCES "public"."operators"("id") ON DELETE no action ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
--> statement-breakpoint
DO $$ BEGIN
ALTER TABLE "whatsapp_groups" ADD CONSTRAINT "whatsapp_groups_account_id_whatsapp_accounts_id_fk" FOREIGN KEY ("account_id") REFERENCES "public"."whatsapp_accounts"("id") ON DELETE no action ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
--> statement-breakpoint
CREATE UNIQUE INDEX IF NOT EXISTS "operators_telegram_user_id_uq" ON "operators" USING btree ("telegram_user_id");--> statement-breakpoint
CREATE UNIQUE INDEX IF NOT EXISTS "whatsapp_accounts_operator_label_uq" ON "whatsapp_accounts" USING btree ("operator_id","label");--> statement-breakpoint
CREATE UNIQUE INDEX IF NOT EXISTS "whatsapp_groups_account_jid_uq" ON "whatsapp_groups" USING btree ("account_id","wa_group_jid");