R18-1/R18-3: 接入企业微信入口绑定与免登回退

这个提交包含在:
2026-03-22 08:33:53 +08:00
父节点 2a1ffe66f3
当前提交 215e3967bc
共修改 15 个文件,包含 1394 行新增和 26 行删除
@@ -0,0 +1,357 @@
-- CreateEnum
CREATE TYPE "ProjectStatus" AS ENUM ('draft', 'active', 'paused', 'completed', 'archived');
-- CreateEnum
CREATE TYPE "ProjectRole" AS ENUM ('owner', 'manager', 'member', 'observer');
-- CreateEnum
CREATE TYPE "ProjectMilestoneStatus" AS ENUM ('pending', 'in_progress', 'done', 'delayed', 'cancelled');
-- CreateEnum
CREATE TYPE "ProjectTaskStatus" AS ENUM ('todo', 'doing', 'blocked', 'done', 'cancelled');
-- CreateEnum
CREATE TYPE "ProjectTaskPriority" AS ENUM ('low', 'normal', 'high', 'urgent');
-- CreateEnum
CREATE TYPE "ProjectRiskLevel" AS ENUM ('low', 'medium', 'high');
-- CreateEnum
CREATE TYPE "ProjectDeliveryRecordType" AS ENUM ('kickoff', 'onsite', 'stage_acceptance', 'final_acceptance', 'handover');
-- CreateEnum
CREATE TYPE "ConfidentialityLevel" AS ENUM ('public', 'internal', 'confidential', 'restricted');
-- CreateEnum
CREATE TYPE "DocumentStorageType" AS ENUM ('oa_link', 'nas', 'internal_share', 'offline_archive');
-- AlterEnum
ALTER TYPE "WorkspacePrimaryEntryMode" ADD VALUE 'wecom';
-- AlterTable
ALTER TABLE "reimbursement_forms" ADD COLUMN "project_id" UUID;
-- AlterTable
ALTER TABLE "todo_items" ADD COLUMN "project_id" UUID;
-- AlterTable
ALTER TABLE "travel_requests" ADD COLUMN "project_id" UUID;
-- CreateTable
CREATE TABLE "wecom_identity_bindings" (
"id" UUID NOT NULL,
"employee_id" UUID NOT NULL,
"external_user_id" VARCHAR(128) NOT NULL,
"external_open_user_id" VARCHAR(128),
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"created_by" UUID,
"updated_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_by" UUID,
CONSTRAINT "wecom_identity_bindings_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "projects" (
"id" UUID NOT NULL,
"project_no" TEXT NOT NULL,
"name" TEXT NOT NULL,
"client_name" TEXT NOT NULL,
"client_alias" TEXT,
"owner_employee_id" UUID NOT NULL,
"manager_employee_id" UUID,
"status" "ProjectStatus" NOT NULL DEFAULT 'draft',
"starts_at" DATE,
"target_end_at" DATE,
"actual_end_at" DATE,
"summary" TEXT,
"is_confidential" BOOLEAN NOT NULL DEFAULT false,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "projects_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "project_members" (
"id" UUID NOT NULL,
"project_id" UUID NOT NULL,
"employee_id" UUID NOT NULL,
"role" "ProjectRole" NOT NULL DEFAULT 'member',
"joined_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"left_at" TIMESTAMP(3),
CONSTRAINT "project_members_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "project_milestones" (
"id" UUID NOT NULL,
"project_id" UUID NOT NULL,
"title" TEXT NOT NULL,
"description" TEXT,
"status" "ProjectMilestoneStatus" NOT NULL DEFAULT 'pending',
"due_date" DATE,
"completed_at" TIMESTAMP(3),
"owner_employee_id" UUID,
"sort_order" INTEGER NOT NULL DEFAULT 100,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "project_milestones_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "project_tasks" (
"id" UUID NOT NULL,
"project_id" UUID NOT NULL,
"title" TEXT NOT NULL,
"description" TEXT,
"status" "ProjectTaskStatus" NOT NULL DEFAULT 'todo',
"priority" "ProjectTaskPriority" NOT NULL DEFAULT 'normal',
"assignee_employee_id" UUID,
"due_date" DATE,
"blocked_reason" TEXT,
"created_by" UUID NOT NULL,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "project_tasks_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "project_risks" (
"id" UUID NOT NULL,
"project_id" UUID NOT NULL,
"title" TEXT NOT NULL,
"detail" TEXT NOT NULL,
"level" "ProjectRiskLevel" NOT NULL DEFAULT 'medium',
"status" VARCHAR(32) NOT NULL DEFAULT 'open',
"owner_employee_id" UUID,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "project_risks_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "weekly_report_project_links" (
"id" UUID NOT NULL,
"weekly_report_id" UUID NOT NULL,
"project_id" UUID NOT NULL,
"progress_text" TEXT NOT NULL DEFAULT '',
"risk_text" TEXT NOT NULL DEFAULT '',
"next_step_text" TEXT NOT NULL DEFAULT '',
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "weekly_report_project_links_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "contract_registry" (
"id" UUID NOT NULL,
"contract_no" TEXT NOT NULL,
"project_id" UUID,
"counterparty_name" TEXT NOT NULL,
"summary" TEXT NOT NULL,
"confidentiality_level" "ConfidentialityLevel" NOT NULL DEFAULT 'internal',
"archive_location" TEXT NOT NULL,
"offline_archive_no" TEXT,
"owner_employee_id" UUID NOT NULL,
"status" VARCHAR(32) NOT NULL DEFAULT 'active',
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "contract_registry_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "project_delivery_records" (
"id" UUID NOT NULL,
"project_id" UUID NOT NULL,
"title" TEXT NOT NULL,
"record_type" "ProjectDeliveryRecordType" NOT NULL,
"summary" TEXT NOT NULL,
"occurred_at" TIMESTAMP(3) NOT NULL,
"owner_employee_id" UUID NOT NULL,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "project_delivery_records_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "confidential_document_refs" (
"id" UUID NOT NULL,
"project_id" UUID,
"contract_registry_id" UUID,
"title" TEXT NOT NULL,
"document_no" TEXT,
"confidentiality_level" "ConfidentialityLevel" NOT NULL DEFAULT 'internal',
"storage_type" "DocumentStorageType" NOT NULL,
"storage_path" TEXT NOT NULL,
"offline_archive_no" TEXT,
"owner_employee_id" UUID NOT NULL,
"access_rule_json" JSONB,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "confidential_document_refs_pkey" PRIMARY KEY ("id")
);
-- CreateIndex
CREATE UNIQUE INDEX "wecom_identity_bindings_employee_id_key" ON "wecom_identity_bindings"("employee_id");
-- CreateIndex
CREATE UNIQUE INDEX "wecom_identity_bindings_external_user_id_key" ON "wecom_identity_bindings"("external_user_id");
-- CreateIndex
CREATE INDEX "idx_wecom_identity_bindings_external_user" ON "wecom_identity_bindings"("external_user_id");
-- CreateIndex
CREATE UNIQUE INDEX "projects_project_no_key" ON "projects"("project_no");
-- CreateIndex
CREATE INDEX "idx_projects_owner_status" ON "projects"("owner_employee_id", "status");
-- CreateIndex
CREATE INDEX "idx_projects_manager_status" ON "projects"("manager_employee_id", "status");
-- CreateIndex
CREATE INDEX "idx_projects_status_target_end" ON "projects"("status", "target_end_at");
-- CreateIndex
CREATE INDEX "idx_projects_client_name" ON "projects"("client_name", "name");
-- CreateIndex
CREATE INDEX "idx_project_members_employee_open" ON "project_members"("employee_id", "left_at");
-- CreateIndex
CREATE UNIQUE INDEX "project_members_project_employee_ux" ON "project_members"("project_id", "employee_id");
-- CreateIndex
CREATE INDEX "idx_project_milestones_project_sort" ON "project_milestones"("project_id", "sort_order");
-- CreateIndex
CREATE INDEX "idx_project_milestones_owner_due" ON "project_milestones"("owner_employee_id", "due_date");
-- CreateIndex
CREATE INDEX "idx_project_tasks_project_status_priority" ON "project_tasks"("project_id", "status", "priority");
-- CreateIndex
CREATE INDEX "idx_project_tasks_assignee_status" ON "project_tasks"("assignee_employee_id", "status");
-- CreateIndex
CREATE INDEX "idx_project_risks_project_status_level" ON "project_risks"("project_id", "status", "level");
-- CreateIndex
CREATE INDEX "idx_project_risks_owner_status" ON "project_risks"("owner_employee_id", "status");
-- CreateIndex
CREATE INDEX "idx_weekly_report_project_links_project_updated" ON "weekly_report_project_links"("project_id", "updated_at");
-- CreateIndex
CREATE UNIQUE INDEX "weekly_report_project_links_report_project_ux" ON "weekly_report_project_links"("weekly_report_id", "project_id");
-- CreateIndex
CREATE UNIQUE INDEX "contract_registry_contract_no_key" ON "contract_registry"("contract_no");
-- CreateIndex
CREATE INDEX "idx_contract_registry_project_status" ON "contract_registry"("project_id", "status");
-- CreateIndex
CREATE INDEX "idx_contract_registry_owner_created" ON "contract_registry"("owner_employee_id", "created_at");
-- CreateIndex
CREATE INDEX "idx_project_delivery_records_project_occurred" ON "project_delivery_records"("project_id", "occurred_at");
-- CreateIndex
CREATE INDEX "idx_confidential_doc_refs_project_level" ON "confidential_document_refs"("project_id", "confidentiality_level");
-- CreateIndex
CREATE INDEX "idx_confidential_doc_refs_contract" ON "confidential_document_refs"("contract_registry_id");
-- CreateIndex
CREATE INDEX "idx_confidential_doc_refs_owner_created" ON "confidential_document_refs"("owner_employee_id", "created_at");
-- CreateIndex
CREATE INDEX "idx_reimbursement_forms_project" ON "reimbursement_forms"("project_id");
-- CreateIndex
CREATE INDEX "idx_todo_items_project_status" ON "todo_items"("project_id", "status");
-- CreateIndex
CREATE INDEX "idx_travel_requests_project" ON "travel_requests"("project_id");
-- AddForeignKey
ALTER TABLE "reimbursement_forms" ADD CONSTRAINT "reimbursement_forms_project_id_fkey" FOREIGN KEY ("project_id") REFERENCES "projects"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "todo_items" ADD CONSTRAINT "todo_items_project_id_fkey" FOREIGN KEY ("project_id") REFERENCES "projects"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "wecom_identity_bindings" ADD CONSTRAINT "wecom_identity_bindings_employee_id_fkey" FOREIGN KEY ("employee_id") REFERENCES "employees"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "projects" ADD CONSTRAINT "projects_owner_employee_id_fkey" FOREIGN KEY ("owner_employee_id") REFERENCES "employees"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "projects" ADD CONSTRAINT "projects_manager_employee_id_fkey" FOREIGN KEY ("manager_employee_id") REFERENCES "employees"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "project_members" ADD CONSTRAINT "project_members_project_id_fkey" FOREIGN KEY ("project_id") REFERENCES "projects"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "project_members" ADD CONSTRAINT "project_members_employee_id_fkey" FOREIGN KEY ("employee_id") REFERENCES "employees"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "project_milestones" ADD CONSTRAINT "project_milestones_project_id_fkey" FOREIGN KEY ("project_id") REFERENCES "projects"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "project_milestones" ADD CONSTRAINT "project_milestones_owner_employee_id_fkey" FOREIGN KEY ("owner_employee_id") REFERENCES "employees"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "project_tasks" ADD CONSTRAINT "project_tasks_project_id_fkey" FOREIGN KEY ("project_id") REFERENCES "projects"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "project_tasks" ADD CONSTRAINT "project_tasks_assignee_employee_id_fkey" FOREIGN KEY ("assignee_employee_id") REFERENCES "employees"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "project_tasks" ADD CONSTRAINT "project_tasks_created_by_fkey" FOREIGN KEY ("created_by") REFERENCES "employees"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "project_risks" ADD CONSTRAINT "project_risks_project_id_fkey" FOREIGN KEY ("project_id") REFERENCES "projects"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "project_risks" ADD CONSTRAINT "project_risks_owner_employee_id_fkey" FOREIGN KEY ("owner_employee_id") REFERENCES "employees"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "weekly_report_project_links" ADD CONSTRAINT "weekly_report_project_links_weekly_report_id_fkey" FOREIGN KEY ("weekly_report_id") REFERENCES "weekly_reports"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "weekly_report_project_links" ADD CONSTRAINT "weekly_report_project_links_project_id_fkey" FOREIGN KEY ("project_id") REFERENCES "projects"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "contract_registry" ADD CONSTRAINT "contract_registry_project_id_fkey" FOREIGN KEY ("project_id") REFERENCES "projects"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "contract_registry" ADD CONSTRAINT "contract_registry_owner_employee_id_fkey" FOREIGN KEY ("owner_employee_id") REFERENCES "employees"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "project_delivery_records" ADD CONSTRAINT "project_delivery_records_project_id_fkey" FOREIGN KEY ("project_id") REFERENCES "projects"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "project_delivery_records" ADD CONSTRAINT "project_delivery_records_owner_employee_id_fkey" FOREIGN KEY ("owner_employee_id") REFERENCES "employees"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "confidential_document_refs" ADD CONSTRAINT "confidential_document_refs_project_id_fkey" FOREIGN KEY ("project_id") REFERENCES "projects"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "confidential_document_refs" ADD CONSTRAINT "confidential_document_refs_contract_registry_id_fkey" FOREIGN KEY ("contract_registry_id") REFERENCES "contract_registry"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "confidential_document_refs" ADD CONSTRAINT "confidential_document_refs_owner_employee_id_fkey" FOREIGN KEY ("owner_employee_id") REFERENCES "employees"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "travel_requests" ADD CONSTRAINT "travel_requests_project_id_fkey" FOREIGN KEY ("project_id") REFERENCES "projects"("id") ON DELETE SET NULL ON UPDATE CASCADE;