chore(docs): Wave 0 调研产出 + P0/P1/P2 反馈调研
建立项目级标杆文档 docs/_overview/ 作为产品全景索引, 解决"PRD 零碎、文档膨胀、跨子系统调研无入口"的问题。 主要内容: - 00-index 总索引 + 维护协议 + 与 CLAUDE.md 关系 - 01-product-overview 产品全景脑图(6 角色 / 6 子系统 / 数据流 / 7 业务概念 / 8+1 AI 矩阵 / 22 术语) - 02a-miniprogram-page-matrix 小程序 21 页业务指纹 - 02b-adminweb-page-matrix admin-web 19 路由业务指纹 - 03-test-spec 测试规范 (L1-L5 分层 + 走查模板 + 75-95 case 估算) - 04-doc-conflicts 39 条冲突索引(P0×8 / P1×13 / P2×13 + 5 子项) - 04a/b/c-conflicts-*-detail 业务故事卡(7 字段:关联/逻辑/影响/选项/判定) - 05-orphan-pages-cleanup admin-web 6 孤儿页面处置(1 归档 + 4 保留) - WAVES-MASTER-PLAN.md 全 Wave 主计划(0-5,共 22-32 工作日) - WAVE-1-KICKOFF.md Wave 1 实施 kickoff - GLOBAL-DECISION-DASHBOARD.md 全局决策仪表板 反馈调研产物: - 04a-feedback/ P0 两轮反馈(8+8 项决策 + D-1/2/3 + F-1/2 子代理产出) - 04b-feedback/ P1 两轮反馈(13+1+5 项 + E-1/2/3/4 + G-1/2 子代理产出) - 04c-feedback/ P2 反馈(13 项 + 5 子项 + H-1/2/3 子代理产出) - NEO-DECISIONS-LOG 累积决策记录 关键追加发现 8 处 D Bug(原蓝本 0): - P0-3 看板沙箱接入(Wave 1 W1-T1) - P0-5 致命 1 (4 处 fdw_etl 残留, 已修 commit17f045a) - P0-5 致命 2 (JWT aud 缺失, 已修 commit17f045a) - P0-6 clearAllTasks 守卫 (Wave 3) - P0-8 DBViewer 黑名单漏 (已修 commit17f045a) - P1-3 task-detail 跳转传 task_id 而非 customer_id - P2-7 board-finance 隐式 null - 2 个独立 Bug (page_context.created_at + ClueCategory 字典) 参考: docs/_overview/00-index.md
This commit is contained in:
299
docs/_overview/04b-feedback/P1-6-trigger-api-merge.md
Normal file
299
docs/_overview/04b-feedback/P1-6-trigger-api-merge.md
Normal file
@@ -0,0 +1,299 @@
|
||||
# P1-6 触发器双 API 合并可行性
|
||||
|
||||
> 反馈背景:Neo 倾向合并双 API(`/admin/ai/triggers` vs `/trigger-jobs`),
|
||||
> "看下数据获取的泛用性,如果合适则合并"。
|
||||
> 本文档基于现状代码评估泛用性、字段差异、合并方案与回归风险。
|
||||
|
||||
调研日期:2026-05-04
|
||||
调研范围:`apps/backend/app/routers/{admin_triggers,trigger_jobs,admin_ai}.py` / `apps/backend/app/services/ai/admin_service.py` / `apps/admin-web/src/api/{adminAI,triggerJobs,triggers}.ts` / `apps/admin-web/src/pages/{AITriggers,TriggerJobs,TriggerManager}.tsx` / 测试库 `biz.{trigger_jobs,ai_trigger_jobs}` 实际数据
|
||||
|
||||
---
|
||||
|
||||
## 一、双 API 字段对比(实际是 3 个 API)
|
||||
|
||||
调研中发现**当前实际有 3 个相关 API**,不是 2 个,先把全图列清楚:
|
||||
|
||||
| API 路径 | 文件 | 数据源 | 用途 |
|
||||
|---|---|---|---|
|
||||
| `GET /api/trigger-jobs` | `routers/trigger_jobs.py` | `biz.trigger_jobs` | 通用:所有定时任务(业务+AI 混合) |
|
||||
| `PATCH /api/trigger-jobs/:id/config` | 同上 | `biz.trigger_jobs` | 通用:改 cron / interval |
|
||||
| `POST /api/trigger-jobs/:id/run` | 同上 | `biz.trigger_jobs` | 通用:手动执行 |
|
||||
| `GET /api/admin/ai/triggers` | `routers/admin_ai.py:400` | `biz.trigger_jobs` (filter `job_type LIKE 'ai_%' OR job_name='task_generator'`) | AI 视角:仅 AI 相关触发器 |
|
||||
| `PATCH /api/admin/ai/triggers/:id` | 同上 | `biz.trigger_jobs` | AI 视角:改 cron / status / description |
|
||||
| `GET /api/admin/triggers/unified` | `routers/admin_triggers.py` | 聚合 `biz.trigger_jobs` + `biz.ai_trigger_jobs` + `public.scheduled_tasks` | 只读:跨数据源全景视图 |
|
||||
|
||||
**核心事实**:
|
||||
- `/admin/ai/triggers` 与 `/trigger-jobs` 操作的是**同一张表 `biz.trigger_jobs`**,前者只是加了 `WHERE job_type LIKE 'ai_%'` 过滤
|
||||
- `/admin/triggers/unified` 是只读聚合视图,跨 3 张表,与上述两个 API 不同源
|
||||
- `biz.ai_trigger_jobs` 是 AI 调用链历史记录表(事件实例),**不是触发器配置表**;当前测试库 0 条记录
|
||||
|
||||
### 1.1 GET 响应字段对比
|
||||
|
||||
| 字段 | `/trigger-jobs` (TriggerJobItem) | `/admin/ai/triggers` (TriggerItem) |
|
||||
|---|---|---|
|
||||
| id | int | int |
|
||||
| job_name | string | string |
|
||||
| job_type | **string** | **string** |
|
||||
| trigger_condition | string | string |
|
||||
| trigger_config | dict\|null | dict(不可为 null) |
|
||||
| last_run_at | string\|null | string\|null |
|
||||
| next_run_at | string\|null | string\|null |
|
||||
| status | string | string |
|
||||
| description | string\|null | string\|null |
|
||||
| last_error | string\|null | string\|null |
|
||||
| **created_at** | **string\|null** ✅ | **未返回** ❌ |
|
||||
|
||||
**差异 = 1 个字段**:`/admin/ai/triggers` 不返回 `created_at`。两个返回值**95% 重合**。
|
||||
|
||||
### 1.2 PATCH 入参字段对比
|
||||
|
||||
| 字段 | `/trigger-jobs/:id/config` (UpdateTriggerConfigRequest) | `/admin/ai/triggers/:id` (TriggerUpdateRequest) |
|
||||
|---|---|---|
|
||||
| cron_expression | ✅ | ✅ |
|
||||
| interval_seconds | ✅ | ❌ |
|
||||
| status | ❌ | ✅ |
|
||||
| description | ❌ | ✅ |
|
||||
| 校验规则 | "至少一个字段" + cron 正则 + interval ≥ 1 | 无 model_validator,cron 正则用 `jsonb_set` 写入 |
|
||||
|
||||
**差异显著**:
|
||||
- `/admin/ai/triggers` 支持改 status(启停)和 description,**`/trigger-jobs` 不支持**
|
||||
- `/trigger-jobs` 支持改 interval,**`/admin/ai/triggers` 不支持**
|
||||
- 这是**互补的字段集**,不是冗余
|
||||
|
||||
### 1.3 排序与过滤差异
|
||||
|
||||
| 维度 | `/trigger-jobs` | `/admin/ai/triggers` |
|
||||
|---|---|---|
|
||||
| WHERE | 无 | `job_type LIKE 'ai_%' OR job_name = 'task_generator'` |
|
||||
| ORDER BY | `id` | `trigger_condition DESC, job_name` |
|
||||
|
||||
### 1.4 测试库实际数据(biz.trigger_jobs 9 行)
|
||||
|
||||
```
|
||||
id job_name job_type condition status
|
||||
1 task_generator task_generator cron enabled ← AI 列表也包含(job_name 命中)
|
||||
2 task_expiry_check task_expiry_check interval enabled
|
||||
3 recall_completion_check recall_completion_check event enabled
|
||||
4 note_reclassify_backfill note_reclassify_backfill event enabled
|
||||
57 ai_consumption_settled ai_consumption_settled event enabled ← AI
|
||||
58 ai_note_created ai_note_created event enabled ← AI
|
||||
59 ai_task_assigned ai_task_assigned event enabled ← AI
|
||||
60 ai_dws_completed ai_dws_completed event enabled ← AI
|
||||
61 ai_dws_prewarm_1000 ai_dws_prewarm cron enabled ← AI
|
||||
```
|
||||
|
||||
`/admin/ai/triggers` 命中 6 行(5 个 ai_ 前缀 + 1 个 task_generator);
|
||||
`/trigger-jobs` 命中全部 9 行;
|
||||
`/admin/triggers/unified` 命中 9 行(biz)+ 0 行(ai_trigger_jobs,0 条记录)+ N 行 etl。
|
||||
|
||||
---
|
||||
|
||||
## 二、前端依赖分析
|
||||
|
||||
### 2.1 三个页面的数据消费
|
||||
|
||||
| 页面 | 数据源 | 消费的字段 |
|
||||
|---|---|---|
|
||||
| `pages/AITriggers.tsx` (独立) | `listTriggers()` → `/admin/ai/triggers` | id / job_name / trigger_condition / trigger_config.cron_expression / trigger_config.event_name / status / description / last_run_at / next_run_at / last_error |
|
||||
| `pages/TriggerJobs.tsx` (独立) | `fetchTriggerJobs()` → `/trigger-jobs` | id / job_name / trigger_condition / trigger_config.\*(cron+interval+event_name)/ status / description / last_run_at / next_run_at / last_error |
|
||||
| `pages/TriggerManager.tsx` (容器) | 4 个 Tab:<br>- `all` Tab → `fetchUnifiedTriggers()` → `/admin/triggers/unified`<br>- `biz` Tab → `fetchTriggerJobs()` → `/trigger-jobs`(**BizTriggersTab 内嵌**)<br>- `ai` Tab → 嵌入 `<AITriggers />` + `<AIOperations />` + `<AITriggerJobs />` 三个组件<br>- `etl` Tab → `fetchSchedules()` → ETL API | 按 Tab 分别展示 |
|
||||
|
||||
### 2.2 字段消费交集
|
||||
|
||||
`AITriggers.tsx` 与 `TriggerJobs.tsx` / `BizTriggersTab` 消费的字段**完全相同**(除 `created_at` 在 AITriggers 未消费)。
|
||||
|
||||
### 2.3 操作能力消费
|
||||
|
||||
| 操作 | AITriggers (in TriggerManager AI Tab) | BizTriggersTab (in TriggerManager biz Tab) | TriggerJobs (独立页面) |
|
||||
|---|---|---|---|
|
||||
| 启停(status 切换) | ✅ Switch 组件 | ❌ | ❌ |
|
||||
| 改 cron | ✅ Modal | ✅ Modal | ❌(只有列表 + run) |
|
||||
| 改 interval | ❌ | ✅ Modal | ❌ |
|
||||
| 改 description | ✅ Modal | ❌ | ❌ |
|
||||
| 手动执行 | ❌ | ❌ | ✅ Button |
|
||||
| 清空所有任务 | ❌ | ❌ | ✅(业务专用) |
|
||||
|
||||
**核心事实**:三个页面消费字段几乎一致,但**操作能力是互补的**。`/admin/ai/triggers` PATCH 比 `/trigger-jobs/:id/config` PATCH 多了 status / description,少了 interval;前端 UI 也按各自支持的字段开放对应控件。
|
||||
|
||||
### 2.4 路由注册情况(admin-web 主导航)
|
||||
|
||||
`apps/admin-web` 当前 4 处入口:
|
||||
- 独立页面 `TriggerJobs.tsx`(路径见路由表)
|
||||
- 独立页面 `AITriggers.tsx`
|
||||
- 聚合容器 `TriggerManager.tsx` Tab "biz" 嵌套 `BizTriggersTab`(与 `TriggerJobs.tsx` 几乎重复)
|
||||
- 聚合容器 `TriggerManager.tsx` Tab "ai" 嵌套 `<AITriggers />`
|
||||
|
||||
**已经有冗余**:`BizTriggersTab` 的 columns 与 `TriggerJobs.tsx` 重复定义。这是当前需要先收敛的 UI 层债务。
|
||||
|
||||
---
|
||||
|
||||
## 三、数据获取泛用性评估
|
||||
|
||||
### 3.1 三个 API 的"可替代性"矩阵
|
||||
|
||||
| 场景 | 可用 API | 评估 |
|
||||
|---|---|---|
|
||||
| 列出全部触发器(业务+AI) | `/trigger-jobs` ✅ / `/admin/triggers/unified`(聚合,包含 etl) | 单源场景下 `/trigger-jobs` 已够用 |
|
||||
| 仅看 AI 触发器 | `/admin/ai/triggers` ✅ / `/trigger-jobs` + 前端过滤 | 后端过滤省一次网络传输;前端过滤更灵活 |
|
||||
| 跨表全景(biz + ai_jobs + etl) | 仅 `/admin/triggers/unified` | 只读,无替代 |
|
||||
| 改 status / description | 仅 `/admin/ai/triggers` PATCH | 缺口(`/trigger-jobs` 不支持) |
|
||||
| 改 interval | 仅 `/trigger-jobs/:id/config` PATCH | 缺口(`/admin/ai/triggers` 不支持) |
|
||||
| 手动 run | 仅 `/trigger-jobs/:id/run` POST | 缺口 |
|
||||
|
||||
**结论**:GET 端可合并(`/trigger-jobs?job_type_prefix=ai_` 即可替代 `/admin/ai/triggers`);PATCH 端**必须先合并字段集**才能合并 API;POST run 端 `/admin/ai/triggers` 本就没有,不冲突。
|
||||
|
||||
### 3.2 泛用性瓶颈
|
||||
|
||||
`/trigger-jobs` 的 PATCH 当前**故意不暴露 status / description**,原因推测:
|
||||
|
||||
1. 业务触发器的启停可能影响 ETL 调度,需要更严格的权限控制(admin_ai 路由有 `_require_admin()` 守卫)
|
||||
2. description 是给后台管理员看的"说明",业务侧可能不希望随便改
|
||||
|
||||
如果直接合并,需要先决策:**`/trigger-jobs` PATCH 是否允许改 status / description**?
|
||||
|
||||
---
|
||||
|
||||
## 四、合并方案对比
|
||||
|
||||
### 方案 A · 完全合并(删除 `/admin/ai/triggers`)
|
||||
|
||||
#### 步骤
|
||||
1. 扩展 `apps/backend/app/schemas/trigger_jobs.py::UpdateTriggerConfigRequest` 加 `status` / `description` 字段
|
||||
2. `apps/backend/app/routers/trigger_jobs.py::update_trigger_config` 加白名单:仅当 `status_new in (enabled, disabled)` 时通过;description 直接 UPDATE
|
||||
3. `GET /api/trigger-jobs` 加 query 参数 `?job_type_prefix=ai_`,等价于 `/admin/ai/triggers` 的过滤
|
||||
4. `apps/admin-web/src/api/adminAI.ts` 删除 `listTriggers` / `updateTrigger` 函数
|
||||
5. `apps/admin-web/src/pages/AITriggers.tsx` 改用 `triggerJobs.ts` 的 `fetchTriggerJobs({ jobTypePrefix: "ai_" })` + 新 PATCH 函数
|
||||
6. 删除后端 `/admin/ai/triggers` 路由
|
||||
7. 同步收敛 `BizTriggersTab` 与 `TriggerJobs.tsx` 的 column 重复定义
|
||||
|
||||
#### 评估
|
||||
| 维度 | 值 |
|
||||
|---|---|
|
||||
| 工作量 | 中(schemas/路由/前端 API 层/2 个组件改造) |
|
||||
| 回归范围 | AITriggers 页面端到端 + TriggerManager AI/biz Tab + TriggerJobs 独立页 + `__tests__/adminAiAppTypes.test.ts` 类的对齐测试 |
|
||||
| 长期维护成本 | 低(单源真相) |
|
||||
| 风险点 | 1)改 status / description 的权限放开后,业务触发器(id 1-4)可能被误改;建议加守卫"业务触发器 status 改动需二次确认"。2)admin-web 之外的调用方(如 mcp-server)需排查 |
|
||||
|
||||
### 方案 B · 字段子集合并(保留两 API,底层 service 合并)
|
||||
|
||||
#### 步骤
|
||||
1. 新建 `apps/backend/app/services/trigger_service.py`,集中 `list_triggers(filter)` / `update_trigger(id, fields)` 两个内核函数
|
||||
2. `routers/admin_ai.py::list_triggers` 与 `routers/trigger_jobs.py::get_trigger_jobs` 都调用 `trigger_service.list_triggers()`,参数不同
|
||||
3. 两个 PATCH 端点都调用 `trigger_service.update_trigger(...)`,前者传 status/description 子集,后者传 cron/interval 子集
|
||||
4. 前端代码不动
|
||||
|
||||
#### 评估
|
||||
| 维度 | 值 |
|
||||
|---|---|
|
||||
| 工作量 | 中(后端重构,前端零改动) |
|
||||
| 回归范围 | 后端 service 层单测 + 路由集成测试 |
|
||||
| 长期维护成本 | 中(API 两份仍在,但底层一致) |
|
||||
| 风险点 | 没有真正解决 Neo 反馈的"双 API"困惑,前端开发仍要在两个 API 客户端之间选 |
|
||||
|
||||
### 方案 C · 不合并,只补文档边界
|
||||
|
||||
#### 步骤
|
||||
1. 在 `apps/backend/app/routers/admin_ai.py` 与 `trigger_jobs.py` 顶部 docstring 互引:"本路由 PATCH 仅改 status/description(业务/AI 都可),改 cron/interval 请用 /trigger-jobs"
|
||||
2. 同步 `apps/backend/CLAUDE.md` 增加一节"触发器 API 边界"
|
||||
|
||||
#### 评估
|
||||
| 维度 | 值 |
|
||||
|---|---|
|
||||
| 工作量 | 极低(< 50 行注释) |
|
||||
| 长期维护成本 | 高(每次新人都要重新理解两 API 边界) |
|
||||
|
||||
---
|
||||
|
||||
## 五、推荐实施步骤
|
||||
|
||||
**推荐方案 A(完全合并)**,分 4 阶段:
|
||||
|
||||
### 阶段 1 · 后端 API 扩展(D+0)
|
||||
|
||||
1. `apps/backend/app/schemas/trigger_jobs.py::UpdateTriggerConfigRequest` 新增字段:
|
||||
```python
|
||||
status: Literal["enabled", "disabled"] | None = None
|
||||
description: str | None = None
|
||||
```
|
||||
model_validator 改为"四选一即可"
|
||||
2. `apps/backend/app/routers/trigger_jobs.py::update_trigger_config`:
|
||||
- 增加 status / description UPDATE 分支
|
||||
- 新增 query 参数 `?job_type_prefix=str` for GET
|
||||
- 新增 query 参数 `?include_event=bool`(默认 true)便于按需排除
|
||||
3. 在 admin_ai.py 的 `/admin/ai/triggers` GET/PATCH 下加 deprecation header(`Deprecation: true`)
|
||||
|
||||
### 阶段 2 · 前端切换调用(D+1)
|
||||
|
||||
1. `apps/admin-web/src/api/triggerJobs.ts::UpdateTriggerConfigReq` 加 status/description
|
||||
2. `apps/admin-web/src/api/triggerJobs.ts::fetchTriggerJobs` 加可选 `params: { job_type_prefix?: string }`
|
||||
3. `apps/admin-web/src/pages/AITriggers.tsx`:
|
||||
- import 改为 `triggerJobs.ts`
|
||||
- `listTriggers()` → `fetchTriggerJobs({ job_type_prefix: 'ai_' })`
|
||||
- `updateTrigger(id, body)` → `updateTriggerConfig(id, body)`
|
||||
4. 收敛 `pages/TriggerManager.tsx::BizTriggersTab` columns 重复定义:直接 `import TriggerJobs` 或抽公共组件 `<TriggerJobsTable filter={...} />`
|
||||
|
||||
### 阶段 3 · 删除旧 API(D+2,灰度后)
|
||||
|
||||
1. 删除 `apps/backend/app/routers/admin_ai.py` 中 `/triggers` 两个端点
|
||||
2. 删除 `apps/backend/app/services/ai/admin_service.py::list_triggers` / `update_trigger`
|
||||
3. 删除 `apps/admin-web/src/api/adminAI.ts` 中 `listTriggers` / `updateTrigger` / `TriggerItem` / `TriggerUpdateRequest`
|
||||
4. 跑全量回归(pytest backend + admin-web 端到端)
|
||||
|
||||
### 阶段 4 · 文档同步(D+2)
|
||||
|
||||
1. `apps/backend/CLAUDE.md` 触发器章节加"统一 API: /api/trigger-jobs"
|
||||
2. 写审计 `docs/audit/changes/<日期>__trigger-api-merge.md`
|
||||
3. 顺手补:`/admin/triggers/unified` 仍保留(跨表只读视图),但在 docstring 标明"如果只看 biz 表用 /trigger-jobs,跨 etl/ai_jobs 时再用 unified"
|
||||
|
||||
---
|
||||
|
||||
## 六、给 Neo 的决策清单
|
||||
|
||||
| 问 | 选项 | 推荐 |
|
||||
|---|---|---|
|
||||
| Q1 | 采纳方案 A(完全合并),还是方案 B(保留双 API 仅合并底层)? | **方案 A** |
|
||||
| Q2 | 合并后 `/trigger-jobs` PATCH 允许改 `status`,业务触发器(id 1-4,task_generator/task_expiry_check 等)是否需要"业务触发器禁止禁用"守卫? | 推荐加一个白名单:`PROTECTED_JOB_NAMES = {"task_generator"}`,禁用时 422 |
|
||||
| Q3 | `/admin/triggers/unified` 是否保留?(它聚合了 ai_trigger_jobs + scheduled_tasks,与单表 API 不同源) | 保留(跨数据源场景仍需要) |
|
||||
| Q4 | 合并后是否把独立页面 `pages/AITriggers.tsx` 也删掉,仅保留 `TriggerManager.tsx` 的 Tab 视图? | 推荐删(已被 TriggerManager 覆盖) |
|
||||
| Q5 | `pages/TriggerJobs.tsx` 独立页面是否也合并到 `TriggerManager.tsx`?路由表清理? | 推荐合并;路由表保留旧路径 redirect → TriggerManager?tab=biz |
|
||||
| Q6 | 灰度策略:直接 D+0 删除旧 API,还是 D+0 加 deprecation header → D+7 删除? | 推荐 D+0 加 header,D+2 删除(admin-web 是单仓库唯一调用方,可短窗口) |
|
||||
|
||||
---
|
||||
|
||||
## 附录:关键文件清单
|
||||
|
||||
### 后端路由
|
||||
- `apps/backend/app/routers/trigger_jobs.py` — 通用 trigger_jobs API(保留并扩展)
|
||||
- `apps/backend/app/routers/admin_ai.py:400-440` — `/admin/ai/triggers` GET/PATCH(待删除)
|
||||
- `apps/backend/app/routers/admin_triggers.py` — `/admin/triggers/unified` 跨数据源聚合(保留)
|
||||
|
||||
### 后端 service
|
||||
- `apps/backend/app/services/ai/admin_service.py:752-820` — `list_triggers` / `update_trigger`(待删除,逻辑迁移到 trigger_jobs 路由)
|
||||
- `apps/backend/app/services/trigger_scheduler.py:346` — `list_trigger_jobs`(保留,是基础设施)
|
||||
|
||||
### 后端 schema
|
||||
- `apps/backend/app/schemas/trigger_jobs.py` — `TriggerJobItem` / `UpdateTriggerConfigRequest`(扩展 status/description)
|
||||
- `apps/backend/app/schemas/admin_ai.py:250-269` — `TriggerItem` / `TriggerUpdateRequest`(待删除)
|
||||
- `apps/backend/app/schemas/admin_triggers.py:14` — `UnifiedTriggerItem`(保留)
|
||||
|
||||
### 前端 API
|
||||
- `apps/admin-web/src/api/triggerJobs.ts` — 主 API 客户端(扩展)
|
||||
- `apps/admin-web/src/api/adminAI.ts:337-366` — `listTriggers` / `updateTrigger` / `TriggerItem`(待删除)
|
||||
- `apps/admin-web/src/api/triggers.ts` — `fetchUnifiedTriggers`(保留)
|
||||
|
||||
### 前端页面
|
||||
- `apps/admin-web/src/pages/TriggerManager.tsx` — 容器页(保留)
|
||||
- `apps/admin-web/src/pages/AITriggers.tsx` — 改用 triggerJobs API 后保留组件,删 listTriggers 调用
|
||||
- `apps/admin-web/src/pages/TriggerJobs.tsx` — 独立页面(建议删除并 redirect)
|
||||
- `apps/admin-web/src/pages/AITriggerJobs.tsx` — 注意:这是 ai_trigger_jobs 历史日志页面,与本调研 API 无关(用 `/admin/ai/trigger-jobs` 是另一组端点)
|
||||
|
||||
### 数据库
|
||||
- `db/zqyy_app/schemas/biz.sql:344-360` — `biz.trigger_jobs` 表定义
|
||||
- `db/zqyy_app/schemas/biz.sql:48-150` — `biz.ai_trigger_jobs` 表定义(事件历史,与触发器配置不同)
|
||||
|
||||
### 测试
|
||||
- `apps/admin-web/src/__tests__/adminAiAppTypes.test.ts` — 现有对齐测试(合并后扩展,加上 trigger PATCH 字段对齐用例)
|
||||
|
||||
### 审计参考
|
||||
- `docs/audit/changes/2026-03-23__trigger-jobs-admin-web-miniprogram-cleanup.md` — 上次 trigger_jobs 改动
|
||||
- `docs/audit/changes/2026-03-24__trigger-jobs-clear-task-interaction.md` — clear-all 交互改动
|
||||
Reference in New Issue
Block a user