32ceba58f0
Co-Authored-By: Claude Code <noreply@anthropic.com>
78 lines
5.2 KiB
PL/PgSQL
78 lines
5.2 KiB
PL/PgSQL
CREATE TYPE "public"."import_job_status" AS ENUM('queued', 'running', 'succeeded', 'succeeded_with_issues', 'failed', 'cancelled', 'stale');--> statement-breakpoint
|
|
CREATE TYPE "public"."source_connection_kind" AS ENUM('wxr');--> statement-breakpoint
|
|
CREATE TYPE "public"."source_snapshot_kind" AS ENUM('wxr', 'sitemap', 'media_bundle', 'manual_url_list');--> statement-breakpoint
|
|
CREATE TABLE "import_jobs" (
|
|
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
|
|
"site_id" uuid NOT NULL,
|
|
"source_snapshot_id" uuid NOT NULL,
|
|
"status" "import_job_status" NOT NULL,
|
|
"mapping_version" text NOT NULL,
|
|
"idempotency_key" text NOT NULL,
|
|
"attempt" integer DEFAULT 0 NOT NULL,
|
|
"started_at" timestamp with time zone,
|
|
"finished_at" timestamp with time zone,
|
|
"error_code" text,
|
|
"error_summary" text,
|
|
"report_path" text,
|
|
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
|
|
CONSTRAINT "import_jobs_idempotency_key_unique" UNIQUE("idempotency_key")
|
|
);
|
|
--> statement-breakpoint
|
|
CREATE TABLE "source_connections" (
|
|
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
|
|
"site_id" uuid NOT NULL,
|
|
"kind" "source_connection_kind" NOT NULL,
|
|
"name" text NOT NULL,
|
|
"configuration" jsonb NOT NULL,
|
|
"created_at" timestamp with time zone DEFAULT now() NOT NULL
|
|
);
|
|
--> statement-breakpoint
|
|
CREATE TABLE "source_records" (
|
|
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
|
|
"site_id" uuid NOT NULL,
|
|
"source_connection_id" uuid NOT NULL,
|
|
"source_snapshot_id" uuid NOT NULL,
|
|
"import_job_id" uuid NOT NULL,
|
|
"source_type" text NOT NULL,
|
|
"source_id" text NOT NULL,
|
|
"locale" text NOT NULL,
|
|
"source_url" text,
|
|
"raw_location" text NOT NULL,
|
|
"source_checksum" text,
|
|
"normalized_checksum" text,
|
|
"parse_status" text NOT NULL,
|
|
"content_entry_id" uuid,
|
|
"created_at" timestamp with time zone DEFAULT now() NOT NULL
|
|
);
|
|
--> statement-breakpoint
|
|
CREATE TABLE "source_snapshots" (
|
|
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
|
|
"site_id" uuid NOT NULL,
|
|
"source_connection_id" uuid NOT NULL,
|
|
"kind" "source_snapshot_kind" NOT NULL,
|
|
"storage_path" text NOT NULL,
|
|
"sha256" text NOT NULL,
|
|
"byte_size" bigint NOT NULL,
|
|
"adapter_version" text NOT NULL,
|
|
"captured_at" timestamp with time zone NOT NULL,
|
|
"metadata" jsonb NOT NULL,
|
|
"created_at" timestamp with time zone DEFAULT now() NOT NULL
|
|
);
|
|
--> statement-breakpoint
|
|
ALTER TABLE "import_jobs" ADD CONSTRAINT "import_jobs_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 "import_jobs" ADD CONSTRAINT "import_jobs_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
|
|
ALTER TABLE "source_connections" ADD CONSTRAINT "source_connections_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 "source_records" ADD CONSTRAINT "source_records_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 "source_records" ADD CONSTRAINT "source_records_source_connection_id_source_connections_id_fk" FOREIGN KEY ("source_connection_id") REFERENCES "public"."source_connections"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
|
|
ALTER TABLE "source_records" ADD CONSTRAINT "source_records_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
|
|
ALTER TABLE "source_records" ADD CONSTRAINT "source_records_import_job_id_import_jobs_id_fk" FOREIGN KEY ("import_job_id") REFERENCES "public"."import_jobs"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
|
|
ALTER TABLE "source_snapshots" ADD CONSTRAINT "source_snapshots_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 "source_snapshots" ADD CONSTRAINT "source_snapshots_source_connection_id_source_connections_id_fk" FOREIGN KEY ("source_connection_id") REFERENCES "public"."source_connections"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
|
|
CREATE UNIQUE INDEX "source_records_identity_uq" ON "source_records" USING btree ("site_id","source_connection_id","source_type","source_id","locale","source_snapshot_id");--> statement-breakpoint
|
|
CREATE UNIQUE INDEX "source_snapshots_uq" ON "source_snapshots" USING btree ("site_id","kind","sha256");--> statement-breakpoint
|
|
-- ↓ 手写追加(drizzle-kit 不生成触发器):快照不可变。sf_forbid_update 为共享函数,
|
|
-- 后续 content_revisions / audit_logs / build_input_snapshots 三张不可变表复用(Task 8/12)。
|
|
CREATE OR REPLACE FUNCTION sf_forbid_update() RETURNS trigger AS $$
|
|
BEGIN RAISE EXCEPTION 'immutable table %: UPDATE forbidden', TG_TABLE_NAME; END $$ LANGUAGE plpgsql;--> statement-breakpoint
|
|
CREATE TRIGGER source_snapshots_immutable BEFORE UPDATE OR DELETE ON source_snapshots
|
|
FOR EACH ROW EXECUTE FUNCTION sf_forbid_update(); |