Sfoglia il codice sorgente

docs(kb): 90 路线按聚簇+DAG 重组;30 §4.5 占位规范;92 同步本批

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
tianyu.chu 2 settimane fa
parent
commit
8d0ac728c4
3 ha cambiato i file con 226 aggiunte e 29 eliminazioni
  1. 18 0
      kb/30-开发规范.md
  2. 201 25
      kb/90-重构路线.md
  3. 7 4
      kb/92-重构进度.md

+ 18 - 0
kb/30-开发规范.md

@@ -219,6 +219,24 @@ flowchart TD
 - `feat: xxx\nfix: yyy\ndocs: zzz` —— 一条 commit 混多个 type
 - `feat: 新增了一大堆表` —— scope 和具体目标不明
 
+### 4.5 占位模块规范
+
+新建 `dw_base/<module>/` 子目录(或 `tests/` 下子目录)时,即使本批**不写实现代码**,也必须带 `README.md`。避免"空 `__init__.py` + 无说明"的幽灵模块堆积(曾于 2026-04-20 清理 `ml/elasticsearch/flink/validation` 四个空壳)。
+
+**README.md 必含 4 节**:
+
+1. **职责** —— 一句话说清该模块做什么 / 不做什么(划边界,与相邻模块的区分)
+2. **对外接口概要** —— 规划中的公开 API(3-5 条 function/class 签名即可,不必最终稿;允许后续漂移)
+3. **依赖** —— 依赖的外部库 + 项目内模块 + 配置文件来源(含账密走 `datasource/` 的说明)
+4. **状态** —— `未启动 / 骨架 / 开发中 / 已交付`,以及当前 blocker 或待确认项
+
+**检查**:
+
+- 下次清理 round,只有空 `__init__.py` 且无 README 的目录 → 直接删(反模式判定)
+- README 与实际代码不符(接口漂移 / 状态陈旧 / 依赖过时)→ 开发者在本轮改动中顺手维护
+
+**示例参考**:`dw_base/io/README.md`、`dw_base/pm/README.md`、`dw_base/dq/README.md`、`dw_base/sync/README.md`、`dw_base/ops/README.md`、`tests/README.md`。
+
 ## 5. 测试规范
 
 见 `90-重构路线.md` §6。核心要点:

+ 201 - 25
kb/90-重构路线.md

@@ -3,7 +3,86 @@
 > 基于老项目 `tendata-warehouse-release` 的代码分析,为新项目 `poyee-data-warehouse` 规划的重构路线。
 > 本文档说"为什么改、怎么改";配套的 `92-重构进度.md` 说"改到哪一步了"。
 
