CREATE TYPE "public"."route_kind" AS ENUM('html', 'asset', 'redirect', 'gone', 'dynamic', 'unresolved');--> statement-breakpoint CREATE TYPE "public"."route_query_policy" AS ENUM('ignore', 'exact', 'preserve', 'dynamic');--> statement-breakpoint CREATE TABLE "route_registry" ( "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, "site_id" uuid NOT NULL, "host" text NOT NULL, "source_path_raw" text NOT NULL, "route_path" text NOT NULL, "exact_route_key" text NOT NULL, "collision_key" text NOT NULL, "query_policy" "route_query_policy" NOT NULL, "query_key" text, "source_status" text NOT NULL, "target_status" text NOT NULL, "route_kind" "route_kind" NOT NULL, "target_content_id" uuid, "target_file" text, "redirect_status" integer, "redirect_location" text, "indexable" boolean NOT NULL, "priority" integer NOT NULL, "source_snapshot_id" uuid, "verification_status" 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 ALTER TABLE "route_registry" ADD CONSTRAINT "route_registry_site_id_sites_id_fk" FOREIGN KEY ("site_id") REFERENCES "public"."sites"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint ALTER TABLE "route_registry" ADD CONSTRAINT "route_registry_source_snapshot_id_source_snapshots_id_fk" FOREIGN KEY ("source_snapshot_id") REFERENCES "public"."source_snapshots"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint -- ↓ 手写追加(drizzle-kit 0.31 不生成 NULLS NOT DISTINCT 子句,schema 层故意的未声明该索引): -- 纯路径唯一——query_key 为 NULL 的路由也参与唯一(spec §5.6 要求数据库级强制,不用哨兵值; -- 默认 NULLS DISTINCT 下两行 NULL 不冲突,挡不住纯路径重复)。 CREATE UNIQUE INDEX route_exact_uq ON route_registry (site_id, host, exact_route_key, query_key) NULLS NOT DISTINCT;