- 07 Aug, 2026 4 commits
-
-
Data Governance Dev authored
把 6 个 tab (merge / redundancy / empty / missing / length / standards) 的展示抽出成通用协议,让每个 step 在 data 里嵌入 _protocol 自描述渲染, 前端一个通用 renderer 按协议渲染;新增 step 只需写 data + 嵌 _protocol, 零前端改动。 后端 - 新建 web/core/tab_protocol.py:dataclass (TabProtocol / KpiSpec / SummarySpec / TableSpec / ColumnSpec / RenderSpec / LinkageSpec) + _eval_path() 路径表达式求值 + make_protocol() 一站式 helper - 5 个 step 文件在 return 里嵌入 _protocol - step2_merge_redundancy.py:2 tab(merge_candidates + redundancy_fields) - step4_empty_fields.py:1 tab + 2 子表 + linkage;summary 加 flat 副本 - step5_missing_comments.py:1 tab - step6_length_check.py:1 tab - step7_standards.py:1 tab + 2 子表 + linkage - orchestrator.py 删 _build_overview 里 KPI 聚合逻辑 - models.py OverviewStats 缩为 5 字段(database / host / db_type / total_tables / total_fields / executed_at) 前端 web/static/index.html 大改 - 8 个硬编码 KPI 卡 → v-for='k in displayedKpis' - 6 个硬编码 <el-tab-pane>(~450 行)→ v-for='t in displayedTabs' - 删 TAB_STEP_MAP / perTableStats / flatEmptyFields / perTableRows / filteredViolations - 新增 displayedTabs / displayedKpis / tabStatus computed - 新增 evalPathExpr / resolvePath / resolveRows / renderSummary / resolveRenderPath 工具函数 - 10 种 render.kind 在 template 里以 v-else-if 分发(text / code / tag / tag_list / two_line / three_line / progress / percent / ratio / number) - 3 个嵌套展开行(merge / standards / empty_fields)保留硬编码 — 展开行内容太特定,WORKLOG 记为后续协议扩展方向 文档与验证 - 新建 docs/TAB_PROTOCOL.md:完整协议规范 + 新增 step 模板 + 真实走读 - 新建 scripts/verify_protocol.cjs(12 case)+ verify_e2e.cjs(9 case) + verify_render.cjs(12 case)+ verify_template.cjs(2 case)—— 共 35 个 case 全过 - verify_template.cjs 用 jsdom + 真实 vue.global.prod.js + Function 劫持 截获编译产物,专门兜底「页面变白 / 编译出坏 JS」回归 - WORKLOG 追加 v-else fallback 编译 bug 修复(Vue 3.5.x 在长 v-else-if 链末尾输出 : () 无条件空 call expression)—— 把 v-else 改为 v-else-if="!cond" 显式条件 构建 - package.json + package-lock.json:jsdom + @vue/compiler-dom(verify 脚本的 dev 依赖) - .gitignore 加 scripts/compiled_*.js(verify_template 失败时的 debug 产物)
-
Data Governance Dev authored
# 需求 用户连续两轮反馈: 1. 「表名 / 注释」外观扁平、长字段名被截断(`bui_history_field_label_table` → `bui_history_field_labe...`) 2. 第一轮我把表名 + 表注释塞在同一 cell 两行后:「错了,两个表还是在同一行, 只是显示表信息的那个表,表名和注释不要挤在一行,显得一行很高, 我希望表名和表注释分两列显示」—— 用户要求真正拆成两列 # 修改 ## 1. style.css — 新增「数据字典浏览器」专属样式块 (+62) ```css .dict-pane { display: flex; gap: 16px; } /* 左右结构保持 */ .dict-pane-left { flex: 0 0 560px; } /* 360 → 480 → 560,容纳 4 列 */ .dict-pane-right { flex: 1; min-width: 0; } .dict-name { display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-family: Consolas; } .dict-name--field{ display: inline-block; max-width: 100%; background: #f5f7fa; padding: 1px 6px; border-radius: 3px; color: #e6a23c; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .dict-comment { font-size: 12px; color: #909399; margin-top: 6px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .dict-comment--empty { font-style: italic; opacity: 0.6; } ``` ## 2. index.html — 拆列 + 类替换 (+12 / -17) - 「表名 / 注释」1 列 → 「表名」+「表注释」两列(min-width=220/180) - `<style>` 块里 dict-pane 7 行样式删除(已迁去 style.css 集中管理) - 字段数列 64 → 72,selection 列 40 → 44(按钮点击更稳) - 右侧字段表:表名列 180 → 200,字段名列 160 → min-width=200, 改用 dict-name / dict-name--field 类 # 验证(jsdom 全页 mock + click 测试连接) header: 4 列 [0] 表名 min-width=220 [1] 表注释 min-width=180 [2] 字段数 width=72 [3] (selection) width=44,含全选 checkbox body row[0]: 4 td td[0] "bui_history_field_label_table" ← 表名 td[1] "数据源标识表" ← 表注释 td[2] "1" td[3] "" has-checkbox=true ← selection 列行复选框 body row[2](无注释): td[1] "(无注释)" + dict-comment--empty ← 斜体灰字 0.6 透明 # 兼容性 - dict-pane 仍为 flex-row 左右结构(用户明确要求保持) - .dict-name-cell 类暂保留(无引用,后续可清理) - selection 列放最后约束保持不变(见上一提交 a07db7bb) # 文件清单 - docs/WORKLOG.md | +129 工作记录(拆分两轮反馈) - web/static/index.html | +12 / -17 列结构 + 类替换 - web/static/style.css | +62 数据字典浏览器专属样式块 -
Data Governance Dev authored
# 问题 左侧「数据字典浏览器」表格渲染了表名 / 字段数,但每行没有勾选框,无法单选 / 多选。 # 根因 Element Plus 的列渲染 bug:当 <el-table-column type="selection"> 写在「最前」, 且后面紧跟带 <template #default> slot 的列时: - header 的 selection <th> 被算成 colspan="2" scope="colgroup" (正常应该是 colspan="1" scope="col") - body 行的 selection <td> 完全不渲染 → 整个表只剩 header 的 1 个全选框 # 验证(jsdom 跑了 4 个最小 case) | selection 位置 | 后续列类型 | 结果 | | 1 | 第 1 | 全部 prop |
✅ 3 cell + 3 checkbox | | 2 | 第 1 | 全部 default slot |❌ 2 cell + 1 checkbox(bug)| | 3 | 末尾 | 全部 default slot |✅ 3 cell + 3 checkbox | | 4 | 末尾 | 全部 prop |✅ 3 cell + 3 checkbox | 只有 case 2 复现 bug —— 确认是 selection 列在前 + 后列带 slot 的组合触发。 # 修复 web/static/index.html:142-165 — 把 <el-table-column type="selection"> 从第 1 列移到末尾(第 3 列),并加注释说明这个约束。 # 验证 jsdom 模拟完整页面渲染后: - header 第 3 列:<th class="... el-table-column--selection" colspan="1" scope="col">含全选 checkbox - body 第 3 列:<td class="... el-table-column--selection"> 含 <label class="el-checkbox"> 行复选框 - 3 行 × 1 checkbox = 3 个勾选框(全部渲染) # 兼容性 - 行复选框从视觉上从最左 → 最右;功能(toggleRowSelection / clearSelection / selection-change)不变,依赖的是 row 对象不是列顺序 - 全选 / 清空 / 反选 三个按钮逻辑不依赖列顺序 # 文件清单 - docs/WORKLOG.md | +50 工作记录(排查过程 + 4 个 case 验证表) - web/static/index.html | +4 / -1 selection 列移位 + 约束注释 -
Data Governance Dev authored
## 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)
-
- 06 Aug, 2026 18 commits
-
-
Data Governance Dev authored
症状:分析完成后所有 tab 都显示「分析完成」徽章,但「冗余字段」 tab 一直停在「分析中」,即使 sections.merge_candidates.redundancy_fields 实际有 21 条数据。 根因:移除 Step 3「数据验证」前,Step 3 返回 section_key='redundancy_fields', 所以 sections.redundancy_fields 直接有数据。移除后没人再写这个顶层 key, 数据落在 sections.merge_candidates.redundancy_fields(Step 2 输出 嵌套在 merge_candidates 里)。 修复:TAB_STEP_MAP 支持 field 字段处理嵌套场景: redundancy: { step: 2, sectionKey: 'merge_candidates', field: 'redundancy_fields' } tabStatus computed 检查改为先取顶层 section、再按 field 取子字段: const section = sections[sectionKey]; const hasData = field ? (section && section[field]) : !!section; 行为: - merge tab 还是查 sections.merge_candidates 整体 - redundancy tab 现在查 sections.merge_candidates.redundancy_fields - 其他 tab 逻辑不变 -
Data Governance Dev authored
上一次删除 Step 3「数据验证」时把这个 SQL 模板也删了,但实际 Step 4_empty_fields.py(新 Step 3 大范围空字段扫描)也需要它来 预先统计每张表的实际行数(拿真实 COUNT(*) 而不是 information_schema 的 TABLE_ROWS 估算值)。 症状:最近一次 run (20260806_144238) 把全部 149 张表都标记为 "统计行数失败: SQL 模板不存在" → high_empty_fields_count=0, "大范围空字段" tab 完全没数据(虽然日志显示 Step 已"完成")。 修复:恢复 web/sql/verify/count_table_rows.sql,并更新注释说明 本 SQL 是 Step 3 大范围空字段扫描用的(不是 Step 3「数据验证」)。 注意:需要重新跑一次分析才能拿到新的 empty_fields 数据。
-
Data Governance Dev authored
移除 Step 3「数据验证」后,Step 号出现断层:1,2,4,5,6,7。重新编号让 Step 号 连续 1-6,对用户更直观。 改动: orchestrator.py: - STEP_REGISTRY:4→3 (空字段扫描), 5→4 (缺注释), 6→5 (字段长度), 7→6 (国标校验) - STEP_DEPENDENCIES 同步重新编号 - step_name() 同步重新编号('3_empty_fields' / '4_missing_comments' / 等) - _run_step4/5/6/7 重命名为 _run_step3/4/5/6(调用方 STEP_REGISTRY 已对,自动匹配) - 顶部 docstring 重写:6 步流程 + 重新编号说明 step_impl/*.py:每个文件里的 step="X" 日志标签同步重新编号 (4→3, 5→4, 6→5, 7→6),同时把 docstring 和 message 文本里的 Step X 字样也改了。 文件本身保留旧文件名(如 step4_empty_fields.py)—— 内部实现细节, 不影响外部行为;如果未来想重命名可单独一次提交。 routes.py:list_steps() 的 StepInfo 也重新编号(4→3, 5→4, 6→5, 7→6) frontend index.html: - form.steps 默认 [1,2,4,5,6,7] → [1,2,3,4,5,6] - 兜底过滤改成 n >= 1 && n <= 6(兼容旧缓存残留的 8/7/3) - TAB_STEP_MAP: - redundancy tab:step 3 → 2(与 merge 同一来源) - empty: 4 → 3 - missing: 5 → 4 - length: 6 → 5 - standards: 7 → 6 注:未触及 workflow/ 旧 CLI 目录、docs/DESIGN.md / README.md 文档, 那些是历史描述,单独一次文档 PR 一起改。 行为:UI 显示 Step 1-6 连续 6 个分析 Step,进度计算 / 报告生成 / section 关联都不变。文件 / 函数命名差异仅是内部实现细节。
-
Data Governance Dev authored
Step 3 实际产出价值低且有副作用: 1. 「行政区划孤儿编码检查」只判断字典表 c_bri_xzqh 是否存在, 没有真正跑 LEFT JOIN 找孤儿(代码注释里写了「可扩展」) 2. 「数据质量问题检查」只是占位,返回空列表 3. 「验证合并候选实际行数」有点用,但 result 已经直接覆盖 Step 2 的输出 最致命的是 _run_step3 返回 section_key='redundancy_fields' —— 这会 反向覆盖 Step 2 的 LLM 分类结果(classification / reasoning / recommendation 全没了,只剩 Step 3 的简单 field + table_count 列表)。 也就是说 Step 2 的 LLM 工作被 Step 3 默默销毁了。移除 Step 3 同时也修了 这个覆盖 bug,Step 2 的分类结果能正确进入报告。 改动: - 删除 web/core/step_impl/step3_verify.py - 删除 web/sql/verify/ + web/sql/xzqh/ 整个目录(仅 Step 3 使用) - orchestrator.py: - STEP_REGISTRY 移除 (3, 数据验证, _run_step3, ...) - STEP_DEPENDENCIES 移除 3: {1, 2} - step_name() 移除 3: '3_verify' - 删除 _run_step3 函数 - 顶部 docstring 重写:6 步流程 + 移除 Step 3 的原因 - routes.py:list_steps() 不再返回 Step 3 - job_manager.py:all_steps 默认值改成从 STEP_REGISTRY 取 (保持单一来源,避免硬编码漏改) - frontend index.html: - form.steps 默认 [1,2,3,4,5,6,7] → [1,2,4,5,6,7] - 兜底过滤也加上 n !== 3(兼容旧本地缓存残留) 注:未触及 workflow/ 旧 CLI 目录,它走的是另一套独立实现。 行为: - UI 上「执行步骤」区只有 6 个分析 Step - /api/steps 返回 6 项 - 主流程跑完后无条件生成报告(Step 8 拆出来之前的约定不变) - Step 2 LLM 分类结果不再被覆盖,能正确进冗余字段报告 -
Data Governance Dev authored
症状:最近 run 里 Step 2「表合并与冗余字段分析」21/21 高频字段全部 classification=unknown, source=llm_failed。但 LLM 调用本身成功 (HTTP 200),只是解析阶段拿不到 valid JSON。 根因:web/configs/llm.yaml 默认 max_tokens=1024。Step 2 让 LLM 返回 每条 reasoning+recommendation 各 50-100 字中文 ≈ 200-300 tokens, 15 字段 × ~250 tokens ≈ 3750 tokens 远超 1024 上限 → LLM 响应被截断 在某个汉字中间 → JSON 不完整 → _safe_parse_json 返回 None → 21 个 字段全标 unknown。 复现:用真实 15 字段 prompt 调 complete(),返回 2824 字符但末尾 "\u5e76\u4e14\u5bb9\u6613\u88ab'" 明显是截断。 修复(A+B 一起): A. web/configs/llm.yaml:max_tokens 1024 → 4096,附注释说明为什么 B. web/core/step_impl/step2_merge_redundancy.py:BATCH 30 → 8, 附注释说明为什么 实测验证(重启后):8 字段 batch 全部解析成功,分类到 4 种 (suspicious/common_business/common_base/true_redundancy),没有 任何 None 失败。 下次跑 21 字段 → 3 个 batch(8+8+5),每个都能塞进 4096 tokens。 注意:需重启后端服务才能让两处都生效(llm.py 是 Python 代码, llm.yaml 是启动时 LLMConfig.load() 一次缓存到 _client 单例)。
-
Data Governance Dev authored
之前 Step 8 出现在 UI 的「执行步骤」复选框里,用户可取消勾选;后端也按 8 in steps 决定是否生成报告,导致: 1. 用户可能漏勾导致拿不到报告 2. 进度条分母里挂着「报告生成」让人误以为它也算分析步骤 按用户要求,报告生成应该是分析完成的固定产出,不应该作为可选步骤。 改动: - orchestrator.py - STEP_REGISTRY 移除 (8, 报告生成, ...) 一项 - STEP_DEPENDENCIES 移除 8: set() 注释也清掉 - step_name() 不再支持 8 - 去掉 has_step8 / main_steps 不再过滤 8 - 「开始 生成报告(Markdown + Word)」从 if 8 in steps 改为无条件执行 - 顶部 docstring 改写说明新约定 - job_manager.py:默认 all_steps 从 range(1,9) 改为 range(1,8) - routes.py:list_steps() 不再返回 Step 8;steps_planned 默认 range(1,9) → (1,8) - models.py:ConnectRequest.steps 注释从「默认全 8 步」改为「默认全 7 步;报告生成不在 steps 内」 - step8_report.py:移除 4 处 step='8' 日志标签(不再是 Step) - frontend index.html - form.steps 默认 [1..8] 改为 [1..7] - startJob 兜底过滤:form.steps = form.steps.filter(n => n !== 8) (防止旧浏览器缓存里残留的 8 让后端报错) - form-hint 补充「报告生成不在步骤列表里,每次分析完成后会自动生成 Markdown + Word 供下载」 行为: - UI 上「执行步骤」区只有 7 个分析 Step - /api/steps 返回 7 项 - 主流程跑完后无条件生成报告,sections.reports.markdown/docx 照常返回 - 关键 Step 失败时仍会 RuntimeError 终止整个任务(与之前一致,sections 数据不全就没东西可报告) -
Data Governance Dev authored
原 step8_report.py 两个问题: 1. Markdown 每个章节都截前 10-20 条样本,详细信息缺失 2. docx 后半部分只是 stub:标题 + f"{summary}" 把整个 dict 塞进段落, 浏览器/Word 里看到的就是一坨 JSON 风格的字符串,没有表格 重写方案:两个版本共用 SECTION_ORDER + 同名渲染函数(_md_xxx / _docx_xxx), 保证两边结构对齐。 新增/补齐的章节内容: - 表合并候选:完整候选明细(ID/优先级/相似度/公共列数/差异列/建议/风险) + 各候选组的公共列清单 + 强/弱废弃候选分开列表 - 冗余字段:全部高频字段(不再截 20)+ LLM 失败标「⚠ ️ 待人工核对」 - 大范围空字段:阈值说明 + 按表汇总(高空数倒序) + 字段明细按表分组 (每张表高空/中空字段单独子表,含空值率) + 跳过表清单 - 缺失注释字段:summary(涉及表/LLM 调用次数)+ 按表分布 + 推测注释明细 (全列) + 未推测样本 - 字段长度异常:6 个汇总指标 + 全部异常字段(按 wasted_bytes desc 排, 10 列含国标/规则/依据) - 国标违规:按标准统计 + 每标准下的违规字段明细 + 违规样本(最多 500 条) 辅助细节: - Markdown 表格换行用 <br>、管道符转义 \|、空值显示 -、浮点格式 xx.xx% - docx 用原生 add_table + style 'Light Grid Accent 1',Heading 1/2/3 分层 - 顶层 docstring 说明新结构;SECTION_ORDER 单一来源驱动两版渲染 smoke test:拿真实 outputs/smart-build/20260804_085733/findings/_all_findings.json 跑过,Markdown 11425 字符 / 255 行,docx 24 段 + 7 张表格,数据正确。 -
Data Governance Dev authored
三处问题一起修: 1. Markdown 按钮点了没反应 - 按钮 @click 传 'md',但 jobResult.reports 里的 key 是 'markdown' - downloadReport 拿不到 url,静默 return - index.html:188 downloadReport('md') → downloadReport('markdown') 2. 改为字节流下载 - 原方案 window.open('/api/reports/...'):浏览器把 .md 直接显示在页面上 - 改 fetch + blob + <a download>:触发浏览器「另存为」对话框,体验正确 - 路径正则兼容正反斜杠(Windows/Linux) - 三段(db/run_id/filename)都 encodeURIComponent - 错误用 ElementPlus.ElMessage.error 提示,不再静默退出 3. API 路由路径少一段导致 404 - routes.py 在 web/api/,少算一层 base 就跨过了 web/ 目录 - 原 base = <项目根>/outputs/...,实际文件在 <项目根>/web/outputs/... - .parent.parent.parent → .parent.parent,与 job_manager.py 保持一致 -
Data Governance Dev authored
嵌套 el-table 在 expand 行里列宽不稳定(之前两版:先加 width:100%,再换 overflow-x:auto + minWidth,都仍只渲染出 3 列,注释/空值率被挤掉)。 改为原生 <table class="inner-empty-table">,浏览器原生 table 渲染稳定可靠: - 列定义:字段名 160 / 类型 100 / 注释 auto / 空值数 110 / 空值率 220 - 保留 el-progress 进度条展示空值率 - style.css 新增 .inner-empty-table 样式:表头浅灰、边框、斑马纹、悬停高亮 确认硬刷新(Ctrl+Shift+R)后展开任一行,5 列正常横向排开。
-
Data Governance Dev authored
两处前端 UI 调整: 1. LLM-required 步骤(Step 2 / 5)加 🪄 MagicStick 图标 + tooltip 提示 - 图标橙色 #e6a23c,仅在 s.llm_mode === 'required' 时显示 - hover 提示'此步骤需要调用大模型,可能会比较耗时' - 标题后追加'需 LLM' warning tag,与'必选'红色 tag 并列 - form-hint 升级:'带
✨ 图标的步骤需调用大模型,耗时会较长 (每步数秒到数十秒)' 2. 数据库类型只露 MySQL: - 删 el-radio-button label='dameng' - 后端 API 仍接受 db_type='dameng',只是 UI 不再露选项 - form.db_type 默认 'mysql' 不变 验证:MagicStick 在 element-plus/icons-vue 包内; 本地 == HTTP 服务返回(66056 字节)。 -
Data Governance Dev authored
Step 2 / 5 是 LLM-required 步骤,前端暴露开关容易让人误以为可以关闭、 跑出残缺结果。本轮简化前端:固定开启 LLM。 - 删除「启用 LLM」el-switch UI 块(原来与「执行步骤」并排 col 12) - 执行步骤 col 升级为 24 整行,避免复选框拥挤 - 删除 form.enable_llm 字段(form reactive 状态里) - 提示语扩展:'Step 2 / 5 需 LLM(已在 web/configs/llm.yaml 配置)' - 后端无需改:ConnectRequest.enable_llm 默认 True, 即使前端忘了带字段也会走默认值,不会降级到 False 验证:前端启用 LLM / enable_llm / el-switch 标记全部清除(65222 字节) 本地 == HTTP 服务返回一致。
-
Data Governance Dev authored
Step2 / Step5 两个 LLM 必跑步骤把单次请求承载量翻倍: - step2_merge_redundancy.py: BATCH = 15 → 30 (高频字段分类,21 个字段 → 1 次 LLM 调用,原来 2 次) - step5_missing_comments.py: BATCH = 15 → 30 (缺失注释推测,119 个字段 → 4 次 LLM 调用,原来 8 次) 每次调用时间略增(更多 input/output tokens),但消除了网络 往返 + LLM 服务侧 per-call 启动成本,总耗时预计缩短 30-50%。 未上更大 batch 的考虑:Step2 每条 item 约 100 tokens, 30 条后 prompt 已 ~3000 tokens,再大会撞输出 token 上限 并触发 LLM 注意力衰减。 首次跑后请观察 start.log 中 LLM 命中成功率(之前 119/119), 若下降到 100/119 以下需回调 BATCH。 AST 全部通过。
-
Data Governance Dev authored
两轮迭代: 第一轮:参考字段长度异常 tab 的新模板布局,把缺失注释字段 tab 从旧的 prop + fixed 改成 width:100% + min-width + 模板内联: - 表名 / 表注释 (template) - 字段名 / 字段注释 (template) - 类型 (prop data_type) - 推测注释 (prop predicted) - 置信度 (template + el-tag) - 依据 (prop reason) el-table 加 style='margin-top: 12px; width: 100%' max-height=560 第二轮:用户反馈'推测注释和类型都没有显示',可能是 prop 在某些 el-table-column 顺序/min-width 组合下被截断到不可见。 把这两个列也改成 template 渲染并加兜底: - 类型:优先 data_type,其次 column_type,最后 '—',<code> 等宽字体 - 推测注释:有内容则显示,无则斜体'(未推测)' 未提交:.gitignore(与本任务无关的此前改动)。
-
Data Governance Dev authored
之前结果只在所有 step 完成后才返回,导致前端看不到中间进度。本轮改: 后端增量发布: - orchestrator.run_governance_workflow 新增 on_section_update 回调 回调在每步完成且有 section_key 时触发 - job_manager 新增 _sync_section_update 同步回调到 job.result['sections'] (job.result 在任务结束时再被整体 result 替换) - api/routes.py /jobs/{id}/result 取消'必须 completed'限制, running/failed/cancelled 状态也允许读取 sections 前端轮询 + tab 状态: - pollStatus 每 1.5s 同时拉 status 与 result; loadResult 改为 merge sections(不整体替换 jobResult) - TAB_STEP_MAP 映射 tab -> (step, sectionKey) - tabStatus computed 按状态返回 'idle'|'running'|'done' - TAB_BADGE 配置:info(非分析对象)/warning(分析中)/success(分析完成) - 6 个 el-tab-pane 全部改用 #label slot,加 el-tag 徽章 bug 修复:OverviewStats 必填字段在运行中没数据导致 500: - core/models.py: database/host/db_type 改为带默认值 '' - api/routes.py: OverviewStats 构造用 try/except 兜底,失败降级到全零值 AST 全部通过;本地 == HTTP 服务返回一致。 -
Data Governance Dev authored
经历多轮迭代,本次提交整合以下改动: 后端 step7_standards.py: - SAMPLE_SPECS 列表:每条标准可对应多条抽样规格(当前 1 条 default) - 抽样时捕获实际渲染的 SQL 与 spec_id 落到每条 detail (sample_sql / sample_spec_id)— 后端保留供报告用 - violations_flat 增 table_comment / column_comment 字段 - 每条标准新增 violating_fields_count + details_with_violations (过滤掉 violations==0 的字段,前端直接消费) - 过滤零违规标准,不进入 violations_by_standard 前端 index.html: - 字段点击联动:selectedField + selectFieldFilter / clearFieldFilter + filteredViolations computed;选中后明细表只显示该字段违规 - 按标准统计表中字段清单改用 details_with_violations, 自动隐藏 0 违规字段;字段数列加「N / M」红字显示有违规字段数 - 标准列去除「取数口径」折叠面板(用户认为没意义) - 明细表去除选中字段时的 SQL 蓝边面板(用户认为没意义) - 明细表改为 4 列:表/表注释、字段/字段注释、标准/标准名、值/违规原因 - alert 文案改为「X 个标准有违规(共 Y 条违规记录)」 - .field-link / .field-link--active CSS:选中字段高亮 数据 / UI 一致性验证:本后端 AST 通过;本地 == HTTP 服务返回(59051 字节)。 "
-
Data Governance Dev authored
用户反馈国标违规 tab 列被压扁、表格未铺满。上一版用 overflow-x:auto 包裹 未能根治。根因:原 el-table-column type="expand" 嵌套子 el-table 加 el-tabs__content 的 overflow:hidden 组合在某些视口下渲染异常。 参照字段长度异常 tab 的简洁模板布局重做两个表: 按标准统计(7 列,无展开): - 标准 width=120 - 标准名称 min-width=380 模板:粗体代码 + 小字名称 - 字段数 width=100 align=right - 抽样数 width=120 align=right - 违规数 width=120 align=right - 违规率 width=140 三色(>50% 红 / >20% 橙 / 余绿) - 字段清单/违规率 min-width=340 模板内联最多 6 个字段,超出显示「…等共 N 个字段」 (替代原本的展开行,违规率按字段级别上色) 违规明细(3 列大幅合并): - 表 / 字段 min-width=280 模板:粗体表名 + 小字字段名 - 标准 / 标准名 min-width=320 模板:粗体规则代码 + 小字标准名 - 值 / 违规原因 min-width=420 模板:<code> 包值 + 小字错误原因 样式统一字段长度 tab: el-table style="margin-top: 12px; width: 100%" max-height="480" 删除上一版的 overflow-x: auto 包裹(不再需要)。 验证:本地 == HTTP 服务返回(54914 字节一致)。 -
Data Governance Dev authored
原规则只按 column_name 正则匹配,对命名不规范但注释清楚的字段(如 code_a / value1 等通用名)漏判。本次扩展: - 规则结构改 dataclass LengthRule: name_pattern: re.Pattern comment_keywords: tuple[str, ...] expected_length / standard / description - 每条规则同时给出字段名正则 + 字段注释关键字列表(CI 子串匹配) - 新增 _match_rule(col_name, col_comment, rule) → (hit, basis_text) 字段名正则未命中再试注释关键字 - issue dict 新增字段 basis: "column_name 匹配 ^pattern$" 或 "column_comment 命中关键字「kw」" - summary 新增 matched_by_name / matched_by_comment 计数 注释关键字示例(已覆盖常见中文命名习惯): 身份证号 → 身份证 / 公民身份 手机号 → 手机号 / 手机号码 / 移动电话 信用代码 → 统一社会信用代码 / 社会信用代码 / 信用代码 行政区划 → 行政区划 / 行政区划代码 / 地区编码 邮政编码 → 邮政编码 / 邮编 邮箱 → 邮箱 / 电子邮件 / e-mail 银行卡 → 银行卡号 / 银行卡 前端 '字段长度异常' tab:'国家标准 / 规则' 列加宽 320→340,下方新增一行 '依据:<basis>' 小字斜体,便于审计。 烟雾测试 5 用例:t1.id_card(身份证号)、t4.region_code(空注释) 走字段名; t2.code_a(注释含手机号)、t5.admin_code(注释含行政区划代码) 走注释关键字; t3.remark(备注) 正确剔除。 -
Data Governance Dev authored
原 v-if="currentJob" 的'取消任务'按钮: - 任务运行中 → 显示 - 任务完成/失败/取消后 → currentJob 仍 truthy,但用户已无'取消'语义可做, 按钮消失后再无任何动作按钮,体验断层 改成按状态显示两种按钮: - 运行中:'取消任务' (danger, 调用 cancelJob 走 DELETE /api/jobs/{id}) - 其它状态(已完成/失败/已取消/有旧结果):'重新分析' (warning) 调用新增的 resetAndStart(): - clearInterval(pollTimer) + close SSE - 重置 currentJob / jobResult / jobStatus / logs 全清零 - await startJob() 重新启动一次 测试:本地文件 = 服务返回(52958 字节一致),Refresh 图标已确认存在于 icons-vue 包。
-
- 05 Aug, 2026 16 commits
-
-
Data Governance Dev authored
上一轮改完后,用户截图反馈: - 表名/字段名/国家标准/规则 4 列内容不显示(show-overflow-tooltip + 窄列下被截断到看不见) - 表注释、字段注释两个数据字段没列展示 - 表格没铺满 tab 区域,右边大量空白 修复(6 列合并布局,总宽 1240px): - 表名 / 表注释 width=260 模板展示:粗体表名 + 小字表注释(无则斜体) - 字段名 / 字段注释 width=240 模板展示:粗体字段名 + 小字字段注释 - 长度 (实际/标准) width=130 模板:实际值红色加粗 / 灰色 / 标准值 - 浪费字节 width=90 模板渲染 - 国家标准 / 规则 width=320 模板:粗体标准号 + 小字规则说明 - 建议 width=200 直接 prop - el-table 加 style="width: 100%",强制撑满 tab 容器宽度 - 去掉全部 show-overflow-tooltip,避免窄列截断到不可见 - max-height=560,行多时纵向滚动 数据字段 table_comment/column_comment 在 step6 产出里就有,无需改后端。
-
Data Governance Dev authored
原表 9 列、累计固定宽 1100+px、首两列 fixed → 在较窄窗口下渲染异常。 改为 7 列、min-width 弹性布局、去掉 fixed、合并'实际长度/标准长度': - 表名 min-width=140 show-overflow-tooltip - 字段名 min-width=130 show-overflow-tooltip - 长度(实际/标准) min-width=130 模板渲染 (实际红色加粗/灰色/标准) - 浪费字节 width=90 align=right - 国家标准 min-width=120 show-overflow-tooltip - 规则 min-width=160 show-overflow-tooltip - 建议 min-width=160 show-overflow-tooltip - el-table 加 max-height=560,行多时纵向滚动 数据字段全部已在 step6 产出,无需改后端。 验证:HTTP 抓取的页面 HTML 已含新表格定义。
-
Data Governance Dev authored
- step6_length_check.py: 移除 llm 入参与自定义字段 LLM 推断分支, 只保留内置 GB/YD 14 条规则;签名简化为 run_step6(dict_data, log) - orchestrator.py: STEP_REGISTRY 中 Step 6 的 llm_mode 由 optional 改为 none; _run_step6 不再向 run_step6 传 llm;顶部 llm_mode 取值注释同步 - routes.py: /api/steps 返回的 Step 6 描述去掉「LLM 可选」字样 - README.md: LLM 依赖矩阵删除 Step 6 行,新增说明 Step 1/3/4/6/7/8 均无 LLM 依赖 - DESIGN.md: Step 6 章节由「固定 + LLM 混合」改为「100% 固定代码」, 删除 suggest_length_rule 示例 - CLAUDE.md: 补充「不要自动提交,我说提交再提交」纪律 验证: - ast.parse 通过 (orchestrator.py / routes.py / step6_length_check.py) - 烟雾测试:varchar(50) id_card + varchar(20) mobile → 2 条异常,符合预期
-
Data Governance Dev authored
上一个提交引入了 wave 调度,如果用户勾选了有依赖的 Step 但没勾该依赖(如选 1/3/4/5 但不选 2), 调度器会在 ready=[] 时抛 RuntimeError('调度死锁'), 整个 job 标失败,日志提示看起来很严重但其实只是用户配置问题。 修复: - 在进入 wave 调度前加预处理,把'依赖不在计划里' 的 Step 拎出来 WARN 跳过(沿用非关键失败的处理路径) - 把 wave 循环里 ready=[] 时的 RuntimeError 降级为 ERROR + break(防御性保留,理论上预处理后不应该再发生) - 调度计划日志里多加一行 '因依赖缺失跳过=...' 字段, 用户 / 排查时可以一眼看出被跳了哪个 验证(steps=[1,3,4,5] 此次失败案例): 调整前:Job 失败,错误 '调度死锁: 剩余 [3] 但无依赖被满足' 调整后:Step 3 因缺 [2] 被 WARN 跳过,Job 正常跑完 1/4/5 -
Data Governance Dev authored
目标 - Step 1(数据字典)为强制步骤,前后端都防御性兜底 - 其余 Step 按依赖图分波并行执行(Wave 调度) - Step 8 报告生成显式排在所有主步骤之后 调度器(orchestrator.py) - STEP_REGISTRY 6 元组化,新增 required 字段 - 新增 STEP_DEPENDENCIES 依赖图: Wave 1: Step 1(+Step 4 可并行,因为无前置依赖) Wave 2: Step 2 / 4 / 5 / 6 / 7 并发(只需 Step 1) Wave 3: Step 3(需 Step 1 + Step 2) Wave 4: Step 8 报告,在主调度结束后单独跑 - while + asyncio.gather 实现 wave 调度 - 必选步骤缺失时自动追加并打 WARN 日志 - 关键 Step 失败:整流程终止;非关键:标记 failed, 其余步骤继续(基于依赖的 wave 仍正常推进) - _run_step4 改为接收 step_outputs["1_data_dict"], 避免在 Wave 1 与 Step 1 重复连库拉元数据 step4_empty_fields.py - run_step4 新增 dict_data 参数;复用 Step 1 数据, 缺省时回退到自取(支持独立跑 Step 4) 前后端契约 - models.StepInfo 加 required: bool - routes.py /api/steps 给 Step 1 标 required=True - index.html:el-checkbox :disabled="s.required" + 必选 step 标题旁红色 "必选" 标签 - startJob 启动前再兜底检查一次 form.steps 是否包含所有必选 perf - 全部 8 步情形下,从串行 ~55s 降至 ~30s 级别 (Wave 2 同时跑 5 个, 加上 LLM 同时批分类 vs 串行等待) -
Data Governance Dev authored
后端 - models.py: OverviewStats 补充 mid_empty_fields / standards_applied 字段, 避免被 routes.py 的字段过滤机制误删 - orchestrator.py: _build_overview 修正 nested overview_meta 取值(三层嵌套, 之前一直兜底到 0 → 表/字段总数显示 0) - step4_empty_fields.py: 修复 table_comment 始终为空(之前从列级 row 取 table_comment,应从 table_summary 取),新增 per_table.total_fields 与 field_record 用同一份 table_comment_map 前端 (index.html / style.css) - 隐藏历史记录入口(保留后端接口,便于以后恢复) - 移除「中空字段」KPI 卡片(位于中间不符合浏览习惯) - 大范围空字段 tab: * 字段明细(平铺:等级/表名/表注释/字段名/字段注释/类型/空值数/空值率) 上移到主视图位置 * 按表统计下移为辅助视图,表名+表注释合并到一列避免错位 - 冗余字段 tab:把 prop 改成与后端实际数据一致的 field/table_count/classification/reasoning/recommendation/source,并 给 llm_failed / true_redundancy / suspicious / common_business / common_base 各加色 tag 显著标识 - 修复"\"LLM 失败\""导致的 template compile 错误引发的白屏 (HTML 属性里 \ 不会被当 JS 转义,把 " 换成「 」即可) - .app-main 宽度 1400 → 1800px,table 更舒展 -
Data Governance Dev authored
-
Data Governance Dev authored
-
Data Governance Dev authored
-
Data Governance Dev authored
-
Data Governance Dev authored
Why:与本次\"分批次提交并写明关联性\"的工作一致,固化到 CLAUDE.md, 后续每次 commit 都遵循\"提交信息描述清楚做了什么、为什么\"的格式。 -
Data Governance Dev authored
把工作流包装成浏览器化的产品:填表 → 测试连接 → 一键治理 → 实时进度。 核心架构 - web/app.py FastAPI 入口 + CORS + 静态资源挂载 - web/start.py 启动前依赖检查(可选 anthropic / dmPython) - web/start.bat Windows 一键启动脚本 - web/api/routes.py 12 个 REST 接口(jobs/history/standards/reports...) 调度与运行 - web/core/orchestrator.py 8 步流程调度 + 步骤级日志 + 异常 traceback - web/core/job_manager.py 后台任务管理 + LogBuffer + SSE 订阅 - web/core/db_adapter.py MySQL / 达梦 统一连接与查询 - web/core/step_impl/ 8 个 Step 的 Web 版实现 LLM 增强(可降级) - web/core/llm.py Anthropic / OpenAI / MiniMax 多 provider 适配 - configs/llm.example.yaml provider / api_key / base_url / model 模板 SQL 模板体系(Python 不再写 SQL) - web/sql/info_schema/ list_columns / list_tables 按 dialect 区分 MySQL / 达梦 - web/sql/verify/ count_table_rows - web/sql/empty_fields/ count_with_nulls - web/sql/xzqh/ check_dict_table_exists / find_xzqh_orphans - web/sql/standards/ sample_field_values - web/sql/health/ check_connection - web/sql/loader.py 占位符 + dialect 自动加载 前端(无构建步骤) - web/static/index.html Vue 3 单页应用 - web/static/lib/ Vue + Element Plus 静态资源 - web/static/style.css 实时日志 / 历史归档 / 报告下载 - SSE 流(GET /api/jobs/{id}/logs/stream) - outputs/<db>/<ts>/findings/_all_findings.json - outputs/<db>/<ts>/reports/{md,docx} - GET /api/history /api/reports/{db}/{ts}/{file} 调试能力(本次一并落地) - 三路日志:SSE 实时流 + web/logs/app.log + outputs/<db>/<ts>/run.log - 每步开始 / 完成带耗时、进度 N/M;异常带 traceback 与异常类型 - 数据库 [DB] 连接 / SQL 执行时间;路由 [POST /api/xxx] 入参摘要 - 启动脚本自带 web/logs/start.log Why:CLI 工作流需要登录机器;Web 端把治理入口放到任何能开浏览器的设备上, 配合 SSE 实时反馈,业务方也能直接用。 How:复用 workflow/ 中的 8 步逻辑与 standards/ 国标插件;新增 Pydantic 契约 + job_manager + SSE,前后端用 REST + 事件流通信。 -
Data Governance Dev authored
把以下两个文件加入 .gitignore,避免 API Key / 主机信息泄露: - web/configs/llm.yaml 含 provider api_key - workflow/config.yaml 含 DB host / user(密码走 env var) 对应的模板文件仍纳入版本控制: - web/configs/llm.example.yaml - workflow/config.example.yaml Why:执行治理时本地会有真实凭据,复用项目时按模板复制即可。
-
Data Governance Dev authored
把 Phase 1 的 7 个独立脚本收敛成一条流水线: 工作流核心 workflow/ - run_governance.py:CLI 入口,支持 --db / --steps / --skip / --offline - config.example.yaml:阈值 / 数据库 / 输出配置(实际 config.yaml 不入库) - core/ db.py 连接与查询辅助 utils.py 配置加载、目录管理、JSON I/O reporter.py Markdown + Word 报告生成 - steps/ 8 个 Step 的实现(每个文件一个 Step) 8 步流水线: 1 数据字典 -> 2 合并/冗余(离线) -> 3 数据验证(连库) -> 4 空字段(连库) -> 5 缺注释(离线) -> 6 长度检查(离线) -> 7 国标校验(连库) -> 8 报告生成(离线) 国标插件 standards/ 独立可扩展 - base.py + registry.py 自动发现所有标准 - std_001_id_card.py GB 11643-1999 身份证 - std_002_uscc.py GB 32100-2015 统一社会信用代码 - std_003_mobile.py YD/T 1313 手机号 - std_004_xzqh.py GB/T 2260 行政区划代码 Why:脚本是一次性产物,工作流才是可复用的工程;分离国标后新增规范 只需要再写一个 std_xxx.py 文件。 How:每个 Step 是独立类,产出统一为 dict,run_governance.py 按编号串行 执行;国标通过字段名匹配自动加载,registry 提供全局发现。 -
Data Governance Dev authored
第一阶段,针对 smart-build 数据库做一次性手工治理: - fetch_data_dictionary.py:拉取 information_schema,输出 data_dictionary.json - check_empty_fields.py:逐表扫 NULL/空字符串比例,输出高空字段报告 - verify_merge_redundancy.py + .sql:连库验证合并候选的实际行数 - validate_standard_fields.py:对身份证/手机/统一社会信用代码等抽样校验 - check_field_length.py:识别 VARCHAR 超出固定长度的字段(基于国标) - check_uncommented_fields.py:扫描无注释字段,按字段名启发式推测 - generate_report.py:把以上 JSON 汇总成 Word 报告 Why:先把\"用什么工具看什么数据\"跑通,再抽象成可复用工作流。 How:每个脚本独立运行,输出落 JSON 到 data_dictionary/,最终由 generate_report.py 汇总成 数据治理报告_smart-build.docx。 -
Data Governance Dev authored
定义项目的核心目标与约束: - 只读分析 smart-build 数据库(MySQL),不修改任何数据 - 五个治理方向:可合并表/冗余字段、空字段、缺注释、固定长度字段、规范字段 - 已识别的国标:身份证、统一社会信用代码、手机号、地区编码 - 工作流分阶段沉淀:脚本 -> 工作流 -> Web 端 Why:后续所有治理脚本、工作流、Web 端都以本目标为准绳。 How:CLAUDE.md 描述目标;.gitignore 屏蔽运行产物(outputs/、JSON 输出、__pycache__、work-logs 等),保留源代码本身。
-