-## 一、模块重命名(高优先级)
+## 〇、全景与依赖 DAG
+
+线性 P0-P3 排序不适合实际推进 —— 配置外移、模块重组、基础设施可以并行,而业务 SQL / 老代码删除强依赖它们。本节把全部任务按**聚簇**组织,按**依赖边**而非阶段号推进。
+
+### 聚簇划分
+
+| 聚簇 | 名称 | 范围 | 对应旧阶段 |
+|------|------|------|-----------|
+| **A** | 配置外移 / 硬编码清理 | `conf/env.sh` / `workers.ini` / `alerter.ini` / `spark-defaults.conf` / `datax-speed.ini` / datasource 多环境 / DataX 路径解耦 | 阶段 2 主体 |
+| **B** | `dw_base/` 重组 | B1 `__init__.py` 瘦身 · B2 `common/utils/io/ops` 四模块边界定稿 · B3 代码风格修正(`__contains__` / SQL 注入 / Shell-Python 重复) · B4 新占位模块 registry | 阶段 2 / 4 混合 |
+| **C** | `bin/` 入口收口 | `datax-import` / `datax-export` 两命令收口 · `datax-gc-generator` 从零重写 · `csv-to-hdfs-starter` 实现 · `publish.sh` 已入 `bin/` | 阶段 1 尾 + 阶段 2 |
+| **D** | 基础设施 | `tests/` 测试体系 · 告警模块重写 · 日志模块统一 · `dq/` 数据质量 · `sync/` Docmost · `pm/` 项目管理集成 | 阶段 2 / 4 |
+| **E** | 业务 SQL 从零开发 | `jobs/{raw,ods,dwd,dws,tdm,ads}/` · DS 工作流 | 阶段 3 |
+| **F** | 老代码删除 | `launch-pad/` 整删 · 其他已确认废弃 | 阶段 5 |
+
+### 依赖 DAG
+
+```
+          ┌───────────────┐
+          │ B1 __init__   │
+          │    瘦身       │
+          └───────┬───────┘
+                  ↓
+     ┌────────────┴────────────┐
+     ↓                         ↓
+┌──────────┐            ┌──────────────┐
+│ A2 spark │            │ B2 四模块    │
+│ defaults │            │    边界定稿  │
+└──────────┘            └──────┬───────┘
+                               ↓
+                     ┌─────────┴──────────┐
+                     ↓                    ↓
+              ┌──────────┐         ┌──────────┐
+              │ B4 新占位 │         │  C bin   │
+              │  (骨架)   │         │  收口    │
+              └──────────┘         └──────────┘
+
+A 其余项 ───────┐
+B3 风格修正 ────┤ 可独立推进,与上图并行
+D 基础设施 ─────┘
+
+       (A + B + C 基本就绪后)
+                 ↓
+              ┌────┐
+              │ E  │  业务 SQL 从零开发
+              └─┬──┘
+                ↓
+              ┌────┐
+              │ F  │  老代码删除
+              └────┘
+```
+
+**关键依赖边**(强依赖,不能翻转):
+
+- **B1 → A2**:`spark-defaults.conf` 路径解析依赖瘦身后的 `PROJECT_ROOT_PATH`,反过来做会踩返工
+- **B2 → B4**:四模块(`common/utils/io/ops`)边界不定,新占位模块放哪里都是赌博
+- **B2 → C**:`bin/` 两命令的底层实现要放 `dw_base/datax/entry.py`,属于四模块定稿后的延伸
+- **A + B + C → E**:业务 SQL 开工需要 conf 外配就绪 + dw_base 结构稳定 + bin 入口可用
+- **E → F**:`launch-pad/` 删除前置条件是新 `jobs/` 在生产跑稳
+
+**可并行的事**(无强依赖):
+
+- A 大部分子项(env.sh / workers.ini / alerter.ini / datax-speed.ini / datasource 多环境 / DataX 脚本路径解耦)彼此独立
+- B3 代码风格修正(`__contains__` / SQL 注入)与任何聚簇都不冲突
+- D 基础设施(tests 骨架 / dq / sync / pm)骨架已建,实现可滚动推进
+- **基础模块弄好后 E 就可并行开工**,不必等 F
+
+### 本文各节与聚簇的对应
+
+- §一 模块重命名 → **跨 B/F**(历史项,大部分已完成)
+- §二 消除硬编码 → **聚簇 A + 部分 C**
+- §三 `__init__.py` 瘦身 → **聚簇 B(B1)**
+- §四 代码风格修正 → **聚簇 B(B3)**
+- §五 清理废弃代码 → **聚簇 F**(目前已清零,留档案)
+- §六 测试体系 → **聚簇 D**
+- §七 其他建议 → **聚簇 D + A 杂项**
+
+---
+
+## 一、模块重命名(高优先级) [聚簇 B / F]
 
 ### 1.1 `tendata` → `dw_base`
 
@@ -31,7 +110,7 @@
 - `zip -qr launch-pad.zip launch-pad` 类命令(如有)→ 改为 `jobs`
 - DolphinScheduler 工作流里老路径的引用 → 新项目上线时一并替换
 
-## 二、消除硬编码(高优先级)
+## 二、消除硬编码(高优先级) [聚簇 A + 部分 C]
 
 ### 2.1 当前硬编码清单
 
@@ -41,7 +120,7 @@
 | `PYTHON3_PATH="/usr/bin/python3"` | `bin/common/init.sh` | 移入 `conf/env.sh` |
 | `RELEASE_USER="alvis"` | `bin/common/init.sh` | 改为 `RELEASE_USER="bigdata"` 并移入 `conf/env.sh` |
 | `RELEASE_ROOT_DIR="/home/alvis/release"` | `init.sh`、`__init__.py` | 改为 `/home/bigdata/release` 并移入 `conf/env.sh` |
