Files
Neo-ZQYY/docs/_overview/02b-adminweb-page-matrix.md
Neo 509cf43284 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 残留, 已修 commit 17f045a)
- P0-5 致命 2 (JWT aud 缺失, 已修 commit 17f045a)
- P0-6 clearAllTasks 守卫 (Wave 3)
- P0-8 DBViewer 黑名单漏 (已修 commit 17f045a)
- 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
2026-05-04 07:38:28 +08:00

326 lines
29 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# admin-web 19 路由业务指纹矩阵
> 生成日期2026-05-04 视角:系统运维(开发 + 运维操作 ETL 库 + AI 监控) 用户Neo + 运维成员
> 来源:`apps/admin-web/src/App.tsx`、`apps/admin-web/src/pages/*.tsx`、`apps/admin-web/src/api/*.ts`
> 后端 baseURL`/api`(见 `apps/admin-web/src/api/client.ts`),路由挂载见 `apps/backend/app/main.py` L203-L246
---
## 一、菜单结构7 一级 + 子菜单)
```
Sider侧边栏
├─ /dashboard 运行状态(首页)
├─ /etl-tasks ETL 任务管理5 子 Tabconfig/queue/schedule/history/status
├─ task-engine-group 小程序任务管理 ▼
│ ├─ /task-engine/trigger-jobs 定时任务
│ ├─ /task-engine/transfer-log 转移日志
│ ├─ /task-engine/pending-review 待审核任务
│ └─ /task-engine/config 参数管理
├─ /triggers 触发器管理4 子 Taball/biz/ai/etl
├─ ai-group AI 管理 ▼
│ ├─ /ai/dashboard 总览
│ ├─ /ai/operations 手动操作
│ ├─ /ai/prewarm 预热进度
│ ├─ /triggers?tab=ai 触发器设置(跳到 TriggerManager AI Tab
│ └─ /ai/trigger-jobs 调度历史
├─ /tenant-admins 租户管理员
├─ settings-group 系统设置 ▼
│ ├─ /settings/env-config 环境配置
│ ├─ /settings/runtime-context 业务运行上下文 / 沙箱
│ └─ /triggers?tab=biz 触发器配置(跳到 TriggerManager 业务 Tab
└─ logs-group 日志调试 ▼
├─ /logs/dev-trace DevTrace全链路日志
├─ /logs/ai-run-logs AI 调用明细
└─ /logs/db-viewer 数据库查看器
```
设计意图:
- 一级菜单按业务域聚合(运行状态 / ETL / 小程序任务引擎 / 触发器 / AI / 租户 / 设置 / 日志)。
- `?tab=` 参数使 AI 与系统设置共用 `/triggers` 一个页面,不同入口落到不同 Tab。
- 历史上是 11 个一级项CHANGE 2026-07-14 Task 7.1 重组为 7 个),合并的页面(`TaskConfig``TaskManager``ETLStatus``AITriggers`)以子组件形式被新页面 import未直接挂载路由。
---
## 二、菜单 → 路由 → 页面 → 后端 API 映射
| 一级菜单 | 子菜单 | 路由 | 页面文件 | 主要后端 API前缀 `/api` | 设计目的 |
|---|---|---|---|---|---|
| —(登录) | — | `/login` | `Login.tsx` | `POST /auth/login`authStore | JWT 登录,成功跳 `/dashboard` |
| 运行状态 | — | `/dashboard` | `Dashboard.tsx` | `GET /ops/system``GET /ops/services``GET /ops/git``GET /admin/db-health``GET /admin/ai/trigger-jobs` | 登录后默认首页:服务器资源 + 服务/Git 状态 + DB 健康 + AI 总览 + AI 调度摘要 |
| ETL 任务管理 | — | `/etl-tasks` | `ETLTasks.tsx`(包 5 Tab | (见各 Tab | 合并 ETL 五大场景为 Tab发起 / 队列 / 调度 / 历史 / 状态 |
| ↳ config | — | `/etl-tasks?tab=config` | `TaskConfig.tsx`(被 ETLTasks 引用) | `GET /tasks``POST /tasks/validate``POST /execution/queue``POST /execution/run``POST /schedules``GET /tasks/flows` | Flow 选择 + 处理模式 + 时间窗口 + 提交 / 直跑 / 创建调度 |
| ↳ queue | — | `/etl-tasks?tab=queue` | `TaskManager.tsx::QueueTab` | `GET /execution/queue``DELETE /execution/queue/:id``POST /execution/:id/cancel`、WS `/ws/logs/:id` | 当前队列 + WebSocket 实时日志 |
| ↳ schedule | — | `/etl-tasks?tab=schedule` | `components/ScheduleTab.tsx` | `GET/POST/PUT/DELETE /schedules``PATCH /schedules/:id/toggle``POST /schedules/:id/run` | 调度任务 CRUD + 启停 + 立即执行 |
| ↳ history | — | `/etl-tasks?tab=history` | `TaskManager.tsx::HistoryTab` | `GET /execution/history``POST /execution/:id/rerun``POST /execution/cleanup-output` | 执行历史 + 重跑 + 清理输出 |
| ↳ status | — | `/etl-tasks?tab=status` | `ETLStatus.tsx`(被 ETLTasks 引用) | `GET /etl-status/cursors``GET /etl-status/recent-runs` | 任务游标 + 最近执行success/failed/running 统计) |
| 小程序任务管理 | 定时任务 | `/task-engine/trigger-jobs` | `TriggerJobs.tsx` | `GET /trigger-jobs``POST /trigger-jobs/:id/run``DELETE /admin/task-engine/clear-all-tasks` | `biz.trigger_jobs` 列表 + 手动执行 + 清空助教任务(高危) |
| ↳ | 转移日志 | `/task-engine/transfer-log` | `TransferLog.tsx` | `GET /admin/task-engine/transfer-log` | P18 客户转移日志(门店/时间/助教筛选 + guard_checks 标签) |
| ↳ | 待审核任务 | `/task-engine/pending-review` | `PendingReview.tsx` | `GET /admin/task-engine/pending-review``POST .../:id/reassign``POST .../:id/close``GET .../transfer-log/:memberId/history` | 待审核任务列表 + 重新分配 + 关闭 + 客户历史抽屉 |
| ↳ | 参数管理 | `/task-engine/config` | `TaskEngineConfig.tsx` | `GET /admin/task-engine/config``PUT /admin/task-engine/config/:id``POST /admin/task-engine/config``DELETE /admin/task-engine/config/:id` | `biz.cfg_task_generator_params` 全局/门店覆盖参数 + 权重卡片编辑 |
| 触发器管理 | — | `/triggers` | `TriggerManager.tsx`(包 4 Tab | (见各 Tab | 聚合 biz / ai / etl 三类触发器为统一管理入口 |
| ↳ all | — | `/triggers?tab=all` | `TriggerManager.tsx::AllTriggersTab` | `GET /admin/triggers/unified` | 跨源只读统一视图 |
| ↳ biz | — | `/triggers?tab=biz` | `TriggerManager.tsx::BizTriggersTab` | `GET /trigger-jobs``PATCH /trigger-jobs/:id/config` | 业务触发器列表 + 编辑 cron / 间隔秒数 |
| ↳ ai | — | `/triggers?tab=ai` | `TriggerManager.tsx::AITriggersTab`(包 `AITriggers` + `AIOperations` + `AITriggerJobs` | `GET /admin/ai/triggers``PATCH /admin/ai/triggers/:id``POST /admin/ai/trigger-event``POST /admin/ai/trigger-jobs/:id/retry``POST /admin/ai/cache/invalidate``POST /admin/ai/run/:appType``POST /admin/ai/batch-run``POST /admin/ai/batch-run/confirm``GET/POST /admin/ai/alerts/:id/(ack\|ignore)` | AI 触发器启停 + 编辑 cron + AI 手动操作 + 调度历史 |
| ↳ etl | — | `/triggers?tab=etl` | `TriggerManager.tsx::ETLTriggersTab` | `GET /schedules` | `meta.scheduled_tasks` 调度任务只读列表 |
| AI 管理 | 总览 | `/ai/dashboard` | `AIDashboard.tsx` | `GET /admin/ai/dashboard` | 4 卡 + 7 天趋势 + App 占比 + 预算进度 + App 健康 + 最近告警 |
| ↳ | 手动操作 | `/ai/operations` | `AIOperations.tsx` | `POST /admin/ai/trigger-jobs/:id/retry``POST /admin/ai/cache/invalidate``POST /admin/ai/batch-run(/confirm)``POST /admin/ai/run/:appType``POST /admin/ai/trigger-event``GET /admin/ai/alerts``POST /admin/ai/alerts/:id/(ack\|ignore)` | 重跑 / 缓存失效 / 按需重跑 / 批量执行 / 告警管理 / 越过去重 |
| ↳ | 预热进度 | `/ai/prewarm` | `AIPrewarm.tsx` | `GET /admin/ai/prewarm/progress``POST /admin/ai/run/:appType`app2_finance / app2a_finance_area`POST /admin/ai/trigger-event` | app2_finance 72 组合8 时间 × 9 区域)覆盖率 + 一键补缺 + 单组合重跑 |
| ↳ | 触发器设置 | `/triggers?tab=ai` | (跳转 TriggerManager | (同 ai Tab | 入口跳转,不渲染独立页面 |
| ↳ | 调度历史 | `/ai/trigger-jobs` | `AITriggerJobs.tsx` | `GET /admin/ai/trigger-jobs``GET /admin/ai/trigger-jobs/:id``POST /admin/ai/trigger-jobs/:id/retry` | 事件链调度记录 + 详情 + 重跑(含今日去重统计) |
| 租户管理员 | — | `/tenant-admins` | `TenantAdmins/index.tsx` | `GET/POST/PATCH/DELETE /admin/tenant-admins``POST /admin/tenant-admins/:id/reset-password``GET /admin/registry/tenants``GET .../sites``PATCH .../sites/:id/code``GET .../sites/:id/code-history``POST/DELETE .../sites` | 租户管理员 CRUD + 简写 ID 管理 + 门店建删 |
| 系统设置 | 环境配置 | `/settings/env-config` | `EnvConfig.tsx` | `GET /env-config``PUT /env-config``GET /env-config/export` | `.env` 键值对编辑 + 导出(敏感值脱敏) |
| ↳ | 业务运行上下文 / 沙箱 | `/settings/runtime-context` | `RuntimeContext.tsx` | `GET /admin/runtime-context/sites``PATCH /admin/runtime-context` | 多门店 live/sandbox 切换 + 历史日期固定 + 触发器自动暂停 |
| ↳ | 触发器配置 | `/triggers?tab=biz` | (跳转 TriggerManager | (同 biz Tab | 入口跳转 |
| 日志调试 | DevTrace | `/logs/dev-trace` | `DevTrace.tsx` | `GET /admin/dev-trace/(dates\|requests\|coverage\|settings)``GET /admin/dev-trace/request/:id``POST /admin/dev-trace/cleanup``POST /admin/dev-trace/coverage/scan``PUT /admin/dev-trace/settings` | 全链路 trace 请求列表 + span 树 + 覆盖率扫描 + 清理 |
| ↳ | AI 调用明细 | `/logs/ai-run-logs` | `AIRunLogs.tsx` | `GET /admin/ai/run-logs``GET /admin/ai/run-logs/:id` | AI 单次调用 prompt / response / error 详情 |
| ↳ | 数据库查看器 | `/logs/db-viewer` | `DBViewer.tsx` | `GET /db/schemas``GET /db/schemas/:s/tables``GET /db/tables/:s/:t/columns``POST /db/query` | Schema/Table 树 + 只读 SQL 执行 |
---
## 三、19 页指纹卡
> 实际可路由页面共 19 个:`Login` + 18 个登录后页面(其中 `/triggers?tab=biz`、`/triggers?tab=ai` 是 `/triggers` 的查询参数入口,菜单暴露但共用 1 个 `TriggerManager.tsx`)。
### 3.1 `/login`
- **设计目的**JWT 用户名+密码登录,仅渐变色卡片。
- **关键操作**:填写用户名 / 密码 → 「登录」按钮。
- **后端 API**`POST /api/auth/login`(通过 `useAuthStore.login`JWT aud=`admin`
- **数据来源**`auth.admin_users`admin/super_admin/site_admin 共表aud 区分)。
- **必现字段**:渐变色背景、`NeoZQYY` 标题、用户名输入、密码输入、登录按钮。
- **典型用例**:进入后台首屏。
- **测试校核重点**:错误返回应展示 `detail` 文案;成功后 `navigate("/dashboard")`
---
### 3.2 `/dashboard`(运行状态,首页)
- **设计目的**登录后默认首页聚合服务器、服务、Git、DB、AI 状态在一屏。
- **关键操作**:刷新(轮询 15s、跳转「ETL 状态详情」、「触发器详情」、「AI 调度详情」、启停服务、`git pull`、同步依赖。
- **后端 API**`GET /api/ops/system``/services``/git``POST /api/ops/services/:env/(start|stop|restart)``POST /api/ops/git/:env/(pull|sync-deps)``GET /api/admin/db-health``GET /api/admin/ai/trigger-jobs`;内嵌 `AIDashboard``GET /api/admin/ai/dashboard`
- **数据来源**:服务器实时(`psutil`+ Git CLI + 业务库 `biz.ai_run_logs` / `biz.trigger_jobs` + 测试库连接探活。
- **必现字段**CPU/内存/磁盘三组进度条、4 个环境prod/test/etl/dev状态、Git branch + last_commit、DB 健康行、AI 调用量/成功率/Token/延迟、AI 调度摘要(今日触发数/成功率/最近错误)。
- **典型用例**每天进入后台第一眼看的总览判断「服务是否在线」「ETL 是否卡住」「AI 是否预算耗尽」。
- **最近变更**CHANGE 2026-07-25Task 8.1OpsPanel 拆出 3 个 Section 组件被本页复用Task 8.x 增加 AI 调度摘要。
- **测试校核重点**`AIDashboard` 在本页是嵌入子组件,不应有独立顶部 TitleDB 健康超时 10s 回落 timeout 状态AI 调度摘要的「今日」基于 `created_at.startsWith(YYYY-MM-DD)`,跨时区注意。
---
### 3.3 `/etl-tasks`ETL 任务管理5 Tab
- **设计目的**:把 ETL 全生命周期(发起 → 队列 → 调度 → 历史 → 状态)合并为单页 5 TabURL 参数 `?tab=` 同步。
- **关键操作**:切换 Tab、Tab 内复用各原页面操作。
- **后端 API**:见 §二映射表(`/tasks/*``/execution/*``/schedules*``/etl-status/*`WS `/ws/logs/:id`)。
- **数据来源**ETL 库(`meta.scheduled_tasks``meta.execution_log`+ 任务调度后端内存队列。
- **必现字段**5 Tab 标题图标(发起 / 队列 / 调度 / 历史 / 状态),`destroyInactiveTabPane={false}` 切回不刷新。
- **典型用例**:运维新发起一次 ETLconfig→ 看队列 → 历史回看 → 状态确认游标推进。
- **最近变更**CHANGE 2026-07-14 Task 9.1 合并 4 页为 TabCHANGE 2026-03-25 拆出原 TaskManager 内部子 Tab。
- **测试校核重点**`?tab=xxx` 非法值回落 `config`;切 Tab 不丢失子 Tab 状态。
---
### 3.4 `/task-engine/trigger-jobs`(小程序定时任务)
- **设计目的**:管理 `biz.trigger_jobs` 中所有定时任务cron / interval / event支持手动执行。
- **关键操作**刷新、手动执行Popconfirm、清空所有助教任务高危 danger 按钮)。
- **后端 API**`GET /api/trigger-jobs``POST /api/trigger-jobs/:id/run``DELETE /api/admin/task-engine/clear-all-tasks`
- **数据来源**`biz.trigger_jobs` + `biz.coach_tasks`(清空目标)。
- **必现字段**:任务名称(描述+job_name、触发方式 Tag、触发配置 code、状态、上次/下次执行、最近错误、操作列。
- **典型用例**:测试重置任务表 + 强制运行某 cron。
- **测试校核重点**:清空所有任务的 `Popconfirm` 含 descriptiondanger 按钮置 loadingstatus≠enabled 的执行按钮 disabled。
---
### 3.5 `/task-engine/transfer-log`(客户转移日志)
- **设计目的**P18 助教任务引擎产生的 `biz.coach_task_transfer_log` 分页只读视图。
- **关键操作**:刷新、按门店/日期范围/助教 ID 筛选、翻页。
- **后端 API**`GET /api/admin/task-engine/transfer-log`(分页 + 筛选)。
- **数据来源**`biz.coach_task_transfer_log`(含 `guard_checks` JSON 三项检查)。
- **必现字段**:转移时间、门店、客户、原助教、新助教、转移原因(中文映射)、转移得分、保护检查 Tagsuccess/error 图标)。
- **典型用例**:审计某客户为何被转走、检查 guard 是否触发。
---
### 3.6 `/task-engine/pending-review`(待审核任务)
- **设计目的**:展示 `status='pending_review'` 的助教任务,超管可重分配 / 关闭。
- **关键操作**:刷新、按门店筛选、重新分配(输入新助教 ID、关闭输入原因、查看转移历史抽屉。
- **后端 API**`GET /api/admin/task-engine/pending-review``POST .../:id/reassign``POST .../:id/close``GET .../transfer-log/:memberId/history`
- **数据来源**`biz.coach_tasks`status=pending_review + `coach_task_transfer_log`
- **必现字段**:任务类型 Tag、转移次数、优先级得分、操作列仅 super_admin 可见)。
- **测试校核重点**`super_admin` 角色才显示重新分配/关闭按钮。
---
### 3.7 `/task-engine/config`(任务引擎参数管理)
- **设计目的**`biz.cfg_task_generator_params` 全局默认 + 门店覆盖参数;权重 `w_rs/w_ms/w_ml` 卡片整体编辑(联合校验)。
- **关键操作**:行内编辑、新增(弹窗)、删除、权重卡片提交。
- **后端 API**`GET /api/admin/task-engine/config``PUT .../:id``POST .../``DELETE .../:id`
- **数据来源**`biz.cfg_task_generator_params`
- **必现字段**参数中文标签13 个映射)、当前值、归属(全局 / 门店#xxx)、更新时间。
- **测试校核重点**3 个权重必须同步提交;非超管只读。
---
### 3.8 `/triggers`触发器统一管理4 Tab
- **设计目的**:聚合 biz / ai / etl 三类触发器为单页 4 Tab统一只读视图 + 编辑能力。
- **关键操作**:切 Tab、`all` 只读统一表、`biz` 编辑 cron/interval、`ai` 复用 AITriggers + AIOperations + AITriggerJobs、`etl` 只读 scheduled_tasks。
- **后端 API**`GET /api/admin/triggers/unified``GET /api/trigger-jobs``PATCH /api/trigger-jobs/:id/config``GET /api/schedules`AI Tab 详见 3.12)。
- **数据来源**`biz.trigger_jobs` + `meta.scheduled_tasks` + `biz.ai_run_logs`(健康)。
- **必现字段**4 Tab 图标(全部 / 业务 / AI / ETL「最近错误」单独一列。
- **最近变更**CHANGE 2026-07-15 Task 10.1 创建。
- **测试校核重点**`?tab=biz` / `?tab=ai` 直达正确 Tabbiz Tab 编辑校验 `cron_expression``interval_seconds` 至少一个ai Tab 内三个组件按 `Space direction="vertical" size="large"` 纵向排列。
- **功能交集**`AITriggers.tsx`(孤儿)功能已被 `BizTriggersTab` 编辑能力 + `AITriggersTab` 嵌入完整覆盖。
---
### 3.9 `/ai/dashboard`AI 总览)
- **设计目的**AI 8 个 App 的整体健康监控。
- **关键操作**:选门店、切日期范围(今日 / 近 3/7/10 天 / 自定义 RangePicker、刷新。
- **后端 API**`GET /api/admin/ai/dashboard`(参数 `site_id``range_days``date_from/date_to`)。
- **数据来源**`biz.ai_run_logs` + `biz.ai_alerts` + `biz.ai_token_budget`
- **必现字段**4 统计卡(调用 / 成功率 / Token / 平均延迟、7 天趋势、App 占比、预算进度(日/月、App 健康、最近告警表。
- **测试校核重点**`/dashboard` 嵌入本页时不应渲染重复顶部range_days=0 时启用 RangePicker。
---
### 3.10 `/ai/operations`AI 手动操作)
- **设计目的**5 卡操作面板:重跑 / 缓存失效 / 按需重跑 / 批量执行 / 告警管理 / 越过去重事件。
- **关键操作**:输入 trigger_job_id 重跑;按 app_type+member 失效缓存;按 app+member+site 重跑某 App批量执行预估→确认两步ack/ignore 告警;触发事件链。
- **后端 API**`POST /api/admin/ai/trigger-jobs/:id/retry``POST .../cache/invalidate``POST .../run/:appType``POST .../batch-run``POST .../batch-run/confirm``POST .../trigger-event``GET .../alerts``POST .../alerts/:id/(ack|ignore)`
- **数据来源**`biz.ai_run_logs` + `biz.trigger_jobs` + `biz.ai_chat_cache` + `biz.ai_alerts`
- **必现字段**site_id 默认 `2790685415443269`朗朗台球、6 个 App 类型选项(不含 app2 系列,预热单独走 `/ai/prewarm`)。
- **测试校核重点**:批量执行需先 estimate 拿 `batch_id` 再 confirm缓存失效返回 `affected_count`
---
### 3.11 `/ai/prewarm`AI 预热进度)
- **设计目的**:监控 app2_finance / app2a_finance_area 的 8 时间 × 9 区域 = 72 组合覆盖率注意area=all 走 app2_finance 8 组合,其余 8 区域走 app2a_finance_area 64 组合)。
- **关键操作**:选门店、刷新、一键批量补缺(串行 POST、触发全量预热dws_completed 事件)、单组合重跑。
- **后端 API**`GET /api/admin/ai/prewarm/progress``POST /api/admin/ai/run/(app2_finance|app2a_finance_area)``POST /api/admin/ai/trigger-event`
- **数据来源**`biz.ai_chat_cache`(统计已生成的 target_id × time_dimension × area 组合)。
- **必现字段**:环形进度条、缺失 missing 表(按区域分组)、单组合「重跑」按钮、批量补缺 Modal 进度。
- **最近变更**CHANGE 2026-04-23 新增 app2a_finance_area 区域版64 组合)。
- **测试校核重点**`areaToAppType('all')``app2_finance`;其他 → `app2a_finance_area`
---
### 3.12 `/ai/trigger-jobs`AI 调度历史)
- **设计目的**AI 事件链consumption / dws_completed / note_created / task_assigned的调度记录。
- **关键操作**:筛选 event_type / status / site_id / 日期范围、查看详情 Modal、Popconfirm 重跑、刷新。
- **后端 API**`GET /api/admin/ai/trigger-jobs``GET .../:id``POST .../:id/retry`
- **数据来源**`biz.trigger_jobs`job_type=ai_*+ 关联 `biz.ai_run_logs`
- **必现字段**:今日去重跳过数(`today_skipped_duplicates`)顶部统计、状态 Tag、事件类型、执行链 `app_chain`、耗时finished_at - started_at
---
### 3.13 `/tenant-admins`(租户管理员)
- **设计目的**:管理员 CRUDauth.tenant_adminsaud=tenant-admin含 2 步创建(基本信息 → 简写 ID
- **关键操作**搜索、切换显示已禁用、新增2 步骤 Steps、编辑、重置密码、软删除、简写 ID 管理弹窗。
- **后端 API**`GET/POST/PATCH/DELETE /api/admin/tenant-admins``POST .../:id/reset-password``GET /api/admin/registry/tenants``GET .../sites``PATCH .../sites/:id/code``GET .../sites/:id/code-history``POST/DELETE .../sites`
- **数据来源**`auth.tenant_admins` + `core.tenants` + `core.sites`FDW
- **必现字段**:用户名、显示名、租户名、管理类型 Tag、`managedSiteIds`、状态、最后登录、5 个操作按钮(编辑/重置密码/简写ID/启停/删除)。
- **后端响应**CamelModel 已序列化为 camelCase`displayName``managedSiteIds` 等)。
- **测试校核重点**Step1 基本信息提交后才能进入 Step2删除走软删除`isActive=false`);简写 ID 编辑同步写入 `core.site_codes_history`
---
### 3.14 `/settings/env-config`(环境配置)
- **设计目的**:编辑根 `.env`(敏感值 `****` 脱敏,导出去敏感)。
- **关键操作**行内编辑、批量保存dirtyMap 暂存)、刷新、导出 `env-config.txt`
- **后端 API**`GET /api/env-config``PUT /api/env-config``GET /api/env-config/export`blob 下载)。
- **数据来源**:根 `.env` 文件。
- **必现字段**:键 / 值(敏感为 ****/ 是否敏感 Tag / 编辑按钮、顶部 dirty Badge 计数。
- **测试校核重点**:敏感值留空提交不修改;导出文件名从 `Content-Disposition` 提取,回退 `env-config.txt`
---
### 3.15 `/settings/runtime-context`(业务运行上下文 / 沙箱)
- **设计目的**:超管按门店切换 live ↔ sandbox指定历史日期切换会按 site_id 暂停/恢复 `biz.trigger_jobs`
- **关键操作**:刷新列表、切到 sandbox选历史日期 + reset_sandbox 开关 + 备注原因)、切回 live、查看切换步骤 Modal。
- **后端 API**`GET /api/admin/runtime-context/sites``PATCH /api/admin/runtime-context`
- **数据来源**`meta.runtime_context` + `biz.trigger_jobs`(暂停/恢复影响)。
- **必现字段**门店列表site_id / site_code / mode Tag / sandbox_date / ai_mode、切换 Drawer/Modal、步骤展示success/skipped/warning/failed 颜色)。
- **测试校核重点**:仅 `super_admin` 可加载列表sandbox_date 必填且 ≤ 今日;切换返回的 steps 全部展示。
---
### 3.16 `/logs/dev-trace`DevTrace 全链路日志)
- **设计目的**HTTP / SSE / WS / Job 全链路 span 树查看 + 覆盖率扫描 + 设置管理 + 手动清理。
- **关键操作**:选日期、按 trace_type / method / status_code / 关键字筛选、点行看 span 树、覆盖率扫描、设置 Drawer开关 + 保留天数 + 清理)。
- **后端 API**`GET /api/admin/dev-trace/(dates|requests|coverage|settings)``GET .../request/:id``PUT .../settings``POST .../cleanup``POST .../coverage/scan`
- **数据来源**:本地 trace 日志文件(按日期分文件)。
- **必现字段**覆盖率状态栏、25 种 span_type 颜色映射、左侧请求列表 + 右侧 span 树。
- **测试校核重点**:覆盖率 scan 是 POST结果异步刷新`cleanupLogs` 返回 `deleted_dates` + `deleted_files`
---
### 3.17 `/logs/ai-run-logs`AI 调用明细)
- **设计目的**AI 单次调用的 prompt / response / error 详情查看。
- **关键操作**:筛选 app_type / status / trigger_type / site_id / 日期范围、点行打开 Drawer。
- **后端 API**`GET /api/admin/ai/run-logs``GET .../:id`
- **数据来源**`biz.ai_run_logs`
- **必现字段**app_type、trigger_type、member_id、tokens_used、latency_ms、状态 Tag、Drawer 内 prompt/response/error 全文。
---
### 3.18 `/logs/db-viewer`(数据库查看器)
- **设计目的**:业务库只读 SQL 查询界面。
- **关键操作**:左侧 Tree 异步加载 schema → table、点表加载列定义、写 SQL → 执行(仅 SELECT
- **后端 API**`GET /api/db/schemas``GET /api/db/schemas/:s/tables``GET /api/db/tables/:s/:t/columns``POST /api/db/query`
- **数据来源**:业务库 `zqyy_app`(含 FDW 映射的 ETL `app.v_*`)。
- **必现字段**:左 Treeschema 图标 + table 行数)、右上 SQL 编辑器、右下 列定义 / 查询结果切换。
- **测试校核重点**:后端只允许 `SELECT``encodeURIComponent` 处理 schema/table 名。
---
## 四、跨页共性约定
1. **认证守卫**`PrivateRoute` 检查 `useAuthStore.isAuthenticated`,未登录跳 `/login`。Login 之外所有路由都包在 `AppLayout` 下。
2. **响应包装**:后端 `ResponseWrapperMiddleware` 把 2xx 响应包为 `{code:0, data:...}``apiClient` 拦截器统一解包,使页面代码直接拿 `data`
3. **JWT 双认证**admin-web 用 aud=`admin` token本后台不应出现 miniapp / tenant-admin token其它两个前端项目独立
4. **401 自动刷新**`apiClient` 拦截器单飞刷新 + 队列重放,刷新失败清 token 跳 `/login`
5. **重定向**`/``/dashboard``/log-viewer`(已废弃)→ `/etl-tasks?tab=queue`
6. **业务日**`useBusinessDayStore.init()` 启动时拉营业日配置(用于 ETL 时间窗口)。
7. **底部状态栏**:每 5s 轮询 `/api/execution/queue`,展示 running 任务flow + 前 3 个 task
8. **侧边栏**`/triggers?tab=biz``/triggers?tab=ai` 是带 search 的特殊菜单 key`getSelectedKeys` 根据 `pathname + search` 精确匹配。
9. **WebSocket**:仅 `TaskManager.QueueTab` 使用 `/ws/logs/:id` 实时日志(无独立 store后台 AI WS 由 `ai_ws_router` 提供,但 admin-web 暂未消费。
10. **响应格式**:多数 API 返回原始数组或对象;分页接口统一返回 `{ items, total, page, page_size }`AI 系列再附加业务字段如 `today_skipped_duplicates`)。
11. **角色控制**`super_admin` 才看到「业务运行上下文」「待审核任务的重分配/关闭」「参数管理的写入」按钮,前端通过 `useAuthStore.user.roles` 判断。
---
## 五、文档冲突待确认清单
> 以下与 NS1 / NS4 PRD、API-REFERENCE 或代码现状发现不一致或需澄清的点,待 Neo 确认。
1. **NS1 vs 代码**NS1 主要描述 `/api/xcx/*` 小程序接口,未覆盖 `/api/admin/*`admin-web 的全部 API 当前以 `apps/backend/app/routers/admin_*.py``app/routers/*.py` 实际实现为准,缺少独立 PRD。`待 Neo 确认`:是否需要补一份 `NS-admin-web-backend-api.md`
2. **NS4 / NS4.1 vs admin-web**NS4 / NS4.1 是 tenant-admin 重设计,与 admin-web 视角无直接冲突。但 `auth.tenant_admins` 表与 `/admin/tenant-admins` 路由都在 admin-web 出现管理租户管理员两者职责边界文档化建议明确admin-web 操作租户管理员账号本身tenant-admin 管理「门店运营」。`待 Neo 确认`
3. **AI 触发器双 API**`/api/admin/ai/triggers`adminAI.ts`/api/trigger-jobs`triggerJobs.ts操作的是同一张 `biz.trigger_jobs` 表,前者带 job_type 过滤、后者全量。`AITriggers.tsx` 用前者编辑 cron/desc`BizTriggersTab` 用后者编辑 cron_expression/interval_seconds。`待 Neo 确认`:两套 API 是否合并?或明文区分使用边界。
4. **预热进度 vs API 文档**`AIPrewarm` 注释写「app2_finance 72 组合」,实际是 `area=all` 走 8 组合 + 8 区域走 64 组合 = 72NS3 / API-REFERENCE 是否同步说明这个二分?`待 Neo 确认`
5. **事件类型枚举**`AIOperations.EVENT_TYPE_OPTIONS`4 项)、`AIPrewarm` triggerEvent (`dws_completed`)、`AITriggerJobs` 不限制NS3 是否有完整 event_type 枚举表?`待 Neo 确认`
6. **DBViewer 的安全边界**`POST /db/query` 后端是否仅允许 SELECT前端无校验依赖后端 sqlparse 或类似拦截。`待 Neo 确认`
7. **`clearAllTasks`(清空 coach_tasks危险操作**`TriggerJobs` 顶部的 danger 按钮调 `DELETE /api/admin/task-engine/clear-all-tasks`,注释写「测试用」。`待 Neo 确认`:是否仅在 `mode=sandbox` 才允许?现状无运行模式守卫。
8. **侧边栏 `?tab=` 入口**「AI 管理 → 触发器设置」与「系统设置 → 触发器配置」都跳到 `/triggers?tab=ai|biz`,菜单上是两个 entry 但页面只有一个 TriggerManagerUX 是否符合预期?`待 Neo 确认`
9. **Login 接口路径**:前端 `useAuthStore.login``/api/auth/login`main.py 通过 `auth.router` 注册),未在本调研中读取 `auth.py` 路径常量,但 401 刷新拦截器引用了 `/auth/refresh``待 Neo 确认`:路径前缀是否含 `/admin`
10. **`ai-group` 「触发器设置」展开问题**`getDefaultOpenKeys` 注释里写 「无法判断 tab交由路由侧 searchParams 处理默认展开」,当前从 ai 子菜单跳到 `/triggers?tab=ai` 时不会自动展开 ai-group。`待 Neo 确认`:是否需要修正 selectedKeys 逻辑使两个 group 都高亮?
---
> 文档篇幅控制:约 280 行(不含本提示)。本文为快速核对参考,详细业务规则以各页面 `.tsx` 顶部注释 + 后端 router 实现为准。