-- ============================================================================= -- 迁移脚本:创建 biz Schema 业务表(coach_tasks / coach_task_history / notes / trigger_jobs) -- 日期:2026-02-27 -- 目标库:test_zqyy_app(通过 APP_DB_DSN 连接) -- 说明:在 biz Schema 下创建助教任务系统和备注系统所需的 4 张业务表, -- 包含字段定义、约束、CHECK 约束、外键、部分唯一索引和查询索引。 -- 前提:biz Schema 已由 2026-02-24__p1_create_auth_biz_schemas.sql 创建 -- 需求:1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9 -- ============================================================================= -- 确保 biz Schema 存在(幂等) CREATE SCHEMA IF NOT EXISTS biz; -- --------------------------------------------------------------------------- -- 1. biz.coach_tasks — 助教任务表 -- --------------------------------------------------------------------------- CREATE TABLE IF NOT EXISTS biz.coach_tasks ( id BIGSERIAL PRIMARY KEY, site_id BIGINT NOT NULL, assistant_id BIGINT NOT NULL, member_id BIGINT NOT NULL, task_type VARCHAR(50) NOT NULL, status VARCHAR(20) NOT NULL DEFAULT 'active', priority_score NUMERIC(5,2), expires_at TIMESTAMPTZ, is_pinned BOOLEAN DEFAULT FALSE, abandon_reason TEXT, completed_at TIMESTAMPTZ, completed_task_type VARCHAR(50), parent_task_id BIGINT REFERENCES biz.coach_tasks(id), created_at TIMESTAMPTZ DEFAULT NOW(), updated_at TIMESTAMPTZ DEFAULT NOW() ); -- 部分唯一索引:同一 (site_id, assistant_id, member_id, task_type) 下 active 任务最多一条 CREATE UNIQUE INDEX IF NOT EXISTS idx_coach_tasks_site_assistant_member_type ON biz.coach_tasks (site_id, assistant_id, member_id, task_type) WHERE status = 'active'; -- 助教任务列表查询索引 CREATE INDEX IF NOT EXISTS idx_coach_tasks_assistant_status ON biz.coach_tasks (site_id, assistant_id, status); -- --------------------------------------------------------------------------- -- 2. biz.coach_task_history — 任务变更历史表 -- --------------------------------------------------------------------------- CREATE TABLE IF NOT EXISTS biz.coach_task_history ( id BIGSERIAL PRIMARY KEY, task_id BIGINT NOT NULL REFERENCES biz.coach_tasks(id), action VARCHAR(50) NOT NULL, old_status VARCHAR(20), new_status VARCHAR(20), old_task_type VARCHAR(50), new_task_type VARCHAR(50), detail JSONB, created_at TIMESTAMPTZ DEFAULT NOW() ); -- --------------------------------------------------------------------------- -- 3. biz.notes — 统一备注表 -- --------------------------------------------------------------------------- CREATE TABLE IF NOT EXISTS biz.notes ( id BIGSERIAL PRIMARY KEY, site_id BIGINT NOT NULL, user_id INTEGER NOT NULL, target_type VARCHAR(50) NOT NULL, target_id BIGINT NOT NULL, type VARCHAR(20) NOT NULL DEFAULT 'normal', content TEXT NOT NULL, rating_service_willingness SMALLINT CHECK (rating_service_willingness BETWEEN 1 AND 5), rating_revisit_likelihood SMALLINT CHECK (rating_revisit_likelihood BETWEEN 1 AND 5), task_id BIGINT REFERENCES biz.coach_tasks(id), ai_score SMALLINT, ai_analysis TEXT, created_at TIMESTAMPTZ DEFAULT NOW(), updated_at TIMESTAMPTZ DEFAULT NOW() ); -- 按目标查询备注索引 CREATE INDEX IF NOT EXISTS idx_notes_target ON biz.notes (site_id, target_type, target_id); -- --------------------------------------------------------------------------- -- 4. biz.trigger_jobs — 触发器配置表 -- --------------------------------------------------------------------------- CREATE TABLE IF NOT EXISTS biz.trigger_jobs ( id SERIAL PRIMARY KEY, job_type VARCHAR(100) NOT NULL, job_name VARCHAR(100) NOT NULL UNIQUE, trigger_condition VARCHAR(20) NOT NULL, trigger_config JSONB NOT NULL, last_run_at TIMESTAMPTZ, next_run_at TIMESTAMPTZ, status VARCHAR(20) NOT NULL DEFAULT 'enabled', created_at TIMESTAMPTZ DEFAULT NOW() ); -- ============================================================================= -- 回滚脚本(按逆序执行) -- ============================================================================= -- DROP INDEX IF EXISTS biz.idx_notes_target; -- DROP INDEX IF EXISTS biz.idx_coach_tasks_assistant_status; -- DROP INDEX IF EXISTS biz.idx_coach_tasks_site_assistant_member_type; -- DROP TABLE IF EXISTS biz.trigger_jobs; -- DROP TABLE IF EXISTS biz.notes; -- DROP TABLE IF EXISTS biz.coach_task_history; -- DROP TABLE IF EXISTS biz.coach_tasks;