CREATE TYPE "public"."audit_status" AS ENUM('success', 'failure', 'external');--> statement-breakpoint CREATE TYPE "public"."invitation_role" AS ENUM('admin', 'viewer', 'contributor');--> statement-breakpoint CREATE TYPE "public"."invitation_status" AS ENUM('pending', 'accepted', 'revoked', 'expired');--> statement-breakpoint CREATE TYPE "public"."membership_role" AS ENUM('viewer', 'contributor');--> statement-breakpoint CREATE TABLE "account" ( "id" text PRIMARY KEY DEFAULT gen_random_uuid()::text NOT NULL, "account_id" text NOT NULL, "provider_id" text NOT NULL, "user_id" text NOT NULL, "access_token" text, "refresh_token" text, "id_token" text, "access_token_expires_at" timestamp with time zone, "refresh_token_expires_at" timestamp with time zone, "scope" text, "password" text, "created_at" timestamp with time zone DEFAULT now() NOT NULL, "updated_at" timestamp with time zone DEFAULT now() NOT NULL ); --> statement-breakpoint CREATE TABLE "audit_event" ( "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, "actor_user_id" text, "client_account_id" uuid, "action" text NOT NULL, "object_name" text, "record_id" text, "status" "audit_status" NOT NULL, "request_id" text NOT NULL, "before" jsonb, "after" jsonb, "metadata" jsonb DEFAULT '{}'::jsonb NOT NULL, "created_at" timestamp with time zone DEFAULT now() NOT NULL ); --> statement-breakpoint CREATE TABLE "client_account" ( "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, "name" text NOT NULL, "twenty_company_id" text NOT NULL, "is_active" boolean DEFAULT true 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 "invitation" ( "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, "email" text NOT NULL, "name" text NOT NULL, "role" "invitation_role" NOT NULL, "client_account_id" uuid, "token_hash" text NOT NULL, "status" "invitation_status" DEFAULT 'pending' NOT NULL, "expires_at" timestamp with time zone NOT NULL, "invited_by_user_id" text NOT NULL, "accepted_at" timestamp with time zone, "created_at" timestamp with time zone DEFAULT now() NOT NULL, "updated_at" timestamp with time zone DEFAULT now() NOT NULL ); --> statement-breakpoint CREATE TABLE "membership" ( "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, "user_id" text NOT NULL, "client_account_id" uuid NOT NULL, "role" "membership_role" NOT NULL, "created_at" timestamp with time zone DEFAULT now() NOT NULL ); --> statement-breakpoint CREATE TABLE "metadata_snapshot" ( "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, "objects" jsonb NOT NULL, "synced_at" timestamp with time zone DEFAULT now() NOT NULL, "synced_by_user_id" text ); --> statement-breakpoint CREATE TABLE "portal_administrator" ( "user_id" text PRIMARY KEY NOT NULL, "created_at" timestamp with time zone DEFAULT now() NOT NULL ); --> statement-breakpoint CREATE TABLE "portal_view" ( "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, "slug" text NOT NULL, "label" text NOT NULL, "object_name_singular" text NOT NULL, "object_name_plural" text NOT NULL, "scope_field_name" text NOT NULL, "columns" jsonb NOT NULL, "detail_fields" jsonb NOT NULL, "filter_fields" jsonb NOT NULL, "create_fields" jsonb NOT NULL, "edit_fields" jsonb NOT NULL, "default_sort_field" text, "default_sort_direction" text DEFAULT 'asc' NOT NULL, "navigation_order" integer DEFAULT 0 NOT NULL, "is_enabled" boolean DEFAULT true NOT NULL, "validation_errors" jsonb DEFAULT '[]'::jsonb 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 "session" ( "id" text PRIMARY KEY DEFAULT gen_random_uuid()::text NOT NULL, "expires_at" timestamp with time zone NOT NULL, "token" text NOT NULL, "ip_address" text, "user_agent" text, "user_id" text 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 "user" ( "id" text PRIMARY KEY DEFAULT gen_random_uuid()::text NOT NULL, "name" text NOT NULL, "email" text NOT NULL, "email_verified" boolean DEFAULT false NOT NULL, "image" text, "created_at" timestamp with time zone DEFAULT now() NOT NULL, "updated_at" timestamp with time zone DEFAULT now() NOT NULL ); --> statement-breakpoint CREATE TABLE "verification" ( "id" text PRIMARY KEY DEFAULT gen_random_uuid()::text NOT NULL, "identifier" text NOT NULL, "value" text NOT NULL, "expires_at" timestamp with time zone 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 "webhook_receipt" ( "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, "fingerprint" text NOT NULL, "event" text NOT NULL, "record_id" text, "received_at" timestamp with time zone DEFAULT now() NOT NULL ); --> statement-breakpoint ALTER TABLE "account" ADD CONSTRAINT "account_user_id_user_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint ALTER TABLE "audit_event" ADD CONSTRAINT "audit_event_actor_user_id_user_id_fk" FOREIGN KEY ("actor_user_id") REFERENCES "public"."user"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint ALTER TABLE "audit_event" ADD CONSTRAINT "audit_event_client_account_id_client_account_id_fk" FOREIGN KEY ("client_account_id") REFERENCES "public"."client_account"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint ALTER TABLE "invitation" ADD CONSTRAINT "invitation_client_account_id_client_account_id_fk" FOREIGN KEY ("client_account_id") REFERENCES "public"."client_account"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint ALTER TABLE "invitation" ADD CONSTRAINT "invitation_invited_by_user_id_user_id_fk" FOREIGN KEY ("invited_by_user_id") REFERENCES "public"."user"("id") ON DELETE restrict ON UPDATE no action;--> statement-breakpoint ALTER TABLE "membership" ADD CONSTRAINT "membership_user_id_user_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint ALTER TABLE "membership" ADD CONSTRAINT "membership_client_account_id_client_account_id_fk" FOREIGN KEY ("client_account_id") REFERENCES "public"."client_account"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint ALTER TABLE "metadata_snapshot" ADD CONSTRAINT "metadata_snapshot_synced_by_user_id_user_id_fk" FOREIGN KEY ("synced_by_user_id") REFERENCES "public"."user"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint ALTER TABLE "portal_administrator" ADD CONSTRAINT "portal_administrator_user_id_user_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint ALTER TABLE "session" ADD CONSTRAINT "session_user_id_user_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint CREATE UNIQUE INDEX "account_provider_unique" ON "account" USING btree ("provider_id","account_id");--> statement-breakpoint CREATE INDEX "account_user_idx" ON "account" USING btree ("user_id");--> statement-breakpoint CREATE INDEX "audit_created_idx" ON "audit_event" USING btree ("created_at");--> statement-breakpoint CREATE INDEX "audit_actor_idx" ON "audit_event" USING btree ("actor_user_id");--> statement-breakpoint CREATE INDEX "audit_client_idx" ON "audit_event" USING btree ("client_account_id");--> statement-breakpoint CREATE INDEX "audit_object_record_idx" ON "audit_event" USING btree ("object_name","record_id");--> statement-breakpoint CREATE UNIQUE INDEX "client_account_company_unique" ON "client_account" USING btree ("twenty_company_id");--> statement-breakpoint CREATE INDEX "client_account_active_idx" ON "client_account" USING btree ("is_active");--> statement-breakpoint CREATE UNIQUE INDEX "invitation_token_unique" ON "invitation" USING btree ("token_hash");--> statement-breakpoint CREATE INDEX "invitation_email_idx" ON "invitation" USING btree ("email");--> statement-breakpoint CREATE INDEX "invitation_status_idx" ON "invitation" USING btree ("status");--> statement-breakpoint CREATE UNIQUE INDEX "membership_user_client_unique" ON "membership" USING btree ("user_id","client_account_id");--> statement-breakpoint CREATE INDEX "membership_client_idx" ON "membership" USING btree ("client_account_id");--> statement-breakpoint CREATE INDEX "metadata_synced_idx" ON "metadata_snapshot" USING btree ("synced_at");--> statement-breakpoint CREATE UNIQUE INDEX "portal_view_slug_unique" ON "portal_view" USING btree ("slug");--> statement-breakpoint CREATE UNIQUE INDEX "portal_view_object_unique" ON "portal_view" USING btree ("object_name_singular");--> statement-breakpoint CREATE INDEX "portal_view_navigation_idx" ON "portal_view" USING btree ("is_enabled","navigation_order");--> statement-breakpoint CREATE UNIQUE INDEX "session_token_unique" ON "session" USING btree ("token");--> statement-breakpoint CREATE INDEX "session_user_idx" ON "session" USING btree ("user_id");--> statement-breakpoint CREATE UNIQUE INDEX "user_email_unique" ON "user" USING btree ("email");--> statement-breakpoint CREATE INDEX "verification_identifier_idx" ON "verification" USING btree ("identifier");--> statement-breakpoint CREATE UNIQUE INDEX "webhook_fingerprint_unique" ON "webhook_receipt" USING btree ("fingerprint");--> statement-breakpoint CREATE INDEX "webhook_received_idx" ON "webhook_receipt" USING btree ("received_at");