92-重构进度.md 45 KB

重构进度

本文档追踪 poyee-data-warehouse 重构任务的执行状态。每次完成一项,在对应 checkbox 打勾并写入完成日期。 与 90-重构路线.md 配套使用:90 说"为什么改、怎么改",92 说"改到哪一步了"。

总览

推进组织方式: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 骨架重命名 🟡 推进中 2026-04-15
阶段 2:P1 硬编码外置 🟡 部分提前完成(B4 骨架 / bin/publish.sh / excel_to_hive 删) 2026-04-20
阶段 3:业务 SQL 从零开发 ⬜ 未开始
阶段 4:测试体系 + 废弃代码清理 🟡 tests 骨架已建 / requirements 精简已完成 2026-04-15
阶段 5:老项目残留删除 ⬜ 未开始

当前所处阶段:主线阶段 1(P0 骨架)推进中;阶段 2 / 4 部分先导项随聚簇 B4 提前完成


阶段 0:知识库梳理 ✅

  • 项目架构文档 00-项目架构.md
  • 运行环境 01-运行环境.md
  • 权限与账号 02-权限与账号.md
  • 业务流程 10-业务流程.md
  • 数据资产 11-数据资产.md
  • 数仓分层与建模 20-数仓分层与建模.md
  • 命名规范 21-命名规范.md
  • 指标体系 22-指标体系.md
  • 标签体系 23-标签体系.md
  • 开发规范 30-开发规范.md
  • 重构路线 90-重构路线.md
  • 项目根 CLAUDE.md 指向 kb

阶段 1:P0 骨架重命名