-| 项目部署目录 `poyee-data-warehouse/` | `publish.sh` | 新项目发布目录为 `/home/bigdata/release/poyee-data-warehouse/` |
+| 项目部署目录 `poyee-data-warehouse/` | `bin/publish.sh`(2026-04-20 从根目录挪入 `bin/`) | 新项目发布目录为 `/home/bigdata/release/poyee-data-warehouse/` |
 | `DATAX_WORKERS=(m3 d1 d2 d3 d4)` + `DATAX_WORKERS_WEIGHTS` 权重 map | `init.sh:18-31`(含展开 `DATAX_WORKERS_QUEUE` 的循环) | workers 列表 + 权重 map **整体**移入 `conf/workers.ini`(ini 格式),`init.sh` 仅保留读取 + 展开逻辑 |
 | `HADOOP_CONF_DIR='/etc/hadoop/conf'` | `__init__.py` | 使用系统环境变量 |
 | `LOG_ROOT_DIR="/opt/data/log"` + whoami 分流 | `init.sh`、`__init__.py` | 删除 whoami 分支,单值改为 `${HOME}/log` 并迁入 `conf/env.sh`,见 §7.2.1 |
@@ -425,7 +504,42 @@ record_per_channel = 100000
 - 支持按 ini 名(业务表)在 conf 里覆盖特定任务的速率
 - 支持命令行 `-speed fast` / `-speed slow` 手动切档(突发高峰 / 限流时用)
 
-## 三、`__init__.py` 瘦身(高优先级)
+### 2.10 `dw_base/` 四模块边界(common / utils / io / ops) [聚簇 B(B2)]
+
+**背景**:老项目 `dw_base/` 下子目录职责混乱 —— `utils/` 里塞过 Excel/Hive 读写、小文件合并;`database/` 又和 `datax/datasources/` 重叠;缺少 I/O 边界和"数据湖运维"这类长期职责的收纳点。重组把全部非业务代码(非 `spark/` / `udf/` / `datax/` 等明确功能域)按**边界属性**归入四个顶层模块,规则如下:
+
+| 模块 | 边界属性 | 典型内容 | 反例(不该放在此处) |
+|------|---------|---------|---------------------|
+| **`common/`** | 常量 / 全局上下文 / 无行为的元数据 | 颜色常量、枚举、模板路径常量、项目级单例 context | 任何"动词"型函数 —— 那是 `utils/` |
+| **`utils/`** | 纯函数,无外部副作用,可纯 Python 单测 | 日期格式、字符串切分、配置解析、数据结构转换 | 读/写 DB / 文件 / HDFS —— 那是 `io/` |
+| **`io/`** | 与外部系统通信的**边界** | DB connector 薄封装、CSV/JSON/Excel 读写、HDFS 文件读写 | 数据湖维护动作(合并小文件、清理分区)—— 那是 `ops/` |
+| **`ops/`** | 数据湖维护动作,会改变湖里的物理状态 | 小文件合并、分区清理、统计信息刷新、存储压缩 | 一次性的业务查询脚本 —— 那走 `jobs/` 或 `manual/` |
+
+**落地规则**:
+
+1. **写新代码前先对号入座**:如果一个函数既读文件又做纯计算,按**最强副作用**归类(读文件 → `io/`,即便函数里 90% 是计算)
+2. **`io/` 只做薄封装**:不把业务 schema 嵌入 `io/`(老 `mongodb_utils.py` 把公司名查询嵌进去就是反例),业务 schema 留在调用方
+3. **`ops/` 里的函数预期被多处复用**:只被一张表调用一次的"清分区"走 `manual/adhoc/`,不进 `ops/`
+4. **跨模块依赖方向**:`ops/` 可依赖 `io/` + `utils/` + `common/`;`io/` 可依赖 `utils/` + `common/`;`utils/` 只依赖 `common/`;`common/` 不依赖任何项目内模块。**禁止反向依赖**
+
+**B2 先于 B4 / C**:新占位模块(io/ops/pm/dq/sync)和 `bin/` 收口都假设四模块边界已定;边界不定就先别新建骨架,否则返工成本高。
+
+### 2.11 新占位模块 registry(B4) [聚簇 B(B4)]
+
+2026-04-20 本批建立的占位模块(空骨架 + README,实现待后续阶段),登记在此便于跨会话追踪:
+
+| 模块 | 路径 | 状态 | 何时实现 | 对应阶段 |
+|------|------|------|----------|---------|
+| `io/` | `dw_base/io/{db,file,hdfs}/` | 骨架 | B2 四模块边界定稿后,搬入 `mysql_utils` + 文件读写 | 阶段 2 |
+| `ops/` | `dw_base/ops/` | 骨架 | 阶段 4 随"重新实现小文件合并 / 分区保留工具"落地 | 阶段 4 |
+| `pm/` | `dw_base/pm/` | 骨架 | 待确认 TAPD vs Jira 后实现(commit → 任务 ID 联动) | 阶段 4 之后 |
+| `dq/` | `dw_base/dq/` | 骨架 | 待确认告警落点 + 首批规则后实现 | 阶段 4 |
+| `sync/` | `dw_base/sync/` | 骨架 | 待确认 Docmost API 鉴权 / webhook 支持后实现 | 阶段 4 之后 |
+| `tests/` | `tests/{unit,integration}/` | 骨架 | 阶段 4 首批 UDF 单测启动时同步补 `conftest.py` + fixtures | 阶段 4 |
+
+**标准**:每个占位模块必须带 README,4 节(职责 / 接口 / 依赖 / 状态)—— 规则见 `kb/30-开发规范.md §4.5`。空 `__init__.py` + 无 README 直接删除,不保留"暂留"。
+
+## 三、`__init__.py` 瘦身(高优先级) [聚簇 B(B1)]
 
 **现状:** `tendata/__init__.py` 约 120 行,import 即执行以下操作:
 - 环境变量设置
