# 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` 内若有跨文件 import（grep 显示无 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 未 import）；19 个路由全部保留可达。
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 行。本子代理仅产出建议，**未对任何源码执行修改**。