目标:让新项目结构立起来,老项目代码可以正常运行不受影响。

  • tendata/ 目录改名为 dw_base/(2026-04-15)
  • 全局替换 from tendata / import tendatafrom dw_base / import dw_base(2026-04-15,102 个文件)
  • 全局替换 SQL 中的 ADD FILE tendata/...ADD FILE dw_base/...(2026-04-15)
  • 全局替换 zip -qr tendata.zip tendatazip -qr dw_base.zip dw_base(2026-04-15,spark_sql.py f-string 形式已手工修正)
  • 全局替换 addPyFile('tendata.zip')addPyFile('dw_base.zip')(2026-04-15,publish.sh 同步更新)
  • 全局替换路径正则 re.sub(r"tendata-warehouse.*", ...) → 使用新项目名(绑定仓库改名;2026-04-20 三批老业务清理后残留进一步缩小到 dw_base/utils/ 剩余文件、bin/doris-*-starter.py 等;diff_utils.py / polling_scheduler.py / drop_*.py / spark/udf/customs/* 的字符串字面量已随删除一并清零)
  • 排查 tendata_corp 等数据库名/表名引用,确认不要误替换(2026-04-15,已确认保留:tendata_corptendata_bigdata256!ent_tendata_interfaceapi.tendata.cn
  • 新建 jobs/ 目录 + jobs/{raw,ods,dim,dwd,dws,tdm,ads}/ 子目录(2026-04-15,已放 .gitkeepdim/ 为顶层独立分层)
  • 新建 manual/ 目录 + 5 个子目录(ddl/backfill/fix/adhoc/archive/)(2026-04-15,已放 .gitkeepmanual/ddl/ 是所有 DDL 的唯一来源)
  • 项目仓库改名 tendata-warehouse-releasepoyee-data-warehouse同步改名 .idea/tendata-warehouse-release.iml.idea/poyee-data-warehouse.iml 并更新 .idea/modules.xml 引用)
  • 更新 publish.sh 中的部署路径与项目名
  • 实现 bin/csv-to-hdfs-starter.py:本地 CSV → gzip(可选,大文件才压缩)→ hdfs dfs -put 到暂存区 → 调用 SparkSQL 执行 jobs/raw/{域}/{表}.sql(含 USING csv 临时视图 + INSERT OVERWRITE)→ 清理暂存。任务定义采用 SQL 格式(参见 00-项目架构.md §9.3 模板)
  • 验证:在测试集群跑一次 bin/spark-sql-starter.py 样例,import 和 Spark 环境初始化能过
  • 验证:在测试集群跑一次 bin/datax-single-job-starter.sh 样例,ini→json 生成能过
  • 验证:bin/csv-to-hdfs-starter.py 用一个样例 CSV 跑通 raw 层入仓

完成判定:老项目 launch-pad 下的某个样例作业,在改名后的 dw_base/ 基础上能跑通(import 和运行不报错)。

阶段 2:P1 硬编码外置

目标:消除对老环境(alvis 用户、/home/alvis/release 路径、硬编码的 worker 列表)的代码耦合。

  • 新建项目根 .gitignore(清单与注意事项见 90-重构路线.md §2.4)
  • 建立 conf/env.sh(Shell 环境变量)
  • 建立 conf/env.py 或 Python 读 env.sh 的桥接
  • 建立 conf/workers.ini(DataX Worker 列表 + 权重 map,整体迁出 bin/common/init.sh:18-31
  • 建立 conf/alerter.ini(企微 Webhook,入库;格式见 90-重构路线.md §2.1)
  • dw_base/__init__.py 瘦身(拆分初始化逻辑,见 90-重构路线.md §3)— 必须先做,下面 spark-defaults 依赖瘦身后的 PROJECT_ROOT_PATH
  • 建立 conf/spark-defaults.conf(Spark 全局默认参数,Spark 原生格式,见 90-重构路线.md §2.3)
  • 改造 dw_base/spark/spark_sql.py:构造函数 fall back 到 conf;实现 L1(conf) < L2(SQL 内 SET,仅 spark.sql.* 系生效) < L3(命令行 -sc / 构造函数传参) 三级覆盖
  • 验证:同一条 SQL 在无 SET、有 SET、命令行 -sc 三种场景下 spark.conf.get(...) 返回值符合优先级预期
  • 验证:SET spark.executor.memory=Xg 不会影响已启动 executor(文档里说清楚这条限制)
  • RELEASE_USER="alvis"RELEASE_USER="bigdata" 并迁入 conf/env.sh
  • RELEASE_ROOT_DIR="/home/alvis/release"/home/bigdata/release 并迁入 conf/env.sh
  • DATAX_WORKERS=(m3 d1 d2 d3 d4) + 权重 map 迁入 conf/workers.ini
  • 删除 whoami == RELEASE_USER 分流,LOG_ROOT_DIR 单值 ${HOME}/log 放入 conf/env.sh(见 90-重构路线.md §7.2.1)
  • 日志路径统一模板 ${LOG_ROOT_DIR}/{module}/{dt}/{file}.log(3 层)
  • 实现 log_path(module, dt, file) 工具函数(Python / Shell 各一份,单一来源)
  • 企微 Webhook Key 从 alerter_constants.py 移入 conf/alerter.ini(钉钉已于 2026-04-20 全部删除,不再迁移)
  • DataX 入口收口为两条命令(暂称 datax-import / datax-export命名待确认;见 90-重构路线.md §2.6)
  • 导入命令实现分区管理(-skip-exist / -force-overwrite / -skip-partitions
  • 导出命令实现源 HDFS 路径探测(-src-check / -skip-missing
  • bin/datax-gc-generator.py 从零重写:定位为参考模板生成器from=pg to=hdfs,输出到开发者本地 workspace/{yyyymmdd}/{name}.ini,该目录被 .gitignore 排除、不入仓;开发者裁剪后把成品提交到 jobs/raw/{domain}/),不再生成 DDL(见 90-重构路线.md §2.7)
  • .gitignore 增加 workspace/ 行(见 90-重构路线.md §2.4 清单)
  • 废弃并删除 mysql_utils/MySQLDataSource/MySQLReader.generate_hive_ddl*/convert_mysql_column_types(见 §2.7 拆除清单)
  • HDFS HA 自检(前置决策):2026-04-18 新 CDH 环境实测:HADOOP_CONF_DIR 未设 + /opt/datax 无预置 hdfs-site.xml;手动 export HADOOP_CONF_DIR=/etc/hadoop/conf 后跑 DataX 仍 UnknownHostException: nameservice1。结论:HADOOP_CONF_DIR 对 DataX 无效(datax.py 不把 conf 目录入 classpath),锁定走 Path B
  • 改造 HDFSDataSource:覆写 get_datasource_dict()[hadoop_config] 整节作为 dict 塞进 ds_dict['hadoopConfig'](2026-04-18)
  • 清理 dw_base/__init__.py:16 死代码 os.environ['HADOOP_CONF_DIR'](2026-04-18,实测对 DataX JVM 无影响)
  • HDFS 数据源 ini 新建:按新 schema 运维补齐 datasource/hdfs/{env}/*.ini(prod 带 [hadoop_config];dev/test 只写 [base] defaultFS
  • HA 回归测试:真实 HA 集群 + 单 NN 集群 + 主备切换三场景
  • DataX 速率配置外移conf/datax-speed.ini 定义分时速率档;dw_base/datax/job_config_generator.py:60-67 硬编码替换为读 conf(见 90-重构路线.md §2.9)
  • 新建 manual/imports/ + manual/exports/ 目录(按日期 {yyyymmdd}/ 组织一次性任务)

阶段 3:业务 SQL 从零开发

目标:按新分层架构填充 jobs/ 下的真实业务 SQL,与老 launch-pad/ 零关联。

  • 梳理首批待入仓业务表(按 11-数据资产.md
  • jobs/raw/ 首批 DataX ini(按业务域分目录)
  • jobs/ods/ 首批贴源 SQL
  • jobs/dwd/ 首批明细 SQL
  • jobs/dws/ 首批汇总 SQL
  • jobs/tdm/ 首批主题模型 SQL
  • jobs/ads/ 首批应用层 SQL + 导出 ini
  • 在 DolphinScheduler 中配置工作流,贯通新链路

阶段 4:测试体系 + 废弃代码清理

  • 建立 tests/ 目录骨架(见 90-重构路线.md §6)
  • UDF 单测首批
  • DataX 配置生成单测
  • __contains__in 全局替换
  • 删除废弃空模块和注释代码
  • 重新实现 Hive HDFS 小文件合并工具:原 dw_base/utils/hive_file_merge.py(2026-04-20 随老业务批清理一并删除)提供 alter table ... partition (...) concatenate 压实能力,但硬编码了老 HiveServer 连接 / cts_*_ex/_im 表名规则 / mirror_country 过滤。新版需通用化:HiveServer 连接从 conf/ 读取、表过滤参数化,剥离业务命名假设
  • 重写告警模块:老钉钉告警文件(dingtalk_* / ent_interface_dingtalk* / country_count_dingtalk / spark_parse_json_to_hive 里的 dingtalk() / bin/dingtalk-work-alert.sh)已于 2026-04-20 全部删除;新项目不再使用钉钉,Webhook Key 走 conf/alerter.ini(见 90-重构路线.md §2.1
  • 重新实现分区保留工具:老 dw_base/scheduler/drop_partitions.py + drop_daily_full_snapshot_tbls.py(2026-04-20 删除)提供"按表清理超期分区,保留最近 N 天 + 例外 dt"能力。前者硬编码海关 cts_{mgdb}_{catalog} 表名 + mg_count_monitor 元表,后者元表驱动(daily_full_snapshot_tblsdb/tbl/days)模式更通用。新版采用元表驱动 + 保留天数参数化 + 例外 dt 白名单,不绑业务表名;新目录可能不叫 scheduler(按 N 天清分区不是调度职责,更像 ops/maintenance/
  • Spark / HMS 侧 Ranger Hive 策略验证(低优先级,见 90-重构路线.md §7.5)
  • 精简 requirements.txt(2026-04-15 提前完成:48 行 → 10 个强依赖,老清单备份到 requirements.txt.bak 并逐行打标)

阶段 5:老项目残留删除

前置条件:阶段 3 的业务 SQL 在生产稳定运行至少一个完整周期,且 DS 工作流已完全切换到 jobs/

  • 确认 DS 工作流已无对 launch-pad/ 的引用
  • 删除 launch-pad/ 整个目录
  • 删除其他已确认废弃的老文件

变更记录

日期 变更 操作人
2026-04-14 初始化进度文档,阶段 0 知识库梳理完成
2026-04-15 90-重构建议.md 更名 90-重构路线.md;新增 his 快照 + dim 顶层分层;manual/ddl/ 作为 DDL 唯一来源(migration 模式);精简 requirements.txt(提前完成阶段 4 一项);新增 Spark 配置三级覆盖路线(L1 conf/spark-defaults.yaml / L2 SQL SET / L3 命令行 -sc,阶段 2 任务)
2026-04-15 阶段 1 模块重命名:tendata/dw_base/(目录 + 102 个文件的 import / SQL ADD FILE / zip 打包 / addPyFile / publish.sh);跳过项:tendata-warehouse 正则(待仓库改名)、tendata_corp 等业务库名、ent_tendata_interface topic、api.tendata.cn URL
2026-04-15 阶段 1 目录骨架:新建 jobs/{raw,ods,dim,dwd,dws,tdm,ads}/manual/{ddl,backfill,fix,adhoc,archive}/,均放 .gitkeep 占位
2026-04-15 sql_style.xml 从项目根移入 kb/30-开发规范.md §4.2 补 IDE 格式化导入说明、关键风格表与"不对齐 AS"理由
2026-04-15 新增 .gitignore 计划(90-重构路线.md §2.4 + 阶段 2 checklist),含 .idea/ / .claude/ 部分 ignore 策略、dw_base.zip 构建产物、conf/alerter.conf 敏感项;阶段 1 仓库改名 checklist 追记 .iml 同步改名
2026-04-18 sql_style.xmlkb/ 移入 conf/(IDE 配置不算文档);同步更新 kb/README.md 索引、kb/30-开发规范.md §4.2.1 路径引用、移除 kb/90-重构路线.md §5.1 对应待办行
2026-04-18 kb 文档整理:zhu_tianyutianyu.chu00-项目架构.md 2 处负责人注释);kb/inbox/ 4 份草稿整合完毕 —— 标签服务演进路线.md23-标签体系.md §6 100% 重复直接删除;dwd明细粒度设计原则.md 并入 20-数仓分层与建模.md §5.5;hive数据类型映射.md 并入 20-数仓分层与建模.md §8.4(ES→Hive 占位待补);业务库同步方案.md 独立成文为 kb/12-同步方案.md 并入 README 索引
2026-04-18 02-权限与账号.md §1 补齐 PySpark 鉴权路线(链路 B):Unix 账号身份 + Ranger UserSync 同时同步 LDAP / Unix group;HS2 doAs 仅链路 A 生效;补漏编号 1 并新增"身份(Who)"条目
2026-04-18 架构框图重排:01-运行环境.md §1 大数据平台全景、20-数仓分层与建模.md §2 分层 × 维度侧柱、00-项目架构.md §5 分层架构图 —— 统一"单层单行 + 右侧 DIM 侧柱"样式,按"中文字符宽 2 / ASCII 宽 1"严格对齐;同步修复三文档数据流 ASCII 尾巴的 orphan 和空行
2026-04-18 02-权限与账号.md §2 Mermaid 时序图补齐链路 B(PySpark → HMS + Ranger Hive Plugin → NameNode + Ranger HDFS Plugin → HDFS,身份=Unix 账号,无 doAs)
2026-04-18 反转两条决策:(a) manual/ddl/ 目录组织从"扁平存放"→ 按 {layer}/{domain}/ 分子目录;(b) jobs/{layer}/{domain}/ 下 SQL 从"一张目标表一个 .sql"→ 简单表仍单文件,多步表{表名}/{表名}-{NN}-{描述}.sql 子目录(99 为最终 insert),区分"可复用中间结果应升层"和"单目标加速 tmp 表"两种语义;同步更新 00-项目架构.md §9.1/§9.2/§9.5 文件命名速查表
2026-04-18 90-重构路线.md 新增 §2.6 DataX 入口收口为 datax-import + datax-export、§2.7 datax-gc-generator 从零重写(仅 PG→HDFS,不再生成 DDL)、§2.8 HDFS defaultFS 统一 nameservice;§2.1 workers 行追记"权重 map 一起迁";§7.2.1 反转"删除 whoami 分流"→"保留分流 + 目的地改为 {module}/{dt}/{file}.log"
2026-04-18 manual/ 新增两个子目录语义:manual/imports/{yyyymmdd}/(一次性入仓)+ manual/exports/{yyyymmdd}/(一次性出仓),同步更新 00-项目架构.md §1 目录树 / §9 manual/ 用途表 / §9.5 文件命名速查
2026-04-18 修正 90-重构路线.md §2.8 关于 HDFS nameservice 的表述:代码侧零特殊处理(dw_base/datax/datasources/hdfs_data_source.py:8,21 只把 defaultFS 当不透明字符串透传),nameservice 解析完全靠 DataX worker 节点的 Hadoop 客户端 + hdfs-site.xml;仓库内无 HADOOP_CONF_DIR export
2026-04-18 90-重构路线.md §2.7 改写 datax-gc-generator 定位为参考模板生成器(不是"一键出可用 ini"),产物落 manual/imports/{yyyymmdd}/ 供开发者按需裁剪字段 / 加 WHERE / 调分区;§2.6 datax-import / datax-export 名称标注"命名待确认"
2026-04-18 30-开发规范.md 新增 §4.4 Git 提交信息(Conventional Commits):type 白名单(feat/fix/docs/refactor/perf/test/chore/style/build/ci/revert)、scope 约定({层}/{域} 或模块名)、标题 ≤ 50 字符、破坏性变更 ! + BREAKING CHANGE: 正文约定
2026-04-18 新增 workspace/ 概念:开发者本地草稿区(datax-gc-generator 输出的参考模板 / 临时 SQL 调试),被 .gitignore 排除、永不入仓。同步更新 90-重构路线.md §2.4 .gitignore 清单增加 workspace/ 行、§2.7 datax-gc-generator 输出目的地从 manual/imports/ 改为 workspace/{yyyymmdd}/{name}.ini;并明确 workspace/ vs manual/imports/ 分工
2026-04-18 修正 §2.8:原"把 defaultFS 换 nameservice 就算支持 HA"是错的;DataX HA 必须在 json 里同时提供 defaultFS + hadoopConfig 块(否则无法把 nameservice 解析为具体 NameNode)。ini schema 升级:新增 ha_enabled + [hadoop_config] 节,key 照搬 hdfs-site.xmlHDFSDataSource 需覆写 get_datasource_dict()reader/writer 两侧代码不用改(靠 load_data_source() 自动注入)
2026-04-18 新增 §2.9:DataX 速率控制从 job_config_generator.py:60-67 的分时硬编码(0750-1900 走 10ch×10MB、其它走 6ch×256MB)外移到 conf/datax-speed.conf,按时间段分档;默认值保持向后兼容;在 conf 头注释里补"白天避开业务高峰"的动机
2026-04-18 排查"运维写死 nameservice"实现:全仓 grep HADOOP_OPTS / -Dfs. / 自定义 hdfs-site.xml 写入等全部零命中;现存 conf/bak/.../hdfs-*.ini 只有 defaultFS 一行。仓库零实现。
2026-04-18 修正早先文档误述:dw_base/__init__.py:16 实际上有 os.environ['HADOOP_CONF_DIR'] = '/etc/hadoop/conf'(原 2026-04-18 changelog 早条说"仓库内无 HADOOP_CONF_DIR export"不准确)
2026-04-18 §2.8 改造降级为"条件触发"(第三轮修正):用户提供老项目真实生产 json 样例显示只写 defaultFS(无 hadoopConfig)也能跑 HA —— 说明老 worker 节点 hdfs-site.xml 配置完整,hadoopConfig可选覆盖而非 HA 必要条件。前两轮论断("必须加 hadoopConfig"、"运维把 xml 写死单 NN")都被推翻。§2.8 加"新环境 HDFS HA 自检清单"(echo $HADOOP_CONF_DIR / grep xml HA keys / hadoop fs -ls hdfs://nameservice1/),三项全过则整节改造不做;仅任何一项失败才启动 ini schema 升级 + HDFSDataSource 改造。92 阶段 2 checklist 相应改为"自检前置 + 条件触发"4 条子项
2026-04-18 §2.8 锁定 Path B(第四轮,实测决定):新 CDH 环境三连实测(json 含/不含 hadoopConfig × HADOOP_CONF_DIR 设/不设),结论:对 DataX JVM,仅 json 的 hadoopConfig 块有效,HADOOP_CONF_DIR 无效(datax.py 不把 conf 目录入 classpath,与 hadoop 命令行不同)。老项目能纯 defaultFS 跑通最可能是老运维把 hdfs-site.xml 塞进了 DataX classpath 目录,新环境 /opt/datax 没这类预置文件。改造要点:(a) HDFSDataSource.get_datasource_dict()[hadoop_config] 整节注入 hadoopConfig;(b) 删除 dw_base/__init__.py:16 os.environ['HADOOP_CONF_DIR'] 死代码。简化 §2.8 文本:去掉 ha_enabled 开关(用 [hadoop_config] 节存在性代替)、去掉自检决策树(已决定)、去掉"运维手工改 IP"误记
2026-04-20 §7.2.1 再次反转:删除 whoami == RELEASE_USER 分流,LOG_ROOT_DIR 改为单值默认 ${HOME}/log 并保留在 conf/env.sh(外配后期可改)。理由:$HOME 天然按用户隔离(bigdata/个人用户家目录不同),代码判断是多余一层;bigdata 本身就是专属调度账号,其 $HOME 即是生产日志合法归宿,不需要系统级 /opt/data/log 那条路。同步更新 90-重构路线.md §7.2.1(核心段)+ §2.1 硬编码表行 + §2.4 env.sh 草稿 + 00-项目架构.md §6 部署段 + 92 阶段 2 checklist
2026-04-20 老业务耦合代码第二批清理(重构计划外):在 UDF/模块独立化讨论中顺带盘点 dw_base/ 子模块,决定 16 文件批量删除:整目录删 3 个——oss/(oss2_util.py + init,新业务不需要对象存储)、scheduler/(polling_scheduler / drop_partitions / drop_daily_full_snapshot_tbls 三业务文件,前者绑死老 Mongo 轮询、后两者按 N 天清分区的能力已在阶段 4 记录重写任务)、hive/(hive_utils + hive_constants;hive_utils 中 get_hive_create_table_ddl* 零引用 + 依赖 COLUMN_NAME_COMMENT_DICT 老业务字段字典、DDL 生成器整体不重建;get_hive_database_name / get_hive_table_prefix 两个命名约定函数语义已在 kb/21-命名规范.md 有规则,不重建代码,后续 bin/datax-gc-generator.py 从零重写时按新约定实现);utils/ 删 7 文件——data_distinct / diff_utils / excel_to_hive_utils / hive_diff_database / hive_to_excel_utils / pdt_check_table / pdt_check_table_multis,全部零外部引用 + 强业务耦合(硬编码 tendata 路径 / 老集群 IP 192.168.30.3 / 中文表名拼音转换 / 海关 cts_* 表名模式)。连带效应bin/datax-gc-generator.py:26 import hive_utils 成破损 import,由 90-路线 §2.7 "从零重写" 任务覆盖,不单独修复。阶段 4 新增任务:重新实现分区保留工具(元表驱动 + 参数化天数,目录可能不叫 scheduler)。CLAUDE.md 规则追加:"空模块直接删"原则首次执行延后(elasticsearch/flink/ml/validation/common/ 暂留,后续更细粒度规整)
2026-04-20 老业务耦合代码批量清理(重构计划外):排查 tendata 残留时发现一批与 tendata_corp / ent_tendata_interface / DolphinScheduler / 钉钉告警强耦合的存量文件,逐项核对后批量删除 40 个文件 + 精简 1 个:老业务模块 34dw_base/scheduler/get_oldmongo_* ×5、dingtalk_* / ent_interface_dingtalk* / country_count_dingtalk / mg_company_alias_init ×8、mg2es/ 整目录 13 文件;dw_base/ds/ 整目录 4 文件;dw_base/spark/udf/spark_read_hive_columns_cnt.pydw_base/utils/tid_utils.pydw_base/spark/td_spark_init.py(老同事 xunxu 所写未被调用);bin/hive-exec.sh),级联清理 6dw_base/spark/udf/spark_id_generate_udf.py + dw_base/spark/udf/enterprise/unique/spark_tid_match_udf.py 依赖已删 tid_utilsdw_base/utils/hive_file_merge.py + dw_base/utils/spark_parse_json_to_hive.py 依赖已删 mg2es/钉钉告警;bin/hive-exec-job-starter.py 调用已删 hive-exec.shbin/dingtalk-work-alert.sh),精简 1dw_base/spark/udf/spark_mmq_udf.py 从 530 行裁到 4 个数据类型转换函数(phone/domain/website/statname 等场景相关 UDF 与 Mongo 相关逻辑全删)。同步更新:00-项目架构.md(移除 td_spark_init / DS 相关条目)、90-重构路线.md(钉钉 + 企微 Webhook 合并表述、删除 DS API 行、§5.2 依赖清理清单标记提前完成)、92-进度.md 阶段 1 第 6 行 re.sub checklist 更新残留范围(~15 处)。阶段 4 新增两项任务:(1) 重新实现 Hive HDFS 小文件合并工具(通用化连接 / 剥离 cts_*_ex/_im 表名假设);(2) 重写告警模块(弃钉钉走 conf/alerter.ini Webhook)
2026-04-20 pyspark 入 requirements.txt(反转 2026-04-15 "不写进" 决策):实际开发流程是 PyCharm SSH 到服务器用 bigdata 用户的 Python 解释器,该解释器 site-packages 只有 findspark==2.0.1,真正的 pyspark 在 CDH $SPARK_HOME/python/ 下不被索引 → PyCharm 静态索引红线 + 本地 pytest 失败。解法:pyspark==2.4.0requirements.txt(版本对齐 CDH 6.3.2 parcel 自带 Spark 2.4.0,见 requirements.txt.bak:45 + kb/01-运行环境.md:64);运行时仍靠 findspark.init() 指向集群 $SPARK_HOME/python/,同版本双轨不冲突。同步 kb/90-重构路线.md §7.1 KEEP 行放回 pyspark + 末句机制改写
2026-04-20 UDF 提升为顶层模块(重构计划外)dw_base/spark/udf/dw_base/udf/。动机:UDF 是独立能力域(后续会高频扩展、需本地单测),不应锁死在 spark/ 子树里。联动:dw_base/__init__.py:27 常量、bin/spark-sql-starter.py + bin/excel_to_hive.py 文件头 SQL 样例注释、dw_base/udf/common/spark_common_udf.py 模块 docstring、kb/00-项目架构.md(目录树新增 udf/ 行 + 模块职责表 + Mermaid 节点)、kb/23-标签体系.md §5 bitmap UDF 注册路径。bin/spark-sql-starter.py:172-173 用的是常量自动生效
2026-04-20 修正 §7.1 pyspark 误记:前期文档把 pyspark 列进强依赖 KEEP 行 + "pyspark 2.4.0 固定" 一句,均与真实的 requirements.txt 不符。真实机制:findspark==2.0.1 运行时定位 CDH 集群已装 PySpark,版本随集群走,客户端不固定也不入 requirements.txt。kb/90 §7.1 表格 KEEP 列去 pyspark + "后续事项"末行改为 findspark 机制说明
2026-04-20 UDF 模块重组(重构计划外):独立 dw_base/spark/udf/ 目录结构为 common/(通用 UDF,SparkSQL 入口自动 ADD FILE 注册)+ business/(业务专用 UDF,SQL 中按需 ADD FILE 加载)两类。(a) 6 份源文件(根 spark_common_udf.py 24 函数 + spark_json_array_udf.py 23 函数 + spark_mmq_udf.py 3 函数 + customs/cts_common.py + product/escape_udf.py + enterprise/spark_eng_ent_json_array_append_udf.py)通读 + 去重 + 业务耦合剥离后,合并为单文件 common/spark_common_udf.py(500 行 40 函数,分 JSON / Array / String / Numeric-Date-Hash / Cross-type-converters 5 段)。单文件方案而非按类型拆分,理由:跨类型转换函数(json2str / arr2json / str2map 等约 9 个,占 20%+)没有明确归属,强行分只会制造边界争议。(b) 清理 dw_base/spark/udf/ 下所有老业务 UDF 子目录与根级业务文件共 60 个:整目录删 contacts/ / customs/ / enterprise/ / product/ / productApplication/ / test/;根目录删 spark_eng_ent_name_clean.py / spark_india_format_phone_udf.py / solr_similar_match_udf.py / main_test.py 以及 3 份源 UDF 文件。(c) dw_base/__init__.py:27 COMMON_SPARK_UDF_FILE 常量路径由 dw_base/spark/udf/spark_common_udf.py 改为 dw_base/spark/udf/common/spark_common_udf.pybin/spark-sql-starter.py:172-173 两处 usage 靠常量传递自动生效)。(d) 删除老 dingtalk_* / mg2es 级联清理中没赶上的 UDF 业务耦合文件在此批统一清零。business/ 目录暂为骨架,后续真正出现新业务 UDF 时按需补
2026-04-20 删除空壳模块 ml/ / elasticsearch/ / flink/ / validation/(反转 2026-04-20 早先"暂留"记录):4 个目录下均只有 56 字节空 __init__.py,零 import / 零内容,保留无意义;2026-04-20 UDF 模块重组 changelog 末尾"暂留"一句是误记。git rm -r 一批清零。同步 kb/90-重构路线.md §5.1 从废弃代码表中移除这 4 行并加指向本条 changelog 的尾注。dw_base/common/alerter_constants.py / config_constants.py / container.py / template_constants.py 非空保留,不在本批
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.confconf/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.confconf/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.confconf/workers.ini(kb/90 §2.1 硬编码表 + §2.4 目录树 + kb/92 checklist 2 处),并把 §2.1 里"ini 或 yaml 格式"的未决表述锁死为"ini 格式"—— 与本项目 Python 读配置统一走 configparser 的约定一致(见上一条 alerter 口径)。(c) conf/spark-defaults.yamlconf/spark-defaults.confSpark 原生 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 DATAX_HOME 条件赋值 + 默认值对齐新环境(§2.1 最小铺垫)bin/common/init.sh:17DATAX_HOME="/opt/module/datax" 改为 DATAX_HOME="${DATAX_HOME:-/opt/datax}"。触发:dim_calendar 测试同步在服务器上报 /opt/module/datax/bin/datax.py 不存在,实际新 CDH 环境 DataX 装在 /opt/datax。两步改动:(a) 默认值从 tendata 时代的 /opt/module/datax 更正为新项目真实路径 /opt/datax,(b) 改为 ${VAR:-default} 条件赋值,允许 shell 环境 override(未来多机器部署路径不一致时零代码改动)。未做:§2.1 完整外配到 conf/env.sh 仍待推进。同步更新 kb/90-重构路线.md §2.1 表格对应行的当前值与备注
2026-04-20 恢复 dw_base/__init__.pyHIVE_CONF_DIR export(反转 2026-04-18 第四轮决策的另一部分;应随 HADOOP_CONF_DIR 恢复时一起做而遗漏,本次补)spark-sql-starter.py 启动通过 HADOOP_CONF_DIR 校验后,查 test.dim_calendar_dw2Table or view not found,同一张表在 Hive CLI describe 正常。根因:.enableHiveSupport() 没找到 hive-site.xml 会静默回落 in-memory metastore,看不到 HMS 真实库表。和 HADOOP_CONF_DIR 是同一批 2026-04-18 被误删的 env export,属同类 bug。整改:(a) 取消 dw_base/__init__.py:19 HIVE_CONF_DIR 的注释;(b) kb/90 §2.8 "老 env 设置"段重写合并 HADOOP_CONF_DIR / HIVE_CONF_DIR 两条说明 + 代码改造清单附表行合并;(c) 教训同步入记忆 feedback_act_not_flatter.md 的触发面扩到"修同类问题时邻域扫一遍"
2026-04-20 删除 geo_hash UDF + pygeohash 依赖(重构计划外)spark-sql-starter.py 在新 CDH 环境启动时报 ModuleNotFoundError: No module named 'pygeohash'dw_base/udf/common/spark_common_udf.py:19 import pygeohash)。根因:2026-04-20 UDF 重组(kb/92:165)把 geo_hash(lat, lng, precision) 保留进 common/(auto-load),但 pygeohash 在 kb/90 §7.1 还标 LAZY 且注释"只被即将清理的老业务代码引用"—— UDF 进 common 后该分类失效。当前阶段业务 SQL 尚未开始,geo_hash 零现成消费者;真需要 geo 分析再从老项目 copy + 放 business/。整改:(a) 删 spark_common_udf.py:19 import pygeohash + :375-376 def geo_hash(...);(b) kb/90 §7.1 LAZY 行的 pygeohash 移除(仓库零引用,不需要 LAZY 档)
2026-04-20 kb/00 目录树同步真实状态 + §2/§3 收敛dw_base/ 实际子目录已变(2026-04-20 删 scheduler/ / hive/,新建占位 io/ / ops/ / dq/ / pm/ / sync/),kb/00 §1 目录树仍停留在旧态;§2 核心模块职责表 + §3 Mermaid 均与 §1 同一信息三视图重复。整改:(a) §1 目录树同步真实子目录,职责并入每行行尾注释;顺带补漏 publish.sh 已挪入 bin/6936460)+ 新增 tests/ 条目 + conf/ 注释更新为"非敏感入库"口径;(b) §2 表删除,替换为一行"职责已并入 §1"指引;(c) §3 Mermaid 删除,保留标题 + 一行"待基础模块实装后重绘"说明。保留 §2/§3 heading 保证节号稳定,外部引用(kb/90 §4.3/§5/§6.4/§9、kb/30 §8/§9.6)零更新
2026-04-20 恢复 dw_base/__init__.py:16HADOOP_CONF_DIR export(反转 2026-04-18 第四轮决策的一小部分)spark-sql-starter.py -f workspace/20260420/select_dim_calendar_dw2.sql 在新 CDH 环境报 When running with master 'yarn' either HADOOP_CONF_DIR or YARN_CONF_DIR must be set —— Spark on YARN 启动时 SparkSubmitArguments.validateSubmitArguments 强校验该 env;bigdata 账号 shell 里未 export。2026-04-18 第四轮决策(kb/92:158)把这行当"死代码"删,判断只基于 DataX JVM(DataX 确实不靠它,HA 走 ini [hadoop_config] 注入),忽略了同一 dw_base/__init__.py 也是 Spark 入口的 bootstrap。本次恢复:os.environ['HADOOP_CONF_DIR'] = '/etc/hadoop/conf' 加回,注释更新为"Spark 需要;DataX 不读 classpath"。同步更新 kb/90 §2.8 末尾"死代码"段(重写为"仅对 Spark 生效")+ §2.8 代码改造清单附表对应行(从"删除"改为"保留",给出双路径理由)。DataX 侧结论(ini [hadoop_config] 注入 HA、HADOOP_CONF_DIR 对 DataX JVM 无效)不受影响
2026-04-20 SPARK_CONF_DIR env 兜底 + 回退 HIVE_CONF_DIR 伪修复 + 删 HDP 残留注释:昨日恢复 HIVE_CONF_DIR 后冒烟测试仍报 Table or view not found,说明 HIVE_CONF_DIR 不是真正触发点。对比老项目 tendata-warehouse-release/tendata/__init__.py 发现老代码同样把 HIVE_CONF_DIR 注释掉(反证此前上一条 changelog 的"伪修复"),且同样没有 SPARK_CONF_DIR。真正差异在环境:新 CDH 用 pip 安装的 pyspark 其 SPARK_CONF_DIR 默认指向自身空 conf/,不会加载集群 /etc/spark/conf/hive-site.xml.enableHiveSupport() 静默回落 in-memory metastore。整改:(a) dw_base/__init__.py os.environ.setdefault('SPARK_CONF_DIR', '/etc/spark/conf')(用 setdefault 允许 shell 侧 export 覆盖),同时把 HIVE_CONF_DIR 重新注释掉,并删除历史遗留行 # os.environ['SPARK_HOME'] = '/usr/hdp/3.1.5.0-152/spark2'(过期 HDP 路径 + 本就是注释,无保留价值);多行 comment 合并为单行;(b) kb/01-运行环境.md 新增 §4 Spark 运行时环境变量(HADOOP_CONF_DIR / SPARK_CONF_DIR 表);(c) kb/90-重构路线.md §2.8 代码改造清单附表行回退 —— 从"保留 HADOOP_CONF_DIR + HIVE_CONF_DIR"改为"保留 HADOOP_CONF_DIR + 新增 SPARK_CONF_DIR.setdefault",附详情指向 01 §4;(d) kb/90 §7.1 findspark 加 TODO:CDH + pip pyspark 环境下其功能可由 SPARK_CONF_DIR + setdefault 覆盖,evaluate 移除。教训:上一条 changelog(HIVE_CONF_DIR 恢复)是在没对比老项目的情况下拍板的,属于典型的"邻域扫但没找对根因";act-not-flatter memory 同步更新边界判定(同根因 yes/no)
2026-04-20 raw 层外部表规范 + "每日调度" 措辞收敛:(a) kb/20-数仓分层与建模.md §8.1 新增 bullet:raw 层建表一律 CREATE EXTERNAL TABLE,DROP TABLE 只删元数据、HDFS 数据保留,raw 作为链路兜底层误删可恢复;(b) kb/00-项目架构.md 三处"每日调度"收敛为"调度执行":§9 目录说明 jobs/ 用途行(L617)、§9 目录说明 jobs SQL 路径行(L623)、§9.2 标题(L703)—— 因为调度周期不一定是日(小时/周/月/ad-hoc 均可),"每日"措辞在通用性描述里不准确;同文档 L909 ads_trd_gmv_d.sql 注释 + kb/23-标签体系.md 两处 tdm_*_ful_d 场景描述保留"每日计算"(_d 后缀表明具体表就是日粒度)。遗留冲突待拍kb/00-项目架构.md §9.2 L829 的 raw 层 CTAS 样例(CREATE TABLE raw.raw_trd_legacy_order_his_o ... AS SELECT)是 managed table,与 §8.1 新规范的"raw 一律 EXTERNAL"冲突——CREATE EXTERNAL TABLE ... AS SELECT 在 Spark / Hive 语法上不支持。候选:① 样例拆两步(先 CREATE EXTERNAL TABLE + LOCATIONINSERT OVERWRITE)② §8.1 加 "CTAS 例外" 条款 ③ 删掉 §9.2 CTAS 路径只留 INSERT OVERWRITE 路径。待用户拍板
2026-04-20 里程碑:DataX + Spark SQL 双入口在新 CDH 环境首次端到端冒烟跑通(tag milestone/datax+spark-smoke-2026-04-20:链路 DataX 导入 PG dim_calendar → Hive test.dim_calendar_dw2workspace/20260420/dim_calendar.ini),Spark SQL 从 Hive 查回(workspace/20260420/select_dim_calendar_dw2.sql),端到端返回 10 行。新 CDH 环境适配前后共三处连锁修复:(a) cf87744 恢复 HADOOP_CONF_DIR(Spark on YARN 启动强校验);(b) 5b2569a 删除 geo_hash UDF + pygeohash 依赖(common auto-load 链路无 fallback);(c) 本次 SPARK_CONF_DIR=/etc/spark/conf setdefault(pip pyspark 默认指向自身空 conf/,缺此项 enableHiveSupport 静默回落 in-memory metastore,看不到 HMS 真实库表)。注:该 tag 打在 feature 分支 commit 上,违反后续 kb/30 §3.4.6.3 "Tag 打在 release → master 合并提交" 规则,已于 2026-04-21 删除(本地 + 远程)
2026-04-20 存储格式约定反转:orc.compress 不显式写 NONE,走 ORC 默认(ZLIB)workspace/20260420/dim_pub_calendar_ful_o.sql 建表时写了 TBLPROPERTIES ('orc.compress' = 'NONE'),核查 ORC 默认压缩为 ZLIB,NONE 是显式关闭压缩(非 no-op)。前期 kb 三处口径"咱不压缩放弃磁盘换 CPU"属于过早决策,小表省 CPU 微乎其微、业务表规模上来后 ZLIB 更优,维护一套"显式写 NONE"的约束成本大于收益。改为走默认、建表不加 TBLPROPERTIES。文档同步三处:kb/20-数仓分层与建模.md §7 压缩行(orc.compress=NONE → 走 ORC 默认)、kb/00-项目架构.md §9.1 末尾存储格式约定行(删 + orc.compress=NONE)、kb/00-项目架构.md raw 层 CTAS 样例(删 OPTIONS ('orc.compress'='NONE') 一行)。未在文档里加"为什么不显式写 NONE"的解释性注释(见用户反馈)
2026-04-20 kb/20 分区/raw STRING 口径收敛:§7 分区字段补 dt 类型 STRING + 格式 YYYYMMDD(如 20260101);§8.1 "全字段 STRING" bullet 去掉 "(不含 dt 分区)"(dt 本身也是 STRING,括号让人误以为 dt 是另一种类型)
2026-04-20 raw EXTERNAL 规范硬化:kb/00 §9.2 CTAS 样例改 INSERT OVERWRITE:关闭上一批 changelog 的"CTAS + EXTERNAL 冲突待拍"。(a) kb/00 §9.2 CSV 一次性导入样例从 CTAS 改为预建 EXTERNAL TABLE + INSERT OVERWRITE 两步;"CTAS vs INSERT OVERWRITE" 对照表替换为"raw 层写入模式对照"(3 个场景全部 EXTERNAL + INSERT OVERWRITE);"为什么 CSV 一次性导入推荐 CTAS" 论证段删除(论点作废);raw 层不再有"省 manual/ddl/"的例外。(b) kb/20 §8.1 "全字段 STRING" bullet 改为 "raw 层所有表字段(含 dt 分区)一律 STRING 类型"(与 §7 dt STRING 规范对齐,消除"业务字段 vs 分区字段"的措辞分裂)
2026-04-20 kb/90 新增 §2.12 通用 UDF 注释完整化 + 自查表(聚簇 B 延伸)dw_base/udf/common/spark_common_udf.py 40 函数注释粗细不一,且当前 common/ auto-load 链路没有任何"新增 UDF 需要登记哪里"的准入规则。三档改造:(a) 40 函数 docstring 统一 5 段模板(摘要 / 入参 / 返回 / 异常与边界 / SQL 示例),按 JSON → Array → String → Numeric-Date-Hash → Cross-type 5 批分 commit;(b) 新建 kb/31-UDF 手册.md(与 30-开发规范.md 同级独立文档,方案 A 而非并入 30),表头 函数名 / 分类 / 入参 / 返回 / 摘要 / 代码位置 / 补注释状态,初版登记 40 函数全量,新增通用 UDF 进 common/ 时必须同步登记;business/ UDF 在自己的子目录 README 维护,不走此表;(c) kb/30-开发规范.mdCLAUDE.md 加硬约束"增删 common/ UDF 先读 kb/31 + 同步更新",与 tests/unit/udf/test_spark_common_udf.py(§2.11 占位 registry 登记的阶段 4 首批单测目标)配套(自查表为开发者服务,单测为回归服务)。本条是 2026-04-20 UDF 模块重组(本 changelog 之前记录的 UDF 6 文件合一 + business/common 分离)的延伸,不动 auto-load 机制,只补文档与规则
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 mvbin/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 状态改"推进中 / 部分提前完成"
2026-04-21 kb/30 §4.6 整合 Git 协作规范kb/inbox/git规范.md 草稿 6 章整合进 kb/30 §4.6(§4.5 与 §5 之间),节号重排为 §4.6.1~§4.6.6 对齐现有多级风格;草稿 §六 "命名规范" 改名为 "分支 / Tag 命名" 避开与 kb/21-命名规范.md 主文档重名;补分支/hotfix/tag 命名示例到各 3 个(个人分支 3 个与 §4.6.1.2 ASCII 图的李四/王五/张三对齐)
2026-04-21 kb/30 大梳理:删 §1 通用开发流程 / §4.5 占位模块规范,Commit 信息归入 Git 协作节,整体节号重排:(a) 删 §1 通用开发流程(与项目无针对性);(b) 删 §4.5 占位模块规范(该规范仅用于架构规划专用、非普通开发内容,迁至项目根 CLAUDE.md);(c) 原 §4.4 Commit 信息(Conventional Commits)并入 Git 协作规范作为 §3.4.7;(d) 节号重排 §2→§1 TPAD / §3→§2 数仓流程 / §4→§3 代码开发(§4.1-§4.3→§3.1-§3.3、§4.6→§3.4,其 §4.6.1-6 → §3.4.1-6)/ §5→§4 / §6→§5 / §7→§6;(e) 联动 kb/README.md §30 条目描述 + kb/90-重构路线.md §2.11 占位模块标准引用从 kb/30 §4.5 改指 CLAUDE.md