CREATE TABLE "accounts" ( "id" text PRIMARY KEY 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 "arena_responses" ( "id" text PRIMARY KEY NOT NULL, "session_id" text NOT NULL, "model_key" text NOT NULL, "provider" text NOT NULL, "content" text DEFAULT '' NOT NULL, "reasoning" text, "status" text DEFAULT 'complete' NOT NULL, "error" jsonb, "usage" jsonb, "latency_ms" integer, "ttft_ms" integer, "cost_usd" double precision, "ratings" jsonb DEFAULT '{}'::jsonb NOT NULL, "created_at" timestamp with time zone DEFAULT now() NOT NULL ); --> statement-breakpoint CREATE TABLE "arena_sessions" ( "id" text PRIMARY KEY NOT NULL, "user_id" text NOT NULL, "prompt" text NOT NULL, "system_prompt" text, "model_keys" jsonb NOT NULL, "settings" jsonb DEFAULT '{}'::jsonb NOT NULL, "created_at" timestamp with time zone DEFAULT now() NOT NULL ); --> statement-breakpoint CREATE TABLE "audit_events" ( "id" text PRIMARY KEY NOT NULL, "user_id" text, "action" text NOT NULL, "ip_address" text, "user_agent" text, "meta" jsonb DEFAULT '{}'::jsonb NOT NULL, "created_at" timestamp with time zone DEFAULT now() NOT NULL ); --> statement-breakpoint CREATE TABLE "conversation_tags" ( "conversation_id" text NOT NULL, "tag_id" text NOT NULL, CONSTRAINT "conversation_tags_conversation_id_tag_id_pk" PRIMARY KEY("conversation_id","tag_id") ); --> statement-breakpoint CREATE TABLE "conversations" ( "id" text PRIMARY KEY NOT NULL, "user_id" text NOT NULL, "title" text DEFAULT 'New chat' NOT NULL, "title_source" text DEFAULT 'auto' NOT NULL, "folder_id" text, "pinned" boolean DEFAULT false NOT NULL, "archived" boolean DEFAULT false NOT NULL, "model_key" text, "provider" text, "system_prompt" text, "settings" jsonb DEFAULT '{}'::jsonb NOT NULL, "parent_conversation_id" text, "branched_from_message_id" text, "message_count" integer DEFAULT 0 NOT NULL, "total_cost_usd" double precision DEFAULT 0 NOT NULL, "total_input_tokens" integer DEFAULT 0 NOT NULL, "total_output_tokens" integer DEFAULT 0 NOT NULL, "last_message_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 "folders" ( "id" text PRIMARY KEY NOT NULL, "user_id" text NOT NULL, "name" text NOT NULL, "color" text, "sort_order" integer DEFAULT 0 NOT NULL, "created_at" timestamp with time zone DEFAULT now() NOT NULL ); --> statement-breakpoint CREATE TABLE "message_attachments" ( "id" text PRIMARY KEY NOT NULL, "user_id" text NOT NULL, "message_id" text, "conversation_id" text, "kind" text NOT NULL, "name" text NOT NULL, "mime_type" text NOT NULL, "size_bytes" integer NOT NULL, "data_base64" text NOT NULL, "width" integer, "height" integer, "created_at" timestamp with time zone DEFAULT now() NOT NULL ); --> statement-breakpoint CREATE TABLE "messages" ( "id" text PRIMARY KEY NOT NULL, "conversation_id" text NOT NULL, "user_id" text NOT NULL, "role" text NOT NULL, "content" text DEFAULT '' NOT NULL, "parts" jsonb DEFAULT '[]'::jsonb NOT NULL, "model_key" text, "provider" text, "status" text DEFAULT 'complete' NOT NULL, "finish_reason" text, "error" jsonb, "usage" jsonb, "settings" jsonb, "latency_ms" integer, "ttft_ms" integer, "cost_usd" double precision, "parent_message_id" text, "version" integer DEFAULT 1 NOT NULL, "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 "model_presets" ( "id" text PRIMARY KEY NOT NULL, "user_id" text NOT NULL, "name" text NOT NULL, "description" text, "icon" text, "model_key" text NOT NULL, "system_prompt" text, "parameters" jsonb DEFAULT '{}'::jsonb NOT NULL, "tools" jsonb DEFAULT '{}'::jsonb NOT NULL, "file_settings" jsonb DEFAULT '{}'::jsonb NOT NULL, "sort_order" integer DEFAULT 0 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 "model_sync_runs" ( "id" text PRIMARY KEY NOT NULL, "provider" text NOT NULL, "triggered_by" text DEFAULT 'schedule' NOT NULL, "started_at" timestamp with time zone DEFAULT now() NOT NULL, "finished_at" timestamp with time zone, "ok" boolean, "models_found" integer, "models_added" integer, "models_removed" integer, "latency_ms" integer, "error_code" text, "error_message" text ); --> statement-breakpoint CREATE TABLE "models" ( "key" text PRIMARY KEY NOT NULL, "provider" text NOT NULL, "model_id" text NOT NULL, "display_name" text NOT NULL, "family" text, "capabilities" jsonb NOT NULL, "limits" jsonb DEFAULT '{}'::jsonb NOT NULL, "parameters" jsonb DEFAULT '{}'::jsonb NOT NULL, "pricing" jsonb, "status" text DEFAULT 'unknown' NOT NULL, "source" text DEFAULT 'catalog' NOT NULL, "hidden" boolean DEFAULT false NOT NULL, "sort_weight" integer DEFAULT 0 NOT NULL, "metadata" jsonb DEFAULT '{}'::jsonb NOT NULL, "first_seen_at" timestamp with time zone DEFAULT now() NOT NULL, "last_seen_at" timestamp with time zone DEFAULT now() NOT NULL, "updated_at" timestamp with time zone DEFAULT now() NOT NULL ); --> statement-breakpoint CREATE TABLE "prompt_presets" ( "id" text PRIMARY KEY NOT NULL, "user_id" text NOT NULL, "name" text NOT NULL, "description" text, "icon" text, "system_prompt" text NOT NULL, "default_model_key" text, "parameters" jsonb DEFAULT '{}'::jsonb NOT NULL, "tools" jsonb DEFAULT '{}'::jsonb NOT NULL, "sort_order" integer DEFAULT 0 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 "provider_connections" ( "id" text PRIMARY KEY NOT NULL, "user_id" text NOT NULL, "provider" text NOT NULL, "encrypted_key" text NOT NULL, "key_hint" text NOT NULL, "key_fingerprint" text NOT NULL, "status" text DEFAULT 'unverified' NOT NULL, "last_validated_at" timestamp with time zone, "last_validation_error" text, "last_success_at" timestamp with time zone, "last_error_at" timestamp with time zone, "last_error_code" text, "models_available" integer, "created_at" timestamp with time zone DEFAULT now() NOT NULL, "updated_at" timestamp with time zone DEFAULT now() NOT NULL ); --> statement-breakpoint CREATE TABLE "sessions" ( "id" text PRIMARY KEY NOT NULL, "expires_at" timestamp with time zone NOT NULL, "token" text NOT NULL, "created_at" timestamp with time zone DEFAULT now() NOT NULL, "updated_at" timestamp with time zone DEFAULT now() NOT NULL, "ip_address" text, "user_agent" text, "user_id" text NOT NULL ); --> statement-breakpoint CREATE TABLE "shared_conversations" ( "id" text PRIMARY KEY NOT NULL, "conversation_id" text NOT NULL, "user_id" text NOT NULL, "title" text NOT NULL, "snapshot" jsonb NOT NULL, "is_public" boolean DEFAULT true NOT NULL, "view_count" integer DEFAULT 0 NOT NULL, "created_at" timestamp with time zone DEFAULT now() NOT NULL, "revoked_at" timestamp with time zone ); --> statement-breakpoint CREATE TABLE "tags" ( "id" text PRIMARY KEY NOT NULL, "user_id" text NOT NULL, "name" text NOT NULL, "color" text, "created_at" timestamp with time zone DEFAULT now() NOT NULL ); --> statement-breakpoint CREATE TABLE "usage_records" ( "id" text PRIMARY KEY NOT NULL, "user_id" text NOT NULL, "conversation_id" text, "message_id" text, "arena_session_id" text, "provider" text NOT NULL, "model_key" text NOT NULL, "kind" text DEFAULT 'chat' NOT NULL, "status" text DEFAULT 'ok' NOT NULL, "error_code" text, "input_tokens" integer DEFAULT 0 NOT NULL, "output_tokens" integer DEFAULT 0 NOT NULL, "cached_tokens" integer DEFAULT 0 NOT NULL, "reasoning_tokens" integer DEFAULT 0 NOT NULL, "cost_usd" double precision, "latency_ms" integer, "ttft_ms" integer, "created_at" timestamp with time zone DEFAULT now() NOT NULL ); --> statement-breakpoint CREATE TABLE "user_model_favorites" ( "user_id" text NOT NULL, "model_key" text NOT NULL, "created_at" timestamp with time zone DEFAULT now() NOT NULL, CONSTRAINT "user_model_favorites_user_id_model_key_pk" PRIMARY KEY("user_id","model_key") ); --> statement-breakpoint CREATE TABLE "user_model_recents" ( "user_id" text NOT NULL, "model_key" text NOT NULL, "used_at" timestamp with time zone DEFAULT now() NOT NULL, "uses" integer DEFAULT 1 NOT NULL, CONSTRAINT "user_model_recents_user_id_model_key_pk" PRIMARY KEY("user_id","model_key") ); --> statement-breakpoint CREATE TABLE "user_preferences" ( "user_id" text PRIMARY KEY NOT NULL, "theme" text DEFAULT 'system' NOT NULL, "language" text DEFAULT 'en' NOT NULL, "default_model_key" text, "default_system_prompt" text, "enter_to_send" boolean DEFAULT true NOT NULL, "streaming" boolean DEFAULT true NOT NULL, "code_wrap" boolean DEFAULT false NOT NULL, "show_reasoning" boolean DEFAULT true NOT NULL, "show_costs" boolean DEFAULT true NOT NULL, "auto_title" boolean DEFAULT true NOT NULL, "extra" jsonb DEFAULT '{}'::jsonb NOT NULL, "updated_at" timestamp with time zone DEFAULT now() NOT NULL ); --> statement-breakpoint CREATE TABLE "users" ( "id" text PRIMARY KEY NOT NULL, "name" text DEFAULT '' NOT NULL, "email" text NOT NULL, "email_verified" boolean DEFAULT false NOT NULL, "image" text, "role" text DEFAULT 'user' NOT NULL, "onboarding_completed_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 "verifications" ( "id" text PRIMARY KEY 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 ALTER TABLE "accounts" ADD CONSTRAINT "accounts_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint ALTER TABLE "arena_responses" ADD CONSTRAINT "arena_responses_session_id_arena_sessions_id_fk" FOREIGN KEY ("session_id") REFERENCES "public"."arena_sessions"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint ALTER TABLE "arena_sessions" ADD CONSTRAINT "arena_sessions_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint ALTER TABLE "audit_events" ADD CONSTRAINT "audit_events_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint ALTER TABLE "conversation_tags" ADD CONSTRAINT "conversation_tags_conversation_id_conversations_id_fk" FOREIGN KEY ("conversation_id") REFERENCES "public"."conversations"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint ALTER TABLE "conversation_tags" ADD CONSTRAINT "conversation_tags_tag_id_tags_id_fk" FOREIGN KEY ("tag_id") REFERENCES "public"."tags"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint ALTER TABLE "conversations" ADD CONSTRAINT "conversations_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint ALTER TABLE "conversations" ADD CONSTRAINT "conversations_folder_id_folders_id_fk" FOREIGN KEY ("folder_id") REFERENCES "public"."folders"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint ALTER TABLE "folders" ADD CONSTRAINT "folders_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint ALTER TABLE "message_attachments" ADD CONSTRAINT "message_attachments_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint ALTER TABLE "message_attachments" ADD CONSTRAINT "message_attachments_message_id_messages_id_fk" FOREIGN KEY ("message_id") REFERENCES "public"."messages"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint ALTER TABLE "message_attachments" ADD CONSTRAINT "message_attachments_conversation_id_conversations_id_fk" FOREIGN KEY ("conversation_id") REFERENCES "public"."conversations"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint ALTER TABLE "messages" ADD CONSTRAINT "messages_conversation_id_conversations_id_fk" FOREIGN KEY ("conversation_id") REFERENCES "public"."conversations"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint ALTER TABLE "messages" ADD CONSTRAINT "messages_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint ALTER TABLE "model_presets" ADD CONSTRAINT "model_presets_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint ALTER TABLE "prompt_presets" ADD CONSTRAINT "prompt_presets_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint ALTER TABLE "provider_connections" ADD CONSTRAINT "provider_connections_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint ALTER TABLE "sessions" ADD CONSTRAINT "sessions_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint ALTER TABLE "shared_conversations" ADD CONSTRAINT "shared_conversations_conversation_id_conversations_id_fk" FOREIGN KEY ("conversation_id") REFERENCES "public"."conversations"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint ALTER TABLE "shared_conversations" ADD CONSTRAINT "shared_conversations_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint ALTER TABLE "tags" ADD CONSTRAINT "tags_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint ALTER TABLE "usage_records" ADD CONSTRAINT "usage_records_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint ALTER TABLE "user_model_favorites" ADD CONSTRAINT "user_model_favorites_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint ALTER TABLE "user_model_recents" ADD CONSTRAINT "user_model_recents_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint ALTER TABLE "user_preferences" ADD CONSTRAINT "user_preferences_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint CREATE INDEX "accounts_user_idx" ON "accounts" USING btree ("user_id");--> statement-breakpoint CREATE INDEX "arena_responses_session_idx" ON "arena_responses" USING btree ("session_id");--> statement-breakpoint CREATE INDEX "arena_sessions_user_idx" ON "arena_sessions" USING btree ("user_id","created_at");--> statement-breakpoint CREATE INDEX "audit_user_created_idx" ON "audit_events" USING btree ("user_id","created_at");--> statement-breakpoint CREATE INDEX "conversations_user_updated_idx" ON "conversations" USING btree ("user_id","updated_at");--> statement-breakpoint CREATE INDEX "conversations_user_folder_idx" ON "conversations" USING btree ("user_id","folder_id");--> statement-breakpoint CREATE INDEX "conversations_user_model_idx" ON "conversations" USING btree ("user_id","model_key");--> statement-breakpoint CREATE INDEX "folders_user_idx" ON "folders" USING btree ("user_id");--> statement-breakpoint CREATE INDEX "attachments_message_idx" ON "message_attachments" USING btree ("message_id");--> statement-breakpoint CREATE INDEX "attachments_user_idx" ON "message_attachments" USING btree ("user_id");--> statement-breakpoint CREATE INDEX "messages_conversation_created_idx" ON "messages" USING btree ("conversation_id","created_at");--> statement-breakpoint CREATE INDEX "messages_user_idx" ON "messages" USING btree ("user_id");--> statement-breakpoint CREATE INDEX "model_presets_user_idx" ON "model_presets" USING btree ("user_id");--> statement-breakpoint CREATE INDEX "model_sync_runs_provider_started_idx" ON "model_sync_runs" USING btree ("provider","started_at");--> statement-breakpoint CREATE INDEX "models_provider_idx" ON "models" USING btree ("provider");--> statement-breakpoint CREATE INDEX "models_status_idx" ON "models" USING btree ("status");--> statement-breakpoint CREATE INDEX "prompt_presets_user_idx" ON "prompt_presets" USING btree ("user_id");--> statement-breakpoint CREATE UNIQUE INDEX "provider_connections_user_provider_uq" ON "provider_connections" USING btree ("user_id","provider");--> statement-breakpoint CREATE UNIQUE INDEX "sessions_token_uq" ON "sessions" USING btree ("token");--> statement-breakpoint CREATE INDEX "sessions_user_idx" ON "sessions" USING btree ("user_id");--> statement-breakpoint CREATE INDEX "shared_conversation_idx" ON "shared_conversations" USING btree ("conversation_id");--> statement-breakpoint CREATE UNIQUE INDEX "tags_user_name_uq" ON "tags" USING btree ("user_id","name");--> statement-breakpoint CREATE INDEX "usage_user_created_idx" ON "usage_records" USING btree ("user_id","created_at");--> statement-breakpoint CREATE INDEX "usage_user_provider_idx" ON "usage_records" USING btree ("user_id","provider");--> statement-breakpoint CREATE INDEX "usage_user_model_idx" ON "usage_records" USING btree ("user_id","model_key");--> statement-breakpoint CREATE UNIQUE INDEX "users_email_uq" ON "users" USING btree ("email");--> statement-breakpoint CREATE INDEX "verifications_identifier_idx" ON "verifications" USING btree ("identifier");