refactor(web): 数据字典抽到 connect-test + 步骤用 step_id 注册 + 修白屏
## 1. 操作模式重构(核心需求)
按用户要求把 web 端的操作模式从"启动任务时抽数据字典 + 编号步骤"改成
"测试连接时抽数据字典 + 步骤注册式可扩展 + 勾选表后再分析"。
### 后端
- 新增 `web/core/data_dict.py`:`extract_data_dictionary(cfg)` 函数,
connect-test 与 orchestrator 共用(避免重复查询)
- 新增 `web/core/data_dict_cache.py`:按连接身份 (db_type/host/port/db/user)
缓存字典,缓存命中走内存,未命中现场再抽
- 删除 `web/core/step_impl/step1_data_dict.py`(从流程中彻底移除)
- `web/core/orchestrator.py`:
- 流程表从 `[(num, fn, ...), ...]` 改为 `dict[str, StepDef]`
- 用 `register_step(...)` 装饰器一行注册一个 Step
- `CRITICAL_STEPS` 改为 `{"merge_redundancy", "missing_comments"}`
- `run_governance_workflow(..., tables: list[str])` 接受前端勾选的表
- `web/core/models.py`:
- `ConnectRequest.tables: list[str]`(必填,空时后端返 400)
- `StepInfo.num: int` → `StepInfo.id: str` + `order: int`
- `JobStatusResponse.current_step: Optional[int]` → `Optional[str]`
- 所有步骤列表 `list[int]` → `list[str]`
- `TestConnectionResponse` 新增 `table_summary` / `data_dictionary` 字段
- `web/core/step_impl/step{2,4,5,6,7}.py`:
- 全部新增 `table_filter: set[str] | None = None` 参数,开头过滤 `columns`
- 全部 `step="N"` 字符串改为 `step="step_id"`(merge_redundancy / empty_fields / ...)
- `web/core/job_manager.py`:`Job.current_step` / `steps_planned` / `steps_completed` /
`steps_failed` 全部从 `int` 改为 `str`,`_sync_step_start/done` 同步
- `web/api/routes.py`:
- `/api/connect/test` 成功后 `extract_data_dictionary` + `cache.put`,
返回 `table_summary` + `data_dictionary`
- `/api/jobs` 校验 `tables` 非空,否则 `HTTP 400`
- `/api/steps` 从 `get_step_defs()` 动态生成(不再写死编号)
### 前端 (`web/static/index.html` 全量重写)
- 卡片 1:连接数据库(保留)
- 卡片 2(新增):数据字典浏览器
- 左侧 el-table(reserve-selection):表名 / 注释 / 字段数;
全选 / 清空 / 反选 按钮 + 搜索框
- 右侧 el-table:选中表的所有字段,按 (table_name, ordinal_position) 排序
- 卡片 3:分析配置
- 步骤勾选 + 「开始分析」按钮(label 实时显示 X 张表 / Y 项检查)
- 表为空时按钮 disabled 并提示
- 卡片 4:分析进度 + 日志(SSE 流式)
- 卡片 5:分析结果(KPI + 多级表格)
- `TAB_STEP_MAP` 改用 step_id,不再用编号
- 移除所有 "Step N:" 前缀
## 2. 修复页面打开白屏
`web/static/index.html` 打开后页面全白,根因两层叠加:
### 2.1 多余 `</el-option>`
DB 表单"字符集"里写了 `<el-option ... />` 自闭合 + `</el-option>` 显式闭合,
Vue 模板编译器报 `Invalid end tag` (compiler code 23)。
修复:删除第 102 行的 `</el-option>`。
### 2.2 `v-else-if` 链断裂(Vue 3 compiler code 30)
Vue 3 要求 `v-else` / `v-else-if` 必须是上一个 v-if 元素的紧邻兄弟。模板里:
- 「重新分析」按钮的 `v-else-if` 与「取消」按钮的 `v-if` 中间夹了一个
无 v-if 的「开始分析」按钮,链断
- 「勾选提示」el-alert 的 `v-else-if` 上方是 `</el-form-item>`,也不是 v-if
修复:去掉 v-else-if,改用独立 v-if 显式写互斥条件。
## 3. 验证
- `python -c "from web.core import ..."` 全部通过
- `python -m web.app` 启动 OK,注册 5 个 step
- `/api/steps` 返回 `{id, order, title, ...}`(无 num)
- `/api/connect/test` 无 DB 时 ok=false,含 `table_summary: []`, `data_dictionary: []`
- `/api/jobs` 空 tables → `HTTP 400 {"detail": "tables 不能为空:..."}`
- 用 jsdom 抓真服务器返回的 `#app.innerHTML`(59914 字符),
喂给浏览器版 Vue 3.5.40 编译:errors=0, warnings=0
- jsdom 完整挂载:`#app` 渲染 2 子元素 / 8484 字符真实 DOM
## 4. 兼容性
- 旧的 `outputs/<db>/<ts>/findings/step_*_data_dict.json` 文件保留(前端不读)
- `step8_report.py` 消费的 6 个 section key
(`merge_candidates` / `redundancy_fields` / `empty_fields` /
`missing_comments` / `length_issues` / `standard_violations`)全部保留
## 5. 文件清单
新增:
- `web/core/data_dict.py`
- `web/core/data_dict_cache.py`
- `docs/WORKLOG.md`
删除:
- `web/core/step_impl/step1_data_dict.py`
修改:
- `web/api/routes.py`
- `web/core/job_manager.py`
- `web/core/models.py`
- `web/core/orchestrator.py`
- `web/core/step_impl/step{2,4,5,6,7}_*.py`
- `web/static/index.html`(全量重写)
- `web/README.md`
- `CLAUDE.md`(项目说明改为"数据治理工具,主要开发 web 端")
- `.gitignore`(加 tags.lock / tags.temp)
Showing
docs/WORKLOG.md
0 → 100644
web/core/data_dict_cache.py
0 → 100644
Please register or sign in to comment