@@ -451,7 +565,7 @@ PROJECT_NAME = ...
 # dw_base/core/spark_env.py —— findspark 初始化(按需 import)
 ```
 
-## 四、代码风格修正(中优先级)
+## 四、代码风格修正(中优先级) [聚簇 B(B3)]
 
 ### 4.1 `__contains__` 反模式
 
@@ -482,7 +596,7 @@ sql = "... WHERE TABLE_SCHEMA='%s' ..." % (database, table_name)
 
 **建议:** 改用参数化查询。
 
-## 五、清理废弃代码(中优先级)
+## 五、清理废弃代码(中优先级) [聚簇 F]
 
 截至 2026-04-20 本节已无待清理项。后续若发现新的废弃代码,在下方表格追加登记;已完成项保留在"历史档案"表中留档。
 
@@ -502,13 +616,14 @@ sql = "... WHERE TABLE_SCHEMA='%s' ..." % (database, table_name)
 
 > 代码里残留的 `conf/datax/config/` replace 死逻辑 + `conf/datax/generated` 默认值,属于 §2.x 路径硬编码清理范畴(改名为 `conf/datax-json/` + 删 replace),不在本节。
 
-## 六、测试体系搭建(中优先级)
+## 六、测试体系搭建(中优先级) [聚簇 D]
 
 ### 6.1 现状
 
 - 仅 UDF 有少量 pytest 测试
 - 核心模块(SparkSQL、DataX 配置生成)无测试
 - 无 CI/CD 集成
+- 2026-04-20 已建 `tests/{unit,integration}/` 骨架 + README(`.gitkeep` 占位,无实测用例),见 §2.11 占位模块 registry
 
 ### 6.2 建议的测试结构
 
@@ -536,7 +651,7 @@ tests/
 - **Spark 集成测试**:使用 `local[*]` + 内存 Hive(`enableHiveSupport()` 需要 Hive MetaStore,可用嵌入式 Derby)
 - **数据质量**:在 DolphinScheduler 工作流中加入校验节点
 
-## 七、其他建议
+## 七、其他建议 [聚簇 D + A 杂项]
 
 ### 7.1 依赖管理(已精简)
 
@@ -626,20 +741,81 @@ else:
 
 **后续处理**:若 HMS 未挂 Ranger Hive,调研补挂成本 + 评估现有 HDFS 兜底是否足够(大部分数仓读写场景下足够,因为 PySpark 任务绝大多数以受控 Unix 账号提交、权限粒度粗即可;若要满足敏感列屏蔽类需求则必须补挂)。
 
-## 八、重构优先级排序
-
-| 阶段 | 任务 | 优先级 |
-|------|------|--------|
-| P0 | 模块重命名 tendata→dw_base、launch-pad→jobs | 高 |
-| P0 | 清理所有业务代码(launch-pad 中保留的样本) | 高 |
-| P1 | 硬编码提取到 conf/ | 高 |
-| P1 | `__init__.py` 瘦身,拆分初始化逻辑 | 高 |
-| P1 | 敏感信息(Webhook token 等)移出代码 | 高 |
-| P2 | `__contains__` → `in` 全局替换 | 中 |
-| P2 | 删除废弃空模块和注释代码 | 中 |
-| P2 | 搭建 tests/ 基础框架 + UDF 单测 | 中 |
-| P2 | 精简 requirements.txt | 中 |
-| P3 | 日志模块统一 | 低 |
-| P3 | SQL 注入修复 | 低 |
-| P3 | 部署脚本改进 | 低 |
-| P3 | Spark/HMS 侧 Ranger Hive 策略验证(见 §7.5) | 低 |
+## 八、聚簇推进视图
+
+替换原 P0-P3 线性优先级表。按聚簇 A-F 组织(定义见 §〇),同一聚簇内部不强排序,跨聚簇只标强依赖。
+
+### A 配置外移 / 硬编码清理
+
+| 子项 | 状态 | 依赖 | 参见 |
+|------|------|------|------|
+| `conf/env.sh`(LOG_ROOT_DIR / RELEASE_USER / RELEASE_ROOT_DIR / PYTHON3_PATH / DATAX_HOME) | 待启动 | — | §2.1 / §7.2.1 |
+| `conf/workers.ini`(DataX Workers + 权重 map 外移) | 待启动 | — | §2.1 |
+| `conf/alerter.ini`(告警 Webhook,入库) | 待启动 | 旧告警代码删除(已 2026-04-20 完成) | §2.1 |
+| `conf/spark-defaults.conf`(Spark 全局默认参数,Spark 原生 flat 格式) | 待启动 | **B1 `__init__.py` 瘦身** | §2.3 |
+| `conf/datax-speed.ini`(DataX 分时速率) | 待启动 | — | §2.9 |
+| `datasource/{db_type}/{env}/{instance}.ini` 多环境分层 | 待启动 | — | §2.5 |
+| DataX 脚本去前缀剥离 + 加 `-env` 参数 | 待启动 | datasource 多环境 | §2.5 |
+| JSON 输出目录改名 `conf/datax-json/` | 待启动 | — | §2.1 |
+
+### B `dw_base/` 重组
+
+| 子项 | 状态 | 依赖 | 参见 |
+|------|------|------|------|
+| **B1** `__init__.py` 瘦身 + `PROJECT_ROOT_PATH` 稳定下来 | 待启动 | — | §三 |
+| **B2** `common/utils/io/ops` 四模块边界定稿 | 待启动 | — | §2.10 |
+| **B3** `__contains__` → `in` 全局替换 | 待启动 | — | §4.1 |
+| **B3** Shell/Python 环境检测去重(`bin/common/init.sh` ↔ `dw_base/__init__.py`) | 待启动 | B1 | §4.2 |
+| **B3** `mysql_utils.py` SQL 注入修复 | 待启动 | —(该文件在 §2.7 `datax-gc-generator` 重写时一并重造,可能被废) | §4.3 |
+| **B4** 新占位模块 `io/` / `ops/` / `pm/` / `dq/` / `sync/` 骨架 + README | ✅ 2026-04-20 已建 | B2 边界规则先立 §2.10 | §2.11 |
+
+### C `bin/` 入口收口
+
+| 子项 | 状态 | 依赖 | 参见 |
+|------|------|------|------|
+| `bin/publish.sh`(从项目根挪入) | ✅ 2026-04-20 完成 | — | §2.1 行 |
+| `bin/excel_to_hive.py` 删除(有需求重做) | ✅ 2026-04-20 完成 | — | changelog |
+| `bin/csv-to-hdfs-starter.py` 实现 | 待启动 | A 大部分就绪 | kb/00 §9 模板 |
+| `bin/datax-import` + `bin/datax-export` 两命令收口 | 待启动 | **B2** 四模块边界 / A datax 路径解耦 | §2.6 |
+| `bin/datax-gc-generator.py` 从零重写 | 待启动 | datasource 多环境就绪 | §2.7 |
+
+### D 基础设施
+
+| 子项 | 状态 | 依赖 | 参见 |
+|------|------|------|------|
+| `tests/{unit,integration}/` 骨架 + README | ✅ 2026-04-20 完成 | — | §2.11 / §六 |
+| `tests/unit/udf/test_spark_common_udf.py` 首批单测 | 待启动 | tests 骨架 + `conftest.py` | §六 |
+| DataX 配置生成单测 | 待启动 | — | §六 |
+| 告警模块重写(弃钉钉 → `conf/alerter.ini`) | 待启动 | `conf/alerter.ini` | §2.1 / 阶段 4 |
+| 日志模块统一(Python `logging` 双输出 / `log_path` 工具) | 待启动 | `conf/env.sh` LOG_ROOT_DIR | §7.2 / §7.2.1 |
+| Hive HDFS 小文件合并工具重新实现 | 待启动 | **B2** → `ops/` | 阶段 4 |
+| 分区保留工具重新实现(元表驱动 + 参数化) | 待启动 | **B2** → `ops/` | 阶段 4 |
+| `dq/` 数据质量规则首批 + runner | 待启动 | `conf/alerter.ini` 就绪 | §2.11 |
+| `pm/` TAPD / Jira 集成(commit → 任务 ID) | 待启动 | 确认平台选型 | §2.11 |
+| `sync/` Docmost → `kb/inbox/` | 待启动 | Docmost API 鉴权确认 | §2.11 |
+| Ranger Hive 策略验证(集群侧) | 待启动 | — | §7.5 |
+
+### E 业务 SQL 从零开发(阶段 3)
+
+见 `kb/92-重构进度.md` 阶段 3 checklist。前置:A + B + C 基本就绪。
+
+### F 老代码删除(阶段 5)
+
+见 `kb/92-重构进度.md` 阶段 5 checklist。前置:E 在生产稳定一个完整周期。
+
+### 当前推进建议
+
+**本阶段可并行开工**(无前置阻塞):
+
+1. A 大部分子项(env.sh / workers.ini / alerter.ini / datax-speed.ini)
+2. B1 `__init__.py` 瘦身(解锁 A2 spark-defaults.conf)
+3. B2 四模块边界定稿(只需写决策,不改代码)
+4. B3 代码风格修正(`__contains__` 全替换)
+5. D 首批 UDF 单测(tests 骨架已建)
+
+**等待前置**:
+
+- A2 spark-defaults.conf ← B1
+- C `bin/` 两命令 / `datax-gc-generator` 重写 ← B2 + A datax
+- D `ops/` 下两个工具 ← B2
+- E 业务 SQL ← A + B + C 基本就绪

+ 7 - 4
kb/92-重构进度.md

@@ -5,16 +5,18 @@
 
 ## 总览
 
+**推进组织方式**:2026-04-20 起 kb/90-重构路线.md 改为聚簇 + DAG 视图(A 配置外移 / B dw_base 重组 / C bin 收口 / D 基础设施 / E 业务 SQL / F 老代码删除),阶段号保留作为历史分期,**实际推进按聚簇**;见 kb/90 §〇 + §八。本 checklist 下方的阶段分节仍保留,便于按阶段对账。
+
 | 阶段 | 状态 | 开始日期 | 完成日期 |
 |------|------|---------|---------|
 | 阶段 0:知识库梳理 | ✅ 已完成 | —  | 2026-04-14 |
-| 阶段 1:P0 骨架重命名 | ⬜ 未开始 | — | — |
-| 阶段 2:P1 硬编码外置 | ⬜ 未开始 | — | — |
+| 阶段 1:P0 骨架重命名 | 🟡 推进中 | 2026-04-15 | — |
+| 阶段 2:P1 硬编码外置 | 🟡 部分提前完成(B4 骨架 / bin/publish.sh / excel_to_hive 删) | 2026-04-20 | — |
 | 阶段 3:业务 SQL 从零开发 | ⬜ 未开始 | — | — |
-| 阶段 4:测试体系 + 废弃代码清理 | ⬜ 未开始 | — | — |
+| 阶段 4:测试体系 + 废弃代码清理 | 🟡 tests 骨架已建 / requirements 精简已完成 | 2026-04-15 | — |
 | 阶段 5:老项目残留删除 | ⬜ 未开始 | — | — |
 
-当前所处阶段:**阶段 0 完成,阶段 1 待启动**。
+当前所处阶段:**主线阶段 1(P0 骨架)推进中;阶段 2 / 4 部分先导项随聚簇 B4 提前完成**。
 
 ---
 
@@ -165,3 +167,4 @@
 | 2026-04-20 | **删除 `dw_base/database/mongodb_utils.py` + kb/90 §5.1 档案化改造**:(a) `mongodb_utils.py` 184 行真实内容仅 `MongoDBHandler` 薄类 19 行(吃 url/port/user/pwd 拼 URI 实例化 MongoClient),其余 165 行全是公司名→Mongo/ES 查询 + TF-IDF 关键词抽取 + 三段老集群 `dds-m5e*` 连接串注释。grep 零外部引用。新项目若需连 Mongo 一行 `MongoClient(uri)` 即可,薄包装无保留价值。(b) §5.1 原表两行实际状态:`mongodb_utils.py` = 本次删除;`conf/datax/` 下老项目遗留 ini/datasource = 项目初始化 `8d2ade5` 时已整体挪入 `conf/bak/datax/{config,datasource}/` 并由 `.gitignore:6 conf/bak` 拦截,早已完成但没画勾。(c) §5.1 改造为"待清理表(当前为空)+ 历史档案表(完成项留档)"双表结构,空壳模块 4 行 + 本次 mongodb_utils + conf/datax 挪 bak 三项入档案。尾注说明:代码里残留的 `conf/datax/config/` replace 死逻辑 + `conf/datax/generated` 默认值属于 §2.x 路径硬编码清理(改名 `conf/datax-json/`),不在本节范围 | — |
 | 2026-04-20 | **alerter + datax-speed 扩展名统一为 `.ini` + alerter 口径统一为"入库"**:(a) `conf/alerter.conf` → `conf/alerter.ini` + 从 gitignore 改为入库;反转 2026-04-15 changelog(line 139)当时记的 `.conf` + gitignore 口径。理由:项目 conf/ 全部 ini + 代码侧 `configparser` 使用 10+ 次 + `PyYAML` 在 requirements 但零 `import yaml`(躺尸依赖)→ ini 是事实标准;webhook key 低敏(最多被拿去发垃圾消息,非账密级)+ 部署靠 git pull,gitignore 会让 bigdata / DolphinScheduler 拉不到配置。结构:`[common] url_prefix` + `[channels] ba/dcp/etl/skb/realtime = <key>`。(b) `conf/datax-speed.conf` → `conf/datax-speed.ini`,同一口径收敛,消除 `.conf/.ini` 混用。同步点:kb/00 §6 sparkconfig 表告警 Webhook 行(gitignore 列 `是` → `否`)、kb/90 §2.1 硬编码表 alerter 行 / §2.4 目录树 / §2.9 整节 4 处、kb/92 阶段 2 checklist 4 处(line 62 去掉"敏感文件"措辞、line 66 改为入库、line 78 钉钉条删除合并入 line 79、line 91 扩展名改)、记忆 `project_templates_and_config` 去掉"kb/92 一致性提醒"段(已消除)。**未改动**:2026-04-15 changelog line 139(历史快照保留)、2026-04-18 changelog line 153(历史快照保留)、`workers.conf` 扩展名 + kb/90 §2.1 里"ini 或 yaml 格式"未定的表述(不在本批范围,用户后续拍板) | — |
 | 2026-04-20 | **DS 残留清理 + workers / spark-defaults 扩展名收敛**:(a) DS 残留:`dw_base/ds/` 目录在 `f20d9c3` 就随老业务批被删,但前瞻 kb 未同步 —— 本次清 `kb/00-项目架构.md:42` 目录树 `ds/` 行 + `:122` Mermaid 节点 `DS_API` + `:169` Mermaid 边 `DS_API --> DS` + `kb/90-重构路线.md:70-72` 目标态目录树 `ds/` 子树 3 行。(b) `conf/workers.conf` → `conf/workers.ini`(kb/90 §2.1 硬编码表 + §2.4 目录树 + kb/92 checklist 2 处),并把 §2.1 里"ini 或 yaml 格式"的未决表述锁死为"ini 格式"—— 与本项目 Python 读配置统一走 configparser 的约定一致(见上一条 alerter 口径)。(c) `conf/spark-defaults.yaml` → `conf/spark-defaults.conf`(**Spark 原生 flat `spark.x.y  value` 格式,非 ini**):反转中途一度采纳的"全部配置 `.ini` 统一"结论,理由是该文件是 `$SPARK_HOME/conf/spark-defaults.conf` 的克隆(运维熟悉、与 `spark-submit --properties-file` 原生兼容、代码侧零映射转换、无 section 前缀/key 拼接 tax)。§2.3 草案块从 `[executor]/[driver]/[sql]/[default]` section + configparser + `spark.{section}.{key}` 拼接的写法,整段改写为 flat key-value;`_load_default_config()` 从 configparser 改为 10 行手写解析器。同步点:kb/90 §2.1 硬编码表 + §2.3 整节(草案 + 代码要点 + 两个落地坑 4 处引用)+ §2.4 目录树、kb/00 §6 配置分类表 + §6.2 三级覆盖图 + §6.2 说明段(启动加载方式从 "configparser" 改为 "Spark 原生 key value")、kb/92 checklist 2 处、记忆 `project_templates_and_config` 扩展名约定段追加 spark-defaults.conf 例外说明。**未改动**:2026-04-15 changelog line 134(`conf/spark-defaults.yaml` 历史快照保留)。**路线外变更同步入册原则**:DS 目录删除在 `f20d9c3` 未同步 kb 前瞻文档,属于此前"默默做完"漏记,本次补 | — |
+| 2026-04-20 | **dw_base 占位模块骨架 + tests 骨架 + bin 收口(B4 提前 + C 起步)**:(a) 新建 5 个占位模块 `dw_base/io/{db,file,hdfs}/` + `dw_base/ops/` + `dw_base/pm/` + `dw_base/dq/` + `dw_base/sync/`,每个带 `__init__.py` + `README.md`(4 节:职责/接口/依赖/状态);实现留待后续阶段。(b) `tests/{unit,integration}/` 骨架 + `tests/README.md` + `.gitkeep`;首批单测目标 `tests/unit/udf/test_spark_common_udf.py`(40 函数)。(c) `bin/excel_to_hive.py` 删除(一次性工具,有需求重做);`publish.sh` 从项目根 `git mv` 到 `bin/publish.sh`(publish 是 DS 调度入口 = 和 bin 同类)。代码侧单次 commit `6936460`。(d) 文档侧同步:`kb/30-开发规范.md §4.5 占位模块规范`(4 节标准 + "空 __init__.py 无 README → 删"铁律);`kb/90-重构路线.md` 按聚簇 + DAG 重组(新增 §〇 全景与 DAG、§2.10 common/utils/io/ops 四模块律、§2.11 新占位 registry、§六.1 tests 骨架标注、§八 从 P0-P3 线性表替换为聚簇 A-F 推进视图;所有主章节加 `[聚簇 X]` 标签;§2.1 publish.sh 行改为 `bin/publish.sh`);本文档总览引入聚簇视图说明 + 阶段 1/2/4 状态改"推进中 / 部分提前完成" | — |