BD_Manual:biz Schema 业务表(助教任务系统 + 备注系统 + 触发器调度)
目标库:test_zqyy_app(通过 APP_DB_DSN 连接)
迁移脚本:
db/zqyy_app/migrations/2026-02-27__p4_create_biz_tables.sql(建表)
db/zqyy_app/migrations/2026-02-27__p4_seed_trigger_jobs.sql(种子数据)
关联 SPEC:04-miniapp-core-business(P4 小程序核心业务模块)
1. 变更说明
新增表(4 张)
| # |
表名 |
用途 |
字段数 |
| 1 |
biz.coach_tasks |
助教任务表:存储任务分配、状态、有效期、置顶、放弃原因等 |
15 |
| 2 |
biz.coach_task_history |
任务变更历史表:记录任务关闭/新建/置顶/放弃的追溯链 |
9 |
| 3 |
biz.notes |
统一备注表:通过 type 字段区分普通备注/回访备注/放弃原因,含星星评分 |
14 |
| 4 |
biz.trigger_jobs |
触发器配置表:存储 cron/interval/event 三种触发方式的配置与执行状态 |
9 |
表字段明细
biz.coach_tasks(15 字段)
| 字段 |
类型 |
约束 |
说明 |
id |
BIGSERIAL |
PK |
自增主键 |
site_id |
BIGINT |
NOT NULL |
门店 ID(多门店隔离) |
assistant_id |
BIGINT |
NOT NULL |
助教 ID |
member_id |
BIGINT |
NOT NULL |
客户 ID |
task_type |
VARCHAR(50) |
NOT NULL |
任务类型:high_priority_recall / priority_recall / follow_up_visit / relationship_building |
status |
VARCHAR(20) |
NOT NULL DEFAULT 'active' |
状态:active / inactive / completed / abandoned |
priority_score |
NUMERIC(5,2) |
可空 |
优先级分数,取 max(WBI, NCI) 快照 |
expires_at |
TIMESTAMPTZ |
可空 |
有效期时间戳,NULL 表示无限期 |
is_pinned |
BOOLEAN |
DEFAULT FALSE |
是否置顶 |
abandon_reason |
TEXT |
可空 |
放弃原因(放弃时必填) |
completed_at |
TIMESTAMPTZ |
可空 |
完成时间 |
completed_task_type |
VARCHAR(50) |
可空 |
完成时的任务类型快照 |
parent_task_id |
BIGINT |
FK → biz.coach_tasks(id),可空 |
父任务 ID(自引用) |
created_at |
TIMESTAMPTZ |
DEFAULT NOW() |
创建时间 |
updated_at |
TIMESTAMPTZ |
DEFAULT NOW() |
更新时间 |
biz.coach_task_history(9 字段)
| 字段 |
类型 |
约束 |
说明 |
id |
BIGSERIAL |
PK |
自增主键 |
task_id |
BIGINT |
NOT NULL, FK → biz.coach_tasks(id) |
关联任务 |
action |
VARCHAR(50) |
NOT NULL |
操作类型:created / type_changed / pinned / abandoned / cancel_abandon / expired / completed |
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() |
记录时间 |
biz.notes(14 字段)
| 字段 |
类型 |
约束 |
说明 |
id |
BIGSERIAL |
PK |
自增主键 |
site_id |
BIGINT |
NOT NULL |
门店 ID |
user_id |
INTEGER |
NOT NULL |
小程序用户 ID |
target_type |
VARCHAR(50) |
NOT NULL |
目标类型(如 member) |
target_id |
BIGINT |
NOT NULL |
目标 ID(如 member_id) |
type |
VARCHAR(20) |
NOT NULL DEFAULT 'normal' |
备注类型:normal / follow_up / abandon_reason |
content |
TEXT |
NOT NULL |
备注内容 |
rating_service_willingness |
SMALLINT |
CHECK (1-5),可空 |
再次服务意愿评分 |
rating_revisit_likelihood |
SMALLINT |
CHECK (1-5),可空 |
再来店可能性评分 |
task_id |
BIGINT |
FK → biz.coach_tasks(id),可空 |
关联任务 |
ai_score |
SMALLINT |
可空 |
AI 应用 6 评分(P5 实现) |
ai_analysis |
TEXT |
可空 |
AI 分析结果(P5 实现) |
created_at |
TIMESTAMPTZ |
DEFAULT NOW() |
创建时间 |
updated_at |
TIMESTAMPTZ |
DEFAULT NOW() |
更新时间 |
biz.trigger_jobs(9 字段)
| 字段 |
类型 |
约束 |
说明 |
id |
SERIAL |
PK |
自增主键 |
job_type |
VARCHAR(100) |
NOT NULL |
任务类型标识,映射到 Python handler |
job_name |
VARCHAR(100) |
NOT NULL, UNIQUE |
任务名称(唯一) |
trigger_condition |
VARCHAR(20) |
NOT NULL |
触发方式:cron / interval / event |
trigger_config |
JSONB |
NOT NULL |
触发配置(cron 表达式 / 间隔秒数 / 事件名) |
last_run_at |
TIMESTAMPTZ |
可空 |
上次运行时间 |
next_run_at |
TIMESTAMPTZ |
可空 |
下次运行时间(event 类型为 NULL) |
status |
VARCHAR(20) |
NOT NULL DEFAULT 'enabled' |
状态:enabled / disabled |
created_at |
TIMESTAMPTZ |
DEFAULT NOW() |
创建时间 |
约束与索引
| 表 |
约束/索引名 |
类型 |
说明 |
coach_tasks |
idx_coach_tasks_site_assistant_member_type |
UNIQUE INDEX (partial) |
(site_id, assistant_id, member_id, task_type) WHERE status = 'active',保证同一组合下活跃任务最多一条 |
coach_tasks |
idx_coach_tasks_assistant_status |
INDEX |
(site_id, assistant_id, status),助教任务列表查询加速 |
coach_tasks |
FK parent_task_id |
FK |
→ biz.coach_tasks(id),自引用 |
coach_task_history |
FK task_id |
FK |
→ biz.coach_tasks(id) |
notes |
idx_notes_target |
INDEX |
(site_id, target_type, target_id),按目标查询备注加速 |
notes |
CHECK rating_service_willingness |
CHECK |
BETWEEN 1 AND 5 |
notes |
CHECK rating_revisit_likelihood |
CHECK |
BETWEEN 1 AND 5 |
notes |
FK task_id |
FK |
→ biz.coach_tasks(id) |
trigger_jobs |
UNIQUE job_name |
UNIQUE |
触发器名称唯一 |
种子数据(4 条触发器配置)
| job_name |
job_type |
trigger_condition |
trigger_config |
next_run_at |
说明 |
task_generator |
task_generator |
cron |
{"cron_expression": "0 4 * * *"} |
次日 04:00 |
每日凌晨 4:00 运行任务生成器 |
task_expiry_check |
task_expiry_check |
interval |
{"interval_seconds": 3600} |
NOW() + 1h |
每小时检查过期任务 |
recall_completion_check |
recall_completion_check |
event |
{"event_name": "etl_data_updated"} |
NULL |
ETL 数据更新后触发召回完成检测 |
note_reclassify_backfill |
note_reclassify_backfill |
event |
{"event_name": "recall_completed"} |
NULL |
召回完成后触发备注回溯重分类 |
2. 兼容性影响
| 组件 |
影响 |
| ETL 任务 |
无直接影响。biz Schema 表不参与 ETL 流程,但任务生成器通过 FDW 只读访问 ETL 库的 WBI/NCI/RS 指数数据 |
| 后端 API |
直接依赖。FastAPI 后端将基于这些表实现任务 CRUD(/api/xcx/tasks)、备注 CRUD(/api/xcx/notes)、触发器调度等功能 |
| 小程序 |
间接依赖。小程序通过后端 API 间接使用任务列表、备注功能 |
| 管理后台 |
暂无影响。后续可能增加任务监控和触发器管理界面 |
| FDW 配置 |
无影响。fdw_etl Schema 独立于 biz,任务生成器和召回检测器通过 FDW 只读查询 ETL 库 |
auth Schema |
间接依赖。任务生成器通过 auth.user_assistant_binding 确定助教与小程序用户的映射关系 |
public Schema |
无影响。member_retention_clue 表独立于本次变更 |
现有 biz Schema |
兼容。biz Schema 已由 P1 迁移脚本创建,本次仅在其中新增 4 张表,不修改已有对象 |
3. 回滚策略
按逆序 DROP TABLE IF EXISTS CASCADE(迁移脚本末尾已包含注释形式的回滚语句):
注意:
CASCADE 会级联删除依赖对象(外键引用的子表数据)
- 如果表中已有业务数据,需先备份再执行回滚
- 回滚不会删除
biz Schema 本身(由 P1 创建,其他表可能依赖)
4. 验证 SQL