-- CreateEnum CREATE TYPE "IndustryStatus" AS ENUM ('ACTIVE', 'DISABLED'); -- CreateEnum CREATE TYPE "CustomerStatus" AS ENUM ('ACTIVE', 'PAUSED', 'ENDED'); -- CreateEnum CREATE TYPE "CustomerFieldStatus" AS ENUM ('PENDING', 'ACTIVE', 'REJECTED', 'DISABLED'); -- CreateTable CREATE TABLE "industries" ( "id" CHAR(26) NOT NULL, "parent_id" CHAR(26), "level" INTEGER NOT NULL DEFAULT 1, "name" VARCHAR(64) NOT NULL, "sort_order" INTEGER NOT NULL DEFAULT 10, "status" "IndustryStatus" NOT NULL DEFAULT 'ACTIVE', "remark" VARCHAR(200) NOT NULL DEFAULT '', "created_at" TIMESTAMPTZ(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, "updated_at" TIMESTAMPTZ(3) NOT NULL, CONSTRAINT "industries_pkey" PRIMARY KEY ("id") ); -- CreateTable CREATE TABLE "customers" ( "id" CHAR(26) NOT NULL, "industry_id" CHAR(26) NOT NULL, "name" VARCHAR(128) NOT NULL, "short_name" VARCHAR(32) NOT NULL, "status" "CustomerStatus" NOT NULL DEFAULT 'ACTIVE', "owner_user_id" CHAR(26) NOT NULL, "contact_name" VARCHAR(32), "contact_phone" VARCHAR(32), "preferences" JSONB NOT NULL DEFAULT '{}', "custom_fields" JSONB NOT NULL DEFAULT '[]', "remark" VARCHAR(500), "created_by" CHAR(26), "created_at" TIMESTAMPTZ(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, "updated_at" TIMESTAMPTZ(3) NOT NULL, "deleted_at" TIMESTAMPTZ(3), CONSTRAINT "customers_pkey" PRIMARY KEY ("id") ); -- CreateTable CREATE TABLE "customer_groups" ( "id" CHAR(26) NOT NULL, "name" VARCHAR(64) NOT NULL, "description" VARCHAR(255) NOT NULL DEFAULT '', "created_by" CHAR(26), "created_at" TIMESTAMPTZ(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, "updated_at" TIMESTAMPTZ(3) NOT NULL, CONSTRAINT "customer_groups_pkey" PRIMARY KEY ("id") ); -- CreateTable CREATE TABLE "customer_group_members" ( "group_id" CHAR(26) NOT NULL, "customer_id" CHAR(26) NOT NULL, "created_at" TIMESTAMPTZ(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, CONSTRAINT "customer_group_members_pkey" PRIMARY KEY ("group_id","customer_id") ); -- CreateTable CREATE TABLE "customer_fields" ( "id" CHAR(26) NOT NULL, "customer_id" CHAR(26) NOT NULL, "name" VARCHAR(32) NOT NULL, "code" VARCHAR(32) NOT NULL, "type" VARCHAR(16) NOT NULL, "options" JSONB NOT NULL DEFAULT '[]', "purpose" VARCHAR(200) NOT NULL, "enters_generation" BOOLEAN NOT NULL DEFAULT false, "status" "CustomerFieldStatus" NOT NULL DEFAULT 'PENDING', "applicant_user_id" CHAR(26) NOT NULL, "approver_user_id" CHAR(26), "applied_at" TIMESTAMPTZ(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, "approved_at" TIMESTAMPTZ(3), "reject_reason" VARCHAR(200), "created_at" TIMESTAMPTZ(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, "updated_at" TIMESTAMPTZ(3) NOT NULL, CONSTRAINT "customer_fields_pkey" PRIMARY KEY ("id") ); -- CreateIndex CREATE INDEX "industries_parent_id_sort_order_idx" ON "industries"("parent_id", "sort_order"); -- CreateIndex CREATE INDEX "industries_level_status_idx" ON "industries"("level", "status"); -- CreateIndex CREATE INDEX "customers_owner_user_id_status_idx" ON "customers"("owner_user_id", "status"); -- CreateIndex CREATE INDEX "customers_status_updated_at_idx" ON "customers"("status", "updated_at"); -- CreateIndex CREATE INDEX "customers_deleted_at_idx" ON "customers"("deleted_at"); -- CreateIndex CREATE UNIQUE INDEX "customers_industry_id_name_key" ON "customers"("industry_id", "name"); -- CreateIndex CREATE UNIQUE INDEX "customer_groups_name_key" ON "customer_groups"("name"); -- CreateIndex CREATE INDEX "customer_group_members_customer_id_idx" ON "customer_group_members"("customer_id"); -- CreateIndex CREATE INDEX "customer_fields_status_applied_at_idx" ON "customer_fields"("status", "applied_at"); -- CreateIndex CREATE INDEX "customer_fields_customer_id_status_idx" ON "customer_fields"("customer_id", "status"); -- CreateIndex CREATE UNIQUE INDEX "customer_fields_customer_id_code_key" ON "customer_fields"("customer_id", "code"); -- AddForeignKey ALTER TABLE "industries" ADD CONSTRAINT "industries_parent_id_fkey" FOREIGN KEY ("parent_id") REFERENCES "industries"("id") ON DELETE RESTRICT ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "customers" ADD CONSTRAINT "customers_industry_id_fkey" FOREIGN KEY ("industry_id") REFERENCES "industries"("id") ON DELETE RESTRICT ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "customers" ADD CONSTRAINT "customers_owner_user_id_fkey" FOREIGN KEY ("owner_user_id") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "customers" ADD CONSTRAINT "customers_created_by_fkey" FOREIGN KEY ("created_by") REFERENCES "users"("id") ON DELETE SET NULL ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "customer_group_members" ADD CONSTRAINT "customer_group_members_group_id_fkey" FOREIGN KEY ("group_id") REFERENCES "customer_groups"("id") ON DELETE CASCADE ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "customer_group_members" ADD CONSTRAINT "customer_group_members_customer_id_fkey" FOREIGN KEY ("customer_id") REFERENCES "customers"("id") ON DELETE CASCADE ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "customer_fields" ADD CONSTRAINT "customer_fields_customer_id_fkey" FOREIGN KEY ("customer_id") REFERENCES "customers"("id") ON DELETE CASCADE ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "customer_fields" ADD CONSTRAINT "customer_fields_applicant_user_id_fkey" FOREIGN KEY ("applicant_user_id") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "customer_fields" ADD CONSTRAINT "customer_fields_approver_user_id_fkey" FOREIGN KEY ("approver_user_id") REFERENCES "users"("id") ON DELETE SET NULL ON UPDATE CASCADE; -- A3 / ADR-002:行业名称唯一性(一级全局唯一,二级同父唯一)与两级结构校验 CREATE UNIQUE INDEX "industries_root_name_key" ON "industries"("name") WHERE "parent_id" IS NULL; CREATE UNIQUE INDEX "industries_child_name_key" ON "industries"("parent_id", "name") WHERE "parent_id" IS NOT NULL; ALTER TABLE "industries" ADD CONSTRAINT "industries_level_check" CHECK (("parent_id" IS NULL AND "level" = 1) OR ("parent_id" IS NOT NULL AND "level" = 2)); ALTER TABLE "industries" ADD CONSTRAINT "industries_no_self_parent_check" CHECK ("id" <> "parent_id");