# 变更审计记录：P18 任务引擎运营看板实施

| 字段 | 值 |
|------|-----|
| 日期 | 2026-03-24 07:44:01 |
| Prompt-ID | P20260324-072446 |
| Session-ID | — |
| Session 路径 | — |

## 操作摘要

基于已评审通过的 P18 PRD（v2.1-reviewed），实施管理后台任务引擎运营看板。新增 3 个前端页面（转移日志、待审核任务、参数管理）、9 个后端 API 端点、12 个 Pydantic Schema、1 个 DDL 迁移（trigger_jobs.last_stats + cfg_task_generator_params.updated_by）。

## 变更文件清单

### DDL 迁移
- `db/zqyy_app/migrations/2026-03-24__p18_task_engine_dashboard.sql` — trigger_jobs 新增 last_stats JSONB；cfg_task_generator_params 新增 updated_by BIGINT
- `docs/database/ddl/zqyy_app__biz.sql` — DDL 基线合并

### 后端（新建）
- `apps/backend/app/schemas/admin_task_engine.py` — 12 个 Pydantic v2 模型
- `apps/backend/app/routers/admin_task_engine.py` — 9 个端点（转移日志分页+历史、待审核任务分页+重新分配+关闭、参数管理 CRUD）

### 后端（修改）
- `apps/backend/app/main.py` — 追加 admin_task_engine router 注册

### 前端（新建）
- `apps/admin-web/src/api/taskEngine.ts` — API 调用模块（类型定义 + 9 个 API 函数）
- `apps/admin-web/src/pages/TransferLog.tsx` — 客户转移日志页面
- `apps/admin-web/src/pages/PendingReview.tsx` — 待审核任务页面
- `apps/admin-web/src/pages/TaskEngineConfig.tsx` — 参数管理页面

### 前端（修改）
- `apps/admin-web/src/App.tsx` — 新增任务引擎菜单组 + 3 个路由 + defaultOpenKeys

### 一次性脚本
- `scripts/ops/_p18_migrate.py` — DDL 迁移执行脚本（已执行完毕）

## 本次对话文件变更

### 新增文件
- `docs/audit/prompt_logs/prompt_log_20260324_072446.md`
- `docs/audit/session_logs/2026-03/24/29_3bf23309_071526/main_01_83361313.md`

## 风险点与待办

1. ⚠️ sites 表 JOIN 条件已修复（`s.site_id = t.site_id`），但需联调验证
2. ⚠️ FDW 姓名关联（member_name/assistant_name）尚未实现，当前返回空字符串，前端降级显示 ID
3. ⚠️ 权重参数联合校验依赖数据库事务，需验证并发场景
4. ⚠️ DDL 基线已合并（`docs/database/ddl/zqyy_app__biz.sql`）

## DDL/迁移状态

- 迁移文件：`db/zqyy_app/migrations/2026-03-24__p18_task_engine_dashboard.sql`
- 新增字段：`biz.trigger_jobs.last_stats` (JSONB)、`biz.cfg_task_generator_params.updated_by` (BIGINT)
- 迁移脚本使用 `ADD COLUMN IF NOT EXISTS`，幂等安全
- DDL 基线：已合并到 `docs/database/ddl/zqyy_app__biz.sql`


## 改动注解

### `db/zqyy_app/migrations/2026-03-24__p18_task_engine_dashboard.sql`
- 变更类型：新增
- 原始原因：P18 运营看板需要 trigger_jobs 表记录最近一次执行统计（last_stats JSONB），以及 cfg_task_generator_params 表记录修改人（updated_by BIGINT）用于审计追溯
- 思路分析：使用 `ADD COLUMN IF NOT EXISTS` 保证幂等性；last_stats 为 JSONB 类型，灵活存储 created/replaced/skipped/transferred 等统计数字；updated_by 为 BIGINT 对应 user_id
- 修改结果：trigger_jobs 表新增 1 字段，cfg_task_generator_params 表新增 1 字段，均可空，不影响现有查询

### `apps/backend/app/schemas/admin_task_engine.py`
- 变更类型：新增
- 原始原因：P18 运营看板 9 个 API 端点需要请求/响应数据模型
- 思路分析：12 个 Pydantic v2 模型，按功能分组（转移日志 2 个、待审核任务 6 个、参数管理 4 个）。所有模型使用 `str | None` 联合类型语法，字段默认值合理（如 member_name 默认空字符串，兼容 FDW 姓名未关联场景）
- 修改结果：为 admin_task_engine router 提供完整的类型安全数据模型

### `apps/backend/app/routers/admin_task_engine.py`
- 变更类型：新增
- 原始原因：P18 运营看板需要 9 个管理端 API 端点，覆盖转移日志查看、待审核任务管理、参数配置 CRUD
- 思路分析：路由前缀 `/api/admin/task-engine`，写操作通过 `_require_super_admin()` 限制仅超级管理员；读操作通过 `_filter_site_id()` 实现门店管理员数据隔离。SQL 使用参数化查询防注入，sites 表 JOIN 使用 `s.site_id`（已修复原 `s.id` 错误）。权重参数更新后做联合校验（w_rs + w_ms + w_ml = 1.0）
- 修改结果：9 个端点全部注册，含完整的权限校验、门店隔离、事务管理和错误处理

### `apps/backend/app/main.py`
- 变更类型：修改
- 原始原因：新增的 admin_task_engine router 需要在 FastAPI 应用中注册
- 思路分析：在 import 行和 `app.include_router()` 调用中追加 admin_task_engine，保持与现有 router 注册模式一致
- 修改结果：admin_task_engine router 已注册，9 个端点可通过 /docs 访问

### `apps/admin-web/src/api/taskEngine.ts`
- 变更类型：新增
- 原始原因：前端 3 个页面需要与后端 9 个 API 端点通信
- 思路分析：定义 TypeScript 接口（TransferLogItem/Page、PendingReviewItem/Page、ConfigParam/List）和 9 个 API 函数，使用 apiClient（Axios 实例）统一处理 JWT 认证和错误
- 修改结果：前端 API 层完整覆盖后端所有端点

### `apps/admin-web/src/pages/TransferLog.tsx`
- 变更类型：新增
- 原始原因：运营团队需要查看客户转移日志，按门店/时间/助教筛选
- 思路分析：Ant Design Table 分页表格 + RangePicker 日期筛选 + InputNumber 门店/助教 ID 筛选。guard_checks JSON 渲染为彩色标签（通过/未通过）。transfer_reason 映射中文标签
- 修改结果：转移日志页面完整可用，支持分页、筛选、guard_checks 可视化

### `apps/admin-web/src/pages/PendingReview.tsx`
- 变更类型：新增
- 原始原因：运营团队需要审核 pending_review 状态的任务，执行重新分配或关闭操作
- 思路分析：分页表格 + 重新分配弹窗（输入目标助教 ID）+ 关闭弹窗（填写原因）+ 转移历史抽屉（点击客户名查看）。操作列仅超级管理员可见（`isSuperAdmin` 判断）
- 修改结果：待审核任务页面完整可用，含权限控制和完整的操作流程

### `apps/admin-web/src/pages/TaskEngineConfig.tsx`
- 变更类型：新增
- 原始原因：运营团队需要按门店调整任务生成参数，监控参数配置
- 思路分析：全局默认 + 门店覆盖参数表格，行内编辑单个参数值。权重参数（w_rs/w_ms/w_ml）使用独立的卡片编辑弹窗，前端预校验三者之和 = 1.0。新增门店覆盖通过 Select 选择参数名 + InputNumber 输入值。全局默认参数禁止删除
- 修改结果：参数管理页面完整可用，含行内编辑、权重卡片编辑、新增/删除门店覆盖

### `apps/admin-web/src/App.tsx`
- 变更类型：修改
- 原始原因：新增的 3 个页面需要在侧边栏导航和路由中注册
- 思路分析：新增 ApartmentOutlined 图标 import、3 个页面 import、task-engine-group 菜单组（含 3 个子菜单）、3 个 Route、defaultOpenKeys 补充 task-engine-group（当路径以 /task-engine/ 开头时自动展开）
- 修改结果：侧边栏新增「任务引擎」菜单组，3 个子页面路由正常工作

### `scripts/ops/_p18_migrate.py`
- 变更类型：新增
- 原始原因：DDL 迁移需要执行脚本
- 思路分析：一次性脚本，连接测试库执行迁移 SQL
- 修改结果：迁移已执行完毕，脚本保留用于记录

## 验证建议

1. 启动后端 `uvicorn app.main:app --reload`，访问 /docs 确认 9 个端点注册
2. 启动前端 `pnpm dev`，验证侧边栏「任务引擎」菜单组和 3 个页面路由
3. 用 super_admin JWT 测试写操作，用 site_admin JWT 验证 403
