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
This commit is contained in:
Neo
2026-05-04 07:38:28 +08:00
parent c6453829a6
commit 509cf43284
44 changed files with 10789 additions and 0 deletions

View File

@@ -0,0 +1,325 @@
# 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 实现为准。