argus-cluster/specs/mvp/v3.9/ui_refactor_plan.md

109 lines
4.5 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.

# v3.9 UI 重构方案(保持功能不变)
## 背景与问题
当前 `src/mvp/py/argus/service/ui.py` 单文件约 1400+ 行,包含:
- 全局 CSS/JS长字符串
- 布局渲染nav/page 拼接)
- 11 个页面的 HTML + 大段内嵌 JS包含 TaskSpec 模板与表单逻辑)
导致:变更难定位、合并冲突多、缺少模块边界、复用困难、测试覆盖薄弱。
## 目标(功能不变)
- **路由与页面行为完全不变**URL、返回内容、按钮/表单行为、localStorage key`mvp_token`/`mvp_sftp_password`、API 调用路径保持不变。
- **不引入前端构建链/新依赖**(仍然用纯字符串/轻量模板函数)。
- 将 UI 拆分为可维护的多个文件(放到 `src/mvp/py/argus/ui/`)。
- 增加最小的单测(确保路由可访问、关键 DOM 标识存在)。
## 非目标
- 不重做 UI 样式/交互;不引入 React/Vue不改后端 API。
- 不新增鉴权逻辑(仍然是浏览器 localStorage + Bearer token
## 拆分后的目录结构(建议)
新增包:`src/mvp/py/argus/ui/`
```
argus/ui/
__init__.py # register_ui_routes(app) 统一入口
assets/
base_css.py # BASE_CSS 常量
base_js.py # BASE_JS 常量apiFetch/apiJson 等通用函数)
layout/
nav.py # nav(active) + 链接配置
page.py # page(title, active, body, script, extra_head=...)
pages/
login.py # /ui/login
tasks.py # /ui/tasks
task_new.py # /ui/tasks/new模板常量 + 表单 JS
task_detail.py # /ui/tasks/{task_id}
task_logs.py # /ui/tasks/{task_id}/logs
serving.py # /ui/serving, /ui/serving/new, /ui/serving/{model_key}
data.py # /ui/data
admin.py # /ui/admin
routes.py # 将各 pages.register(app) 聚合注册
```
兼容层(可选但推荐):保留 `src/mvp/py/argus/service/ui.py` 仅做转发:
```py
from argus.ui import register_ui_routes
```
这样可以避免一次性改动 `service/app.py` 的 import 路径,减少风险。
## 页面拆分原则
每个 page 模块提供两个函数:
- `render(...) -> HTMLResponse`:只负责拼接 body/script不直接碰 FastAPI app
- `register(app: FastAPI) -> None`:只负责挂载路由(`@app.get(...)`)。
通用能力下沉:
- `_BASE_CSS`/`_BASE_JS` 移到 `assets/`
- `_nav()``_page()` 移到 `layout/`
- 大块常量TaskSpec 模板、UI 文案)放在页面模块同文件顶部,避免散落在函数内部。
## 资源交付方式(两种可选)
### 方案 A最稳继续内联 CSS/JS但拆到不同 Python 文件
- `page()` 内继续 `<style>{BASE_CSS}</style>``<script>{BASE_JS}</script>`
- 只改变代码组织,不改变浏览器加载方式,风险最低。
### 方案 B推荐中期新增静态端点分发资源
新增:
- `GET /ui/assets/base.css`
- `GET /ui/assets/base.js`
页面改为 `<link rel="stylesheet" href="/ui/assets/base.css">` + `<script src="/ui/assets/base.js"></script>`
优点:减少 HTML 体积、浏览器缓存更好;缺点:需要确认反向代理/中间件不拦截这些路由。
建议 v3.9 先落地方案 A稳定后再做方案 B。
## 迁移步骤(建议分 3 次 PR
1) **抽公共层**:引入 `argus/ui/assets/*``argus/ui/layout/*`,保持 UI 输出完全一致;`service/ui.py` 仍在但内部改为调用新 layout或先不动
2) **按页面迁移**:逐个把 routes 迁移到 `argus/ui/pages/*`每迁一个页面就加一个最小测试用例200 + 关键文本存在)。
3) **清理与稳定**`service/ui.py` 变为兼容转发;可选引入 `/ui/assets/*` 静态端点(方案 B
## 测试策略(最小但有效)
新增 `src/mvp/py/tests/test_ui_pages.py`
- 创建 FastAPI app复用现有测试的 app 初始化方式)
- 请求下列页面,断言 `status_code == 200`
- `/ui/login`, `/ui/tasks`, `/ui/tasks/new`, `/ui/serving`, `/ui/data`, `/ui/admin`
- 断言响应包含稳定锚点文本(例如 `Argus MVP`, `New Task`, `Tasks`),避免脆弱的全量快照。
## 验收标准Definition of Done
- 11 个 `/ui/*` 路由行为与输出不变(人工 smoke + 自动化最小测试)。
- `src/mvp/py/argus/service/ui.py` 不再包含大段 HTML/JS仅兼容转发或极薄封装
- 新增/修改 UI 页面不需要触碰 1000+ 行单文件;每页的改动范围限定在对应模块。