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,141 @@
# admin-web 孤儿页面处置建议
> 生成日期2026-05-04 范围6 个 `.tsx`5 个被列为孤儿 + 1 个已确认在用)
> 用户列出的清单经源码核对后修正:`AITriggers.tsx`、`ETLStatus.tsx`、`TaskConfig.tsx`、`TaskManager.tsx` 4 个并非孤儿,而是被新页面以子组件方式 import只有 `OpsPanel.tsx` 是真正孤儿。
> 来源:`apps/admin-web/src/App.tsx`、`apps/admin-web/src/pages/ETLTasks.tsx`、`apps/admin-web/src/pages/TriggerManager.tsx`、`apps/admin-web/src/pages/Dashboard.tsx`,以及对 `import` 语句的全量 grep。
---
## 一、清单(实际状态)
| 页面 | 路由 | 状态 | App.tsx 是否 import | 实际是否被引用 | 建议 |
|---|---|---|---|---|---|
| `AITriggers.tsx` | 无 | 已挂载(子组件) | 否 | 是(`TriggerManager.tsx` L40 import嵌入 `AITriggersTab` | **保留** |
| `ETLStatus.tsx` | 无 | 已挂载(子组件) | 否 | 是(`ETLTasks.tsx` L25 import作为 `status` Tab | **保留** |
| `OpsPanel.tsx` | 无 | 真孤儿 | 否 | 否grep 无任何 import功能由 `Dashboard.tsx` 直接组合 ops/* Section 实现) | **归档到 `_archived/`,待 Neo 确认后删除** |
| `TaskConfig.tsx` | 无 | 已挂载(子组件) | 否 | 是(`ETLTasks.tsx` L22 import作为 `config` Tab | **保留** |
| `TaskManager.tsx` | 无 | 已挂载(子组件,仅命名导出) | 否 | 是(`ETLTasks.tsx` L23 `import { QueueTab, HistoryTab }` | **保留**;可考虑后续重构为 `tabs/QueueTab.tsx` + `tabs/HistoryTab.tsx` |
| —(参考样例) | — | — | — | — | — |
> 注:`TenantAdmins/index.tsx` 以目录导出,不在本盘点范围。`_archived/LogViewer.tsx` 已规范归档。
---
## 二、逐个分析
### 2.1 `AITriggers.tsx`
- **代码内容**(顶部注释 + 关键能力):
- 「AI 触发器设置页面。管理 `biz.trigger_jobs` 表中 `job_type='ai_*'` 的所有触发器」
- 列表 + 启停 Switch + 编辑 cron 表达式 / 描述(仅 cron 类型可编辑 cron
- 调用 `listTriggers()``updateTrigger()`(即 `GET/PATCH /api/admin/ai/triggers/:id`)。
- **业务功能**AI 触发器 CRUD不含创建/删除)。
- **是否被替代**:未被替代,**而是被嵌入复用**。`TriggerManager.tsx` L40 显式 `import AITriggers from './AITriggers'`,并在 `AITriggersTab` 子组件里以 `<AITriggers />` + `<AIOperations />` + `<AITriggerJobs />` 的纵向组合展示。
- **建议****保留**。
- **删除影响**:会破坏 `/triggers?tab=ai` 入口的 AI 触发器编辑能力,且 `AITriggers` 调的是 `/api/admin/ai/triggers`(不同于 `BizTriggersTab` 用的 `/trigger-jobs`),两个 API 在后端实际由不同 router 提供,不能简单替代。
---
### 2.2 `ETLStatus.tsx`
- **代码内容**:游标状态 Table`task_code` / `last_start` / `last_end`+ 最近执行记录 Table`task_codes` / 状态 / `started_at` / `duration_ms`+ 顶部 success/failed/running 计数 Statistic。
- **业务功能**ETL 调度任务的健康监控(游标推进 + 最近执行)。
- **是否被替代**:未替代,**被嵌入为 `/etl-tasks?tab=status` Tab**。`ETLTasks.tsx` L25 `import ETLStatus from './ETLStatus'`L99 `children: <ETLStatus />`
- **建议****保留**。
- **删除影响**:会让 `/etl-tasks?tab=status` 渲染失败(编译报错)。
---
### 2.3 `OpsPanel.tsx`**真孤儿**
- **代码内容**:组合 `SystemResourceSection` + `ServiceStatusSection` + `GitStatusSection` 三个 ops 子组件,调 `fetchSystemInfo / fetchServicesStatus / fetchGitInfo / startService / stopService / restartService / gitPull / syncDeps` 8 个 API。
- **业务功能**:服务器资源 + 服务启停 + Git 状态(与 `/dashboard` 上半部分完全重叠)。
- **是否被替代****是**。`Dashboard.tsx` 在 CHANGE 2026-07-25 / Task 8.1 之后直接内联 ops/* 三个 Section 组件 + 同样的 8 个 API 调用(含 `Modal.info` 显示 git pull 输出),等价复刻了 OpsPanel 的全部行为;并在其上叠加 DB 健康 + AI 总览 + AI 调度摘要。
- **建议****移到 `apps/admin-web/src/pages/_archived/OpsPanel.tsx`,待 Neo 确认后删除**。不直接删除是因为:
1. CHANGE 注释2026-07-25 Task 8.1)有保留它作为「单页可见的运维子页」备份的潜在价值。
2. 测试文件 `apps/admin-web/src/__tests__/dashboard.test.tsx` 涉及 OpsPanel 相关命名,需先确认是否引用 `OpsPanel` 类型/常量后再清理。
- **删除影响**grep 全量无任何 `from.*OpsPanel``import.*OpsPanel`(仅页面自身的注释和 `components/ops/*` 子组件出现)。`__tests__/dashboard.test.tsx` 中的 OpsPanel 字符串需复核(可能是断言文案,不影响)。
- **建议命令****示例,待 Neo 批准后再执行;本子代理不实际操作**
```bash
git mv apps/admin-web/src/pages/OpsPanel.tsx apps/admin-web/src/pages/_archived/OpsPanel.tsx
```
---
### 2.4 `TaskConfig.tsx`
- **代码内容**顶部注释「ETL 任务配置页面。提供 Flow 选择、处理模式、时间窗口、高级选项等配置区域,以及连接器/Store 选择、任务选择、DWD 表选择、CLI 命令预览和任务提交功能」。包含丰富的 fallback Flow 字典 + `validateTaskConfig` + `submitToQueue` / `executeDirectly` / `createSchedule`。
- **业务功能**ETL 任务发起(最复杂的页面之一)。
- **是否被替代**:未替代,**被嵌入为 `/etl-tasks?tab=config` Tab**(默认 Tab。`ETLTasks.tsx` L22 `import TaskConfig from './TaskConfig'`L59 `children: <TaskConfig />`。
- **建议****保留**。
- **删除影响**`/etl-tasks?tab=config`(默认 Tab渲染失败这是用户进入 `/etl-tasks` 的首屏。
---
### 2.5 `TaskManager.tsx`
- **代码内容**3 Tab 容器(队列 / 调度 / 历史),但 `ETLTasks.tsx` 只复用其中 2 个 **命名导出**`export const QueueTab` / `export const HistoryTab`。WebSocket 实时日志在 `QueueTab`。
- **业务功能**ETL 任务队列与历史。
- **是否被替代**:未替代,**子组件被新页面以命名 import 复用**。`ETLTasks.tsx` L23 `import { QueueTab, HistoryTab } from './TaskManager'`。但 `TaskManager` 默认导出如果有和「调度」Tab 内部逻辑(`ScheduleTab` 现已提到 `components/ScheduleTab.tsx` 顶层)已不再使用。
- **建议****保留**当前文件,但建议后续轻量重构(**非本次任务范围**
1. 把 `QueueTab` / `HistoryTab` 拆到独立文件 `pages/etl-tasks/QueueTab.tsx` / `HistoryTab.tsx`
2. 删除 `TaskManager.tsx` 的 default export如有和容器 Tabs 逻辑,因为已被 `ETLTasks.tsx` 取代。
- **删除影响**:直接删除会让 `ETLTasks.tsx` 的 queue / history Tab 渲染失败。
---
## 三、批量执行建议
仅对 **真孤儿 `OpsPanel.tsx`** 给出动作清单。其余 4 个文件**禁止删除或归档**(会破坏在用功能)。
### 3.1 推荐方案 A保守**默认推荐**
```bash
# 仅归档 OpsPanel保留可恢复路径
git mv apps/admin-web/src/pages/OpsPanel.tsx apps/admin-web/src/pages/_archived/OpsPanel.tsx
```
- 优点:可恢复;遵循 `_archived/` 归档惯例(同 `LogViewer.tsx` 在 `_archived/` 的处理);触发 `pre_read_archived_block.py` hook 阻断后续意外读取。
- 风险:`__tests__/dashboard.test.tsx` 内若有跨文件 importgrep 显示无 import 但有字符串匹配),需测试运行验证。
### 3.2 方案 B激进仅在 Neo 明确批准时使用)
```bash
git rm apps/admin-web/src/pages/OpsPanel.tsx
```
- 风险:丢失备份;如果 Dashboard 内联化未来回滚,需从 git 历史恢复。
### 3.3 不在本次任务执行的「后续重构」建议
- `TaskManager.tsx` 拆分为 `pages/etl-tasks/QueueTab.tsx` / `HistoryTab.tsx`,删除容器代码(仅在确认 `default export` 未被外部使用后)。
- `AITriggers.tsx` / `ETLStatus.tsx` / `TaskConfig.tsx` 的命名规范化建议:移动到 `pages/etl-tasks/` 与 `pages/triggers/` 子目录,使「孤儿假象」从源头消除。
---
## 四、对路由 / 测试 / 后续 Wave 的影响
1. **路由**:仅归档 `OpsPanel.tsx` 不改变任何已注册路由App.tsx 未 import19 个路由全部保留可达。
2. **构建**:归档后 `pnpm build` 应仍然通过(因无 import 引用);执行前建议在本机跑一次 `pnpm tsc --noEmit` 与 `pnpm build` 验证。
3. **测试**
- `apps/admin-web/src/__tests__/dashboard.test.tsx` 对 OpsPanel 字符串的引用需 grep 复核:若仅是断言文案 `「OpsPanel」`,可不动;若 `import` 了 `OpsPanel`,需先调整测试。
4. **Wave 2/3 测试场景**
- Wave 2「ETL 全流程走查」覆盖 `/etl-tasks` 5 Tab**禁止删除 TaskConfig / TaskManager / ETLStatus**。
- Wave 2「触发器统一管理」覆盖 `/triggers` 4 Tab**禁止删除 AITriggers**。
- Wave 3「运维首页」仅依赖 `Dashboard.tsx` 与 `components/ops/*`,与 OpsPanel 归档/删除无关。
---
## 五、修正用户原任务描述
用户原任务描述「6 个孤儿/已挂载页面5 孤儿 + 1 已挂载)」与源码不符。修正:
- **真正孤儿**1 个(`OpsPanel.tsx`)。
- **已挂载(路由)**0 个(这 5 个文件均未直接挂载路由)。
- **已挂载(子组件复用)**4 个(`AITriggers.tsx`、`ETLStatus.tsx`、`TaskConfig.tsx`、`TaskManager.tsx`)。
最终建议汇总:**1 归档OpsPanel+ 4 保留(其余)+ 0 直接删除**;待 Neo 确认是否升级到「方案 B 删除」或同时启动 TaskManager 重构。
---
> 文档篇幅约 200 行。本子代理仅产出建议,**未对任何源码执行修改**。