Files
cms-website/apps/api/drizzle/0006_confused_lord_hawal.sql
T
2026-10-20 20:24:18 +08:00

107 lines
6.0 KiB
SQL

CREATE TYPE "public"."audit_actor_type" AS ENUM('system', 'cli_user');--> statement-breakpoint
CREATE TYPE "public"."build_artifact_kind" AS ENUM('dist', 'manifest', 'report', 'log');--> statement-breakpoint
CREATE TYPE "public"."build_job_status" AS ENUM('queued', 'snapshotting', 'building', 'validating', 'succeeded', 'failed', 'cancelled', 'stale');--> statement-breakpoint
CREATE TABLE "audit_logs" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"site_id" uuid,
"actor_type" "audit_actor_type" NOT NULL,
"actor_id" text,
"actor_label" text NOT NULL,
"command_id" text,
"action" text NOT NULL,
"object_type" text NOT NULL,
"object_id" text NOT NULL,
"before_value" jsonb,
"after_value" jsonb,
"occurred_at" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE "build_artifacts" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"build_job_id" uuid NOT NULL,
"kind" "build_artifact_kind" NOT NULL,
"storage_path" text NOT NULL,
"sha256" text NOT NULL,
"byte_size" bigint NOT NULL,
"created_at" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE "build_input_snapshots" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"build_job_id" uuid NOT NULL,
"site_id" uuid NOT NULL,
"content_snapshot_hash" text NOT NULL,
"route_snapshot_hash" text NOT NULL,
"asset_manifest_hash" text NOT NULL,
"site_config_revision_id" uuid,
"theme_key" text NOT NULL,
"theme_version" text NOT NULL,
"theme_source_hash" text NOT NULL,
"dependency_lock_hash" text NOT NULL,
"source_commit" text NOT NULL,
"node_version" text NOT NULL,
"pnpm_version" text NOT NULL,
"astro_version" text NOT NULL,
"locale" text NOT NULL,
"timezone" text NOT NULL,
"build_timestamp" timestamp with time zone NOT NULL,
"manifest_path" text NOT NULL,
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
CONSTRAINT "build_input_snapshots_build_job_id_unique" UNIQUE("build_job_id")
);
--> statement-breakpoint
CREATE TABLE "build_jobs" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"site_id" uuid NOT NULL,
"status" "build_job_status" NOT NULL,
"idempotency_key" text NOT NULL,
"attempt" integer DEFAULT 0 NOT NULL,
"worker_id" text,
"started_at" timestamp with time zone,
"heartbeat_at" timestamp with time zone,
"finished_at" timestamp with time zone,
"error_code" text,
"error_summary" text,
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
CONSTRAINT "build_jobs_idempotency_key_unique" UNIQUE("idempotency_key")
);
--> statement-breakpoint
CREATE TABLE "validation_issues" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"validation_run_id" uuid NOT NULL,
"severity" text NOT NULL,
"rule" text NOT NULL,
"url" text,
"evidence" jsonb NOT NULL,
"resolution_status" text NOT NULL,
"created_at" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE "validation_runs" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"site_id" uuid NOT NULL,
"build_job_id" uuid,
"rule_version" text NOT NULL,
"status" text NOT NULL,
"started_at" timestamp with time zone,
"finished_at" timestamp with time zone,
"created_at" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
ALTER TABLE "audit_logs" ADD CONSTRAINT "audit_logs_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 "build_artifacts" ADD CONSTRAINT "build_artifacts_build_job_id_build_jobs_id_fk" FOREIGN KEY ("build_job_id") REFERENCES "public"."build_jobs"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "build_input_snapshots" ADD CONSTRAINT "build_input_snapshots_build_job_id_build_jobs_id_fk" FOREIGN KEY ("build_job_id") REFERENCES "public"."build_jobs"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "build_input_snapshots" ADD CONSTRAINT "build_input_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 "build_input_snapshots" ADD CONSTRAINT "build_input_snapshots_site_config_revision_id_site_config_revisions_id_fk" FOREIGN KEY ("site_config_revision_id") REFERENCES "public"."site_config_revisions"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "build_jobs" ADD CONSTRAINT "build_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 "validation_issues" ADD CONSTRAINT "validation_issues_validation_run_id_validation_runs_id_fk" FOREIGN KEY ("validation_run_id") REFERENCES "public"."validation_runs"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "validation_runs" ADD CONSTRAINT "validation_runs_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 "validation_runs" ADD CONSTRAINT "validation_runs_build_job_id_build_jobs_id_fk" FOREIGN KEY ("build_job_id") REFERENCES "public"."build_jobs"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
CREATE UNIQUE INDEX "build_artifacts_uq" ON "build_artifacts" USING btree ("build_job_id","kind","storage_path");--> statement-breakpoint
-- ↓ 手写追加(drizzle-kit 不生成触发器):输入快照不可变 + 审计日志追加式(禁改禁删)。
-- sf_forbid_update 为 0001 建立的共享函数,此处复用(其报错文案 "immutable table %: UPDATE forbidden"
-- 同样覆盖 DELETE——触发器挂在 BEFORE UPDATE OR DELETE 上,两条路径走同一函数)。
CREATE TRIGGER build_input_snapshots_immutable BEFORE UPDATE OR DELETE ON build_input_snapshots
FOR EACH ROW EXECUTE FUNCTION sf_forbid_update();--> statement-breakpoint
CREATE TRIGGER audit_logs_immutable BEFORE UPDATE OR DELETE ON audit_logs
FOR EACH ROW EXECUTE FUNCTION sf_forbid_update();