# 观澜 · 源代码模块化重构方案 v0.1(2026-09-22) > **本文用途**:给开发团队做**源代码组织层面**的重构依据。本次**只重构目录与接口**(用户令 2026-09-22): > 暂不引入 TiDB / MinIO / Redis / Nginx,只在存储、缓存、网关三处留好**接入点**。 > **兼容底线:零行为变化、逐版本可回滚** —— 页面、CLI、产物、审计门、交付包的产出一律不变, > 每阶段独立提交、跑通全部门禁才推进,出问题按提交回退。 --- ## 1 为什么这样分(按"变化的原因"切,而不是按技术层切) 观澜现在有两处"变化速率完全不同"的东西混在一起: - **业务逻辑**(判级口径、曲线镜头、可靠性指标、融合判据)—— 变化快,且**跨风电场/机型必须能替换与扩展**; - **运行与交付**(服务、网关、重算编排、审计门、打包安装)—— 变化慢,但**一堆硬约束**(离线单包、无外网、可移植、版本纪律)。 把它们分层,才能做到"改算法不动服务、换存储不动算法"。所以按**六个业务模块 + 一个公共层**切: | 模块目录 | 中文职责 | 变化原因 | 关键约束 | |---|---|---|---| | `app_common/` | 公共层:路径真源、版本真源、日志、进程、入口引用、控制台输出 | 极少变 | 只被依赖,不依赖任何业务模块 | | `app_ETL/` | 数据接入管理:摄入、体检与落位、标准仓、契约与词典 | 随现场数据形态变 | 源件只读;缺族如实标注;列名绑定 | | `app_algorithmModel/` | 算法:判级矩阵、七镜头曲线、可靠性、融合面、振动与温度面、趋势 | **最快** | 纯函数优先;输入是标准仓,输出是判定;不得直接读原始件 | | `app_ontology/` | 本体与知识层:对象库、机制链、检索、SOP 与验收状态机、模型闸 | 中 | 只读复用;不写业务产物 | | `app_backEnd/` | 后端:组件服务、网关、运维控制台、重算编排、CLI | 慢 | 端口/入口/日志口径统一;不缓存产物口径 | | `app_frontEnd/` | 前端:页面与交互、图表、静态件与门户 | 中 | 只读接口;不内嵌业务判据 | | `app_qualityGate/` | 质量门与审计 + 打包安装:审计器、门禁、打包器、安装/卸载 | 慢 | 门禁必须能独立重跑、逐条给退出码 | **依赖方向(单向,无环)**: `app_frontEnd → app_backEnd → {app_algorithmModel, app_ontology, app_ETL} → app_common`; `app_qualityGate` 只读依赖全部模块(审计者不参与业务调用链)。 ## 2 目录结构(每个模块一个目录) 用户令给的前端示例照此推广——模块根下 `common/` 放**跨模块可复用的公共组件**,`app_<模块>_guanlan/` 放**观澜在该模块的实现**: ``` app_common/ |__common/ |__app_common_guanlan/ [观澜公共层:paths/version/logfile/proc/entry_refs/console/opsjob/derived_manifest/tabfmt] |____init__.py |__api.py ← 对外公开面(其他模块只许从这里 import) |__README.md app_ETL/ |__common/ |__app_ETL_guanlan/ [数据接入管理] app_algorithmModel/ |__common/ |__app_algorithmModel_guanlan/ [算法] app_ontology/ |__common/ |__app_ontology_guanlan/ [本体与知识层] app_backEnd/ |__common/ |__app_backEnd_guanlan/ [后端] app_frontEnd/ |__common/ |__app_frontEnd_guanlan/ [前端] app_qualityGate/ |__common/ |__app_qualityGate_guanlan/ [质量门与审计 + 打包安装] ``` **边界规则(机器可查,见 `scripts/module_boundary_audit.py`)**: 1. 跨模块调用**只许**经由对方的 `api.py`;模块内部实现不得被别的模块直接 import。 2. 依赖方向不得反向、不得成环(按 `configs/modules.yaml` 的 `allow` 判定)。 3. 每个模块必须有 `README.md`(职责/公开面/依赖/迁移进度)与 `api.py`。 4. 公共层 `app_common` 不得依赖任何业务模块(否则公共层变成"上帝模块")。 ## 3 现有代码 → 目标模块(映射表) > 阶段 0(本轮)**只建骨架与接口**,下面的文件**原地不动**;各模块 `api.py` 现在转发到既有实现, > 保证"接口先立、行为不变"。后续阶段逐个 `git mv` 到目标目录,并在**旧路径留转发壳**。 | 目标模块 | 迁移来源(现有路径) | 现有规模 | |---|---|---| | `app_common` | `src/{paths,version,logfile,proc,entry_refs,console,opsjob,derived_manifest,tabfmt}.py`、`configs/registry.yaml`(配置登记) | 9 文件 / 1,683 行 | | `app_ETL` | `src/windscada/{data,scada_source,slim,mdb_names}.py`、`scripts/{rebuild_from_raw,rebuild_all,scada_slim_build,windscada_monthly_build,vib_raw_build,raw_scan,raw_data_check,place_raw_data,pitch_face_build,baseline_38_build,component_history_build,csv_to_mdb}.py`、`configs/{canonical,contracts,farms}` | 约 30 文件 | | `app_algorithmModel` | `src/windscada/{taxonomy,audit}.py`、`src/windscada/perf/*`、`src/windscada/subsys/*`、`src/windcms/{report_std,tcm,knowledge,cross_review,audit_rules,pipeline}.py` | 约 40 文件 / 2 万行 | | `app_ontology` | `src/ontology/*`、`src/sop/*` → `ontology/`、`sop/` 两个子包(旧路径全部留兼容壳) | 58 模块 / 19,775 行 | | `app_backEnd` | `guanlan.py`、`scripts/{windscada_serve,guanlan_gateway,guanlan_ops,_ops_launch,_ops_run,_ops_stop_keep_gateway,service_ctl,guanlan_start_hidden}.py`、`src/windscada/{config,terms,i18n,lang,report_export}.py`、`src/windcms/{serve,orchestrator,llm,agent}.py` | 约 20 文件 | | `app_frontEnd` | `src/windscada/ui/{app.js,app.css,charts.js,favicon.svg,shell.html,build.py,snapshot.py}`、`src/windscada/{design,lang,terms}.py`、`windscada_serve.py` 内的页面模板(CHART_JS/PAGE_*,约 246 KB)、`scripts/{portal_build,guanlan_portal_fix_anchors,guanlan_portal_inject_claims}.py` | 13 件 / 约 3,300 行 + 246 KB 模板 | | `app_qualityGate` | `scripts/{*_audit,check_*,detail_deps,page_fingerprint,pack_dist,pack_verify_entry,guanlan_uninstall,delivery_docs_build,delivery_docs_figures}.py` → `audits/`、`docs/`、`pack/` 三个子包(旧路径留 CLI 壳;**根引导脚本 install.*/uninstall.*/check.bat/pack.* 按"解压即用"约定原地不动**) | 23 件 / 7,426 行 | ## 4 分阶段迁移(每阶段一个提交,随时可回退) | 阶段 | 内容 | 验收(全绿才进下一阶段) | 回滚 | |---|---|---|---| | **P0(本轮)** | 建 7 个模块目录 + `common//{__init__,api}.py` + README;`configs/modules.yaml` 登记;新增 `scripts/module_boundary_audit.py` 并接入 `guanlan.py check` | 边界审计 rc=0;`guanlan.py check` 全绿;三份交付文档重渲通过 | 删目录即可 | | **P1(已完成 2026-09-22)** | `app_common` 平台件**实体迁移**,`src/<同名>.py` 变转发壳 | 旧路径可导入 + 安装根正确 + 全部门禁 rc=0 | revert 该提交 | | P2 | `app_ETL` 迁移(构建器按 CLI 入口迁,`scripts/` 留转发) | 重算链 `--dry-run` 计划不变 + 全门禁 | 同上 | | P3 | `app_algorithmModel` 迁移(判级/曲线/可靠性/融合纯函数化) | 判级与曲线**逐值对拍**(同一时间窗结果一致)+ 全门禁 | 同上 | | **P4(已完成 2026-09-22)** | `app_backEnd` 迁移(21 文件 / 10,482 行;服务、网关、编排、CLI、配置与语言件) | 服务起停 + 六条路由全 200 + 全门禁 + 开箱验证 | revert 该提交 | | **P5(已完成 2026-09-28)** | `app_frontEnd` 迁移(资源件 / 页面装配 / 经典页模板 / 设计系统 / 文案语言包 / 门户装配器,13 件) | 模板与出页逐字节对拍 + 服务重启后逐页 sha256 一致 + 全门禁 | revert 该提交 | | **P6(已完成 2026-09-28)** | `app_ontology` 迁移(本体 20 件 + SOP 38 件,58 模块 / 19,775 行) | 58/58 新旧路径同体导入 + 10 条本体/SOP 路由响应体逐字节对拍 + `-m` 旧入口冒烟 + 全门禁 | revert 该提交 | | **P7(已完成 2026-09-28)** | `app_qualityGate` 迁移(审计 17 + 文档 3 + 打包/卸载 3 = 23 件 / 7,426 行) | 8 条门 stdout 逐字节对拍 + 23 个 CLI 壳 importlib 同面 + 打包开箱 5/5 + 卸载核验 + 全门禁 | revert 该提交 | **旧路径转发壳约定**(保证兼容性):迁移后旧路径保留一个薄文件,例如 `src/paths.py` → `from app_common.app_common_guanlan.paths import * # 兼容转发,勿新增逻辑`。 这样 `scripts/**`、审计器、文档里的既有引用**不需要一次性改完**,可以按阶段收敛。 ## 5 为四个系统组件留的接入点(本轮只留接口,不接实现) | 组件 | 接入点(本轮建立的边界) | 后续替换方式 | |---|---|---| | **TiDB community** | `app_ETL` 的"标准仓读写"接口(现为 parquet 仓):表↔仓的映射与事务边界在**接口层**确定 | 新增 TiDB 实现,配置切换;算法层不变 | | **MinIO** | `app_ETL` 的"源件与产物对象存储"接口(现为本地目录):以对象键替代绝对路径 | 新增 MinIO 实现;`app_common` 的路径真源继续提供逻辑键 | | **Redis** | `app_backEnd` 的"按时间窗缓存与任务状态"接口(现为进程内 `_WIN_CACHE` 与 `run/ops_job.json`) | 新增 Redis 实现,支持多实例共享与分布式锁 | | **Nginx** | `app_backEnd` 的"统一入口/静态件"接口(现为 Python 网关 `guanlan_gateway.py`) | Nginx 反代 + 静态托管,网关退化为路由表 | **约束**:上表四项都是"可插拔实现",**默认实现仍是本地/进程内**,因此离线单包交付形态与现有验收链不变。 ## 6 与既有纪律的关系(不得破的底线) - 版本纪律:本重构按**中版本**升位(源码组织层重构,运行形态与核心功能未变),`src/version.py` 单点真源; - 审计纪绿:`guanlan.py check`、反向呼应、页面归口、配置统一、链缺口、可移植性、文档三检**必须保持全绿**; - 交付纪律:交付包默认不含输入数据/产物/日志;`install.ps1`/`uninstall.*` 行为不变; - 文档纪律:三份交付文档(需求分析 / 系统设计说明 / 数据要求说明)随版本号改名并重渲,内容口径不变。 ## 7 当前进度(2026-09-22) - **P0 已完成**:7 个模块目录、接口与 README、`configs/modules.yaml`、`scripts/module_boundary_audit.py`(接入 `guanlan.py check`)。 - **P1 已完成(2026-09-22)**:公共层 9 个平台件(paths/version/logfile/proc/entry_refs/console/opsjob/derived_manifest/tabfmt)实体迁入 `app_common/app_common_guanlan/`;安装根推算改为按标记查找;旧路径留兼容转发壳;实测旧路径三种导入写法照旧、安装根正确、全部门禁 rc=0。 - **P2 已完成(2026-09-22)**:数据接入管理迁入 `app_ETL/app_ETL_guanlan/`(data/scada_source/slim/mdb_names)与 `builders/`(rebuild_from_raw、rebuild_all、scada_slim_build、windscada_monthly_build、vib_raw_build、raw_scan、raw_data_check、place_raw_data、pitch_face_build、baseline_38_build、component_history_build、csv_to_mdb);`scripts/<同名>.py` 留 CLI 壳;12/12 构建器可导入,`raw_scan --check`、`scada_slim_build --check`、`rebuild_all --dry-run` 全部 rc=0,全门禁绿。 - **P3 已完成(2026-09-22)**:算法层迁入 `app_algorithmModel/app_algorithmModel_guanlan/`(taxonomy、audit、perf/*、subsys/*、windcms 随迁 6 件);判级/曲线/可靠性/M9/四轴/限电/故障/趋势/功率曲线逐值对拍一致(见上);全门禁绿。 - **P4 已完成(2026-09-22)**:后端层迁入 `app_backEnd/app_backEnd_guanlan/`;入口(根 `guanlan.py`、`scripts/<9 件>`)与旧库路径留壳;服务起停与六条路由实测全通;全门禁绿。 - **P5 已完成(2026-09-28)**:前端层迁入 `app_frontEnd/app_frontEnd_guanlan/`(`assets/`、`pages/`、`design.py`、`lang.py`、`terms.py`、`builders/`);旧路径留壳;`serve.py` 的经典页模板抽出(值逐字节一致,行数 5549 → 2707);逐页渲染与重启后页面 sha256 对拍一致;全门禁绿。 - **P6 已完成(2026-09-28)**:本体与 SOP 层 58 个模块迁入 `app_ontology/app_ontology_guanlan/{ontology,sop}/`;旧路径全部留壳(含 `python -m src.ontology.<件>` 入口);10 条本体/SOP 路由响应体与迁移前逐字节一致;全门禁绿。 - **P7 已完成(2026-09-28)**:23 个质量门/打包/卸载工具迁入 `app_qualityGate/app_qualityGate_guanlan/{audits,docs,pack}/`;旧路径留 CLI 壳,根引导脚本不动;8 条门 stdout 与迁移前逐字节一致;打包器从新位置出包并开箱验证 5/5 + 卸载核验;全门禁绿。 - **P0–P7 全部完成**:七个模块(公共/数据接入/算法/本体/前端/后端/质量门)各一个目录、各一个 `api.py` 公开面、旧路径全部留兼容壳;逐阶段独立提交、随时可 revert。 - **待裁**:英文投影层(`ui_en/i18n_en/data_tpl_en/en_text`,后端数据层英文投影在用)的模块归口。 ## 8 P9:源码目录结构变更(2026-09-28 用户令,已完成) 用户令:`app_frontEnd/`、`app_backEnd/`、`app_algorithmModel/`、`app_ETL/` 四个目录下,严格按 `common`(通用插件/组件)· `configs`(配置)· `data`(数据)· `app_<模块>_guanlan`(实现)+ `README.MD` + `install/uninstall/run` 脚本组织;并确保打包、安装、运行正常;之后清理无用源代码与目录。 | 项 | 内容 | |---|---| | 包上提 | `app_<模块>/common/app_<模块>_guanlan/` → `app_<模块>/app_<模块>_guanlan/`(7 个模块) | | 引用改写 | 点号 540 处 + 实路径 190 处(`src/**` 壳、`scripts/**` 壳、`api.py`、安装器、打包器、门禁、文档) | | 兼容别名 | `common/app_<模块>_guanlan/__init__.py` 前缀重定向(同名同体),保留一个版本 | | 配置双根 | 模块专属域下放(app_ETL: canonical/contracts/farms;app_frontEnd: terms);取用口多根 + 单源校验;登记表加 owner | | 每模块新增 | `common/README.md`、`configs/README.md`、`data/README.md`、`README.MD`、`install/uninstall/run`(bat+sh) | | 门禁联动 | R1/R2/R5 结构判定改新布局(并修 `_TARGETS` 带注解写法漏检);入口闭合纳入 42 个模块脚本(92 条) | | 验收 | 189 模块文件新旧前缀同体导入 · 全门禁 rc=0 · 起服务逐页(`/detail/v2` 仅页内注释路径变化)· 打包开箱 5/5 + 卸载核验 | ## 9 P10:算法服务化(Python + FastAPI,2026-09-29 用户令) 用户令给出目标栈(前端 Vue/TS/Node · 后端 Java+SpringCloudAlibaba+SpringBoot+Swagger+MyBatis-Plus · 算法 Python+FastAPI),本期只做**算法**一步: | 项 | 内容 | |---|---| | 实现位置 | `app_algorithmModel/app_algorithmModel_guanlan/service/{app,registry,jsonable,deps}.py` | | 入口 | `python scripts/algorithm_service.py --port 18050`(端口登记 `configs/serve.json` 的 `algorithm`) | | 端点 | 11 个只读端点 + `/healthz` + `/api/endpoints` + `/api/{名}/raw`(对拍) + `/docs`·`/openapi.json` | | 只读保证 | 登记表里把写盘参数固定为只读值(如 `curves.write=False`) | | 离线依赖 | FastAPI 运行栈随包 `vendor/pyfastapi/`(15.9 MB)+ `deps.ensure_fastapi()` 兜底 | | 验收 | 逐值对拍:HTTP 与进程内直调 JSON 逐字节一致(11 端点 + 3 带参抽查,2026-09-29 实测全过) | | 零行为变化 | 不改进程内调用链;页面/CLI/产物不变 |