# 审计记录：admin-web AI 管理套件（可视化全流程管控）

**日期**：2026-04-21
**会话**：为 admin-web 补齐 AI 可视化管理页面 + 后端对应端点
**影响范围**：backend（schemas/services/routers）/ admin-web（api/pages/App.tsx）

---

## 变更摘要

用户需求：
> 为我在 admin-web 修改完善 AI 相关工具和板块。让我能有可视化的工具进行 AI 方面的全流程可视化可操作的管理，包含调试阶段的集中预热以及触发器状态设置等。

本次交付 2 个新页面 + 1 个页面增强 + 1 个 AI 一级菜单组，并新增 4 个后端端点作为前端数据源。

---

## 后端变更

### 新增 Pydantic 模型（`apps/backend/app/schemas/admin_ai.py`）

| 模型 | 用途 |
|------|------|
| `TriggerItem` | 触发器单条记录（id/job_name/job_type/trigger_condition/trigger_config/status/last_run_at/next_run_at/last_error） |
| `TriggerUpdateRequest` | 触发器更新（status / cron_expression / description） |
| `PrewarmMissingItem` | 缺失组合（target_id / time_dimension / area） |
| `PrewarmProgressResponse` | 预热进度（total=72 / done / missing / last_updated） |
| `ManualTriggerRequest` | 手动触发事件请求（event_type / site_id / member_id / assistant_id / payload / is_forced） |
| `ManualTriggerResponse` | 手动触发响应（trigger_job_id / status） |

### 新增服务方法（`apps/backend/app/services/ai/admin_service.py`）

| 方法 | 实现 |
|------|------|
| `list_triggers()` | 查 `biz.trigger_jobs WHERE job_type LIKE 'ai_%' OR job_name='task_generator'` |
| `update_trigger(id, status, cron_expression, description)` | 支持部分字段更新，cron 用 `jsonb_set` 改 trigger_config |
| `get_prewarm_progress(site_id)` | 对比 72 组合 expected vs `biz.ai_cache` 中 `app2_finance` 的 target_id，返回 done/missing |

### 新增路由端点（`apps/backend/app/routers/admin_ai.py`）

| 方法 | 路径 | 说明 |
|------|------|------|
| GET | `/api/admin/ai/triggers` | 列出所有 AI 触发器 |
| PATCH | `/api/admin/ai/triggers/{trigger_id}` | 启停 / 改 cron / 改描述 |
| GET | `/api/admin/ai/prewarm/progress?site_id=N` | App2 预热 72 组合进度 |
| POST | `/api/admin/ai/trigger-event` | 手动触发事件链，默认 `is_forced=True` 跨越去重 |

所有端点走 `_require_admin()` 要求 `site_admin`/`tenant_admin` 角色。

---

## 前端变更

### API 层（`apps/admin-web/src/api/adminAI.ts`）

新增 4 个函数 + 6 个类型接口：
- `listTriggers()` / `updateTrigger(id, body)` + `TriggerItem` / `TriggerUpdateRequest`
- `getPrewarmProgress(siteId)` + `PrewarmProgressResponse` / `PrewarmMissingItem`
- `triggerEvent(body)` + `ManualTriggerRequest` / `ManualTriggerResponse`

### 新建页面

**`apps/admin-web/src/pages/AITriggers.tsx`** — 触发器设置页（`/ai/triggers`）
- 表格列出所有 AI 触发器（id / 名称+描述 / 类型 tag / 表达式或事件名 / 启停 Switch / 最近/下次运行 / 最后错误）
- 编辑 Modal：cron 类型支持改 cron 表达式，所有类型可改描述
- 行内快速启停：Switch 直接切换 enabled/disabled

**`apps/admin-web/src/pages/AIPrewarm.tsx`** — 预热进度页（`/ai/prewarm`）
- 顶部卡片：72 组合进度条 + done/missing 计数 + last_updated
- 2 个主动作：
  - "触发全量预热"：调 `triggerEvent(dws_completed, is_forced=true)`，后台异步跑
  - "一键补齐缺失"：串行 `runApp(app2_finance, time_dimension, area)` 逐个补，前端进度 Alert
- 缺失组合表格：每行一个"单独生成"按钮，快速补单个组合（30-120s）
- 时间/区域标签中英双显（`本月 (this_month)`）

### 页面增强

**`apps/admin-web/src/pages/AIOperations.tsx`** — 新增 Card 2.6「手动触发事件链（调试用）」
- 事件类型下拉（consumption / note_created / task_assigned / dws_completed）
- 输入 member_id / assistant_id 按需
- 默认勾选「跳过去重」复选框（is_forced=true）
- 触发后返回 `trigger_job_id` 供后续查调度历史

### 路由与菜单（`apps/admin-web/src/App.tsx`）

- 新增一级菜单「AI 管理」（图标 RobotOutlined），含 5 个子项：
  - 总览 → `/ai/dashboard`（原 AIDashboard，此前未挂载路由，本次接入）
  - 手动操作 → `/ai/operations`（原 AIOperations，同上）
  - 预热进度 → `/ai/prewarm`（新）
  - 触发器设置 → `/ai/triggers`（新）
  - 调度历史 → `/ai/trigger-jobs`（原 AITriggerJobs，同上）
- `getSelectedKeys` / `getDefaultOpenKeys` 补 `/ai/` 前缀匹配

---

## 验证状态

- **代码语法**：TypeScript / Python 均通过编辑器层面校验（无 linter 报错）
- **烟雾测试**：后端 `--reload` 触发自身 lifespan 阻塞（已知环境问题：远程 PG 560ms RTT × psycopg2 每请求新建连接），未能在本会话 curl 成功。端点逻辑已完整覆盖已有 admin_ai 路由的模式，复用 `_require_admin()` / `_admin_svc` / `get_dispatcher()` 等成熟组件
- **手动验证路径**：
  1. 重启后端至稳定
  2. 登录 admin-web，左侧菜单展开「AI 管理」应看到 5 项
  3. 「总览 / 手动操作 / 调度历史」是重新挂载路由的现有页面，直接可用
  4. 「触发器设置」读取 `biz.trigger_jobs` 的 5 条 AI 触发器（`ai_consumption_settled` / `ai_note_created` / `ai_task_assigned` / `ai_dws_completed` / `ai_dws_prewarm_1000`）
  5. 「预热进度」应显示 46/72（当前进度），可一键补齐剩余 26 个

---

## 遗留风险点

1. **admin JWT 与 auth.users 混用**：`_require_admin → require_permission() → _get_user_status(user_id)` 查 `auth.users`，但 admin 用户实际在 `admin_users` 表。生产 admin-web 登录后 JWT 的 sub 必须指向 `auth.users.id` 才能通过。本次不修此老问题，沿用现有 admin_ai 所有端点的约定
2. **后端远程 PG 网络延迟**（本会话观测 ping 560ms）导致每请求 psycopg2.connect ≈ 3s，叠加 AI 预热任务会拖垮整体响应。根治需加连接池或切本地 PG，与本次改动无关
3. **cron 修改立即生效依赖 scheduler 重新解析**：改完 cron_expression 后，`biz.trigger_jobs.next_run_at` 需在 scheduler 下一次 poll 时重算（默认 60s）；用户感知到的生效延迟最多 1 分钟

---

## 回滚

- 后端：`git restore apps/backend/app/routers/admin_ai.py apps/backend/app/schemas/admin_ai.py apps/backend/app/services/ai/admin_service.py`
- 前端：`git restore apps/admin-web/src/api/adminAI.ts apps/admin-web/src/App.tsx apps/admin-web/src/pages/AIOperations.tsx && rm apps/admin-web/src/pages/AITriggers.tsx apps/admin-web/src/pages/AIPrewarm.tsx`
