Explorar o código

docs(kb): 30 删 §1 通用流程 / §4.5 占位模块,commit 信息归入 §3.4 Git 协作,节号重排(README/90 联动)

tianyu.chu hai 2 semanas
pai
achega
ac59f8c7e3
Modificáronse 4 ficheiros con 70 adicións e 154 borrados
  1. 65 149
      kb/30-开发规范.md
  2. 1 1
      kb/90-重构路线.md
  3. 3 3
      kb/92-重构进度.md
  4. 1 1
      kb/README.md

+ 65 - 149
kb/30-开发规范.md

@@ -1,77 +1,13 @@
 # 开发规范
 
-> 本文档记录 `poyee-data-warehouse` 团队通用开发流程与项目管理规范。
+> 本文档记录 `poyee-data-warehouse` 数仓数据开发流程与项目管理规范。
 > 与 `数仓命名规范.md`、`90-重构路线.md` 配合使用。
 
-## 1. 通用开发流程
-
-```
-需求评审 → 技术评审 → 开发&测试排期 → 设计文档 → 开发&测试 → 需求方验收 → 生产部署 → 复盘总结
-```
-
-### 1.1 需求评审
-
-详细了解需求背景与细节,讨论可行性。关键点:
-- 需求是否明确?解决什么问题?
-- 复杂度高时能否分阶段实施?
-- 完成的期望指标、验收标准、交付形式?
-- 技术上能否实现、逻辑有无问题?
-- 开发期间遇到问题与谁对接?
-- 需求未明确前必须让需求方澄清疑问点
-- 对接完成后邮件告知
-
-### 1.2 技术评审
-
-阐述详细的技术实现方案,评估合理性:
-- 表结构设计
-- 接口定义
-- 技术难点及应对
-
-### 1.3 开发 & 测试排期
-
-评估工作量,安排各步骤截止日期。
-
-### 1.4 输出开发设计文档
-
-**放置位置**:Confluence(或团队 Wiki)。
-
-**必要章节**:
-- 需求背景
-- 开发设计(技术方案)
-- 排期计划
-- 开发流程详细内容
-- 附录
-
-> **必须在开发测试开始前**完成需求背景、技术方案、排期计划;其他部分可随进度补充。
-
-### 1.5 开发 & 测试
-
-按技术方案和排期实现。
-
-### 1.6 需求方验收
-
-- 开发修 bug
-- 可提前提供部分样例结果做预验收
-
-### 1.7 生产部署
-
-按环境部署(见 `publish.sh`)。
-
-### 1.8 需求复盘总结
-
-复盘问题出在哪里、以后如何规避、有哪些优点可以借鉴。
-
-### 1.9 对接与验收阶段注意事项
-
-- 首版需求已评审的前提下,若出现频繁变更和不确定点,必须明确要求需求方**批量提供变更点**
-- 建议最多一次批量补充;第二批及以上按**需求变更**流程处理
-- 开发要合理评估,避免承接不合理需求
-
-## 2. 项目管理规范(TPAD)
+## 1. 项目管理规范(TPAD)
 
 目前 TPAD 已创建**数据需求工作流**和**技术需求工作流**。
 
-### 2.1 TPAD 任务建档要求
+### 1.1 TPAD 任务建档要求
 
 | 耗时 | 要求 |
 |------|------|
@@ -79,9 +15,9 @@
 | **2 小时以上** | 必须建立 TPAD 任务 |
 | **8 小时以上** | 必须有方案或设计文档 |
 
-## 3. 数据开发流程
+## 2. 数据开发流程
 
-### 3.1 数据开发全流程图
+### 2.1 数据开发全流程图
 
 ```mermaid
 flowchart TD
@@ -110,9 +46,7 @@ flowchart TD
     Q --> Z
 ```
 
-### 3.2 关键节点说明
-
-数据开发在通用流程基础上增加以下专属环节:
+### 2.2 关键节点说明
 
 | 环节 | 说明 |
 |------|------|
@@ -127,9 +61,9 @@ flowchart TD
 | **数据质量校验** | 在 DolphinScheduler 工作流中加入质量校验节点 |
 | **历史回溯** | 确保任务支持按 `dt` 回跑;追溯完成后需要验收 |
 
-## 4. 代码开发规范
+## 3. 代码开发规范
 
-### 4.1 Python / PySpark
+### 3.1 Python / PySpark
 
 - PEP 8 风格
 - 禁用 `dict.__contains__(key)`,改用 `key in dict`
@@ -137,14 +71,14 @@ flowchart TD
 - 硬编码配置项必须外置到 `conf/`(见 `90-重构路线.md` §2)
 - 敏感信息(数据库账密)**不得入库**
 
-### 4.2 SQL
+### 3.2 SQL
 
 - 表名、字段名遵循五段式命名
 - 所有字段必须带 `COMMENT`
 - 分区字段统一 `dt`(日期)/ `hr`(小时)
 - 存储格式统一 ORC
 
-#### 4.2.1 IDE SQL 格式化配置
+#### 3.2.1 IDE SQL 格式化配置
 
 `conf/sql_style.xml` 是 **JetBrains 系 IDE(PyCharm / DataGrip / IntelliJ)的 SQL Code Style 导出文件**,团队统一从此文件导入,避免每人格式化后 diff 里一堆空白噪音。
 
@@ -170,7 +104,7 @@ flowchart TD
 | `EXPR_CASE_END` | 1 | CASE / END 换行 |
 | `CONTINUATION_INDENT_SIZE` | 4 | 续行缩进 4 空格 |
 
-#### 4.2.2 为什么不对齐 AS
+#### 3.2.2 为什么不对齐 AS
 
 字段别名**不对齐** AS 关键字是刻意的,理由:
 
@@ -181,70 +115,18 @@ flowchart TD
 5. **可读性不需要靠对齐**:每个字段一行 + 逗号前置已足够清晰
 
 
-### 4.3 Shell
+### 3.3 Shell
 
 - 环境变量统一从 `conf/env.sh` 读取
 - 避免在业务脚本中重复环境检测逻辑(统一交给 Python 入口)
 
-### 4.4 Git 提交信息(Conventional Commits)
-
-每条 commit message 必须以 `<type>: <简短描述>` 开头,type 从下面固定列表里选一个;长说明放正文,与标题空一行。
-
-| type | 用途 | 示例 |
-|------|------|------|
-| `feat` | 新功能 / 新 job / 新表 | `feat(raw/crm): 新增 ods_crm_ent_contact_di` |
-| `fix` | Bug 修复 / 数据订正 | `fix(dwd/trd): 修复订单金额币种换算错误` |
-| `docs` | 只改文档(含 `kb/`、注释、README) | `docs(kb): 更新 21-命名规范.md §3.9 示例` |
-| `refactor` | 不改变外部行为的重构 | `refactor(dw_base): tendata → dw_base 模块改名` |
-| `perf` | 性能优化 | `perf(dws): 拆 tmp 表减少 shuffle` |
-| `test` | 只增/改测试 | `test(udf): 补 safe_cast_decimal 边界用例` |
-| `chore` | 构建、依赖、CI、打包 | `chore: 精简 requirements.txt` |
-| `style` | 空白 / 格式 / import 顺序(不改逻辑) | `style: sql_style.xml 全局格式化` |
-| `build` | 打包脚本 / publish.sh / Dockerfile | `build: publish.sh 支持 -env 参数` |
-| `ci` | DolphinScheduler / GitHub Actions 配置 | `ci: DS 工作流加质量校验节点` |
-| `ops` | 运维类操作(补数、回刷、重跑、人工干预) | `ops(dwd/trd): 补 20260101-20260131 订单分区` |
-| `revert` | 撤销某次提交 | `revert: feat(raw/crm): ...` |
-
-**约定**:
-
-1. **标题 ≤ 50 字符**,祈使句(「新增 xxx」而不是「新增了 xxx」)
-2. **scope 可选但推荐**:数仓项目里 scope 常取 `{层}/{域}`(如 `dwd/trd`)或模块名(`dw_base`、`bin`、`kb`、`conf`)
-3. **破坏性变更**:标题末尾加 `!`,正文以 `BREAKING CHANGE:` 开头说明迁移方式
-   - 例:`refactor(dw_base)!: 拆分 __init__.py` + `BREAKING CHANGE: 需要在调用处显式 import findspark`
-4. **一次提交做一件事**:不要把"新增表 + 顺手修 bug + 改文档"塞一起,按 type 拆成 3 个 commit
-5. **关联 TPAD / issue**:正文末尾加 `Refs: TPAD-1234` 或 `Closes: #42`
-
-**反例**(会被 reject):
-
-- `update` / `修改` / `提交` —— 没有 type,描述空洞
-- `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`。
-
-### 4.6 Git 协作规范
+### 3.4 Git 协作规范
 
 本节定义数仓项目团队使用 Git 协作的分支模型与工作流程,保证主干历史整洁可追溯,降低多人协作冲突风险。
 
-#### 4.6.1 分支模型
+#### 3.4.1 分支模型
 
-##### 4.6.1.1 分支总览
+##### 3.4.1.1 分支总览
 
 | 分支 | 定位 | 受保护 | 合并来源 | 触发动作 |
 |------|------|--------|----------|----------|
@@ -253,7 +135,7 @@ flowchart TD
 | `feature` | 公共开发分支 | 是 | `feature-xxx`(个人分支) | 测试通过后合入 `release` |
 | `feature-xxx` | 个人开发分支 | 否 | —— | 通过 PR 合入 `feature` 后自动删除 |
 
-##### 4.6.1.2 分支结构
+##### 3.4.1.2 分支结构
 
 ```
                                      [tag: datax+spark-smoke-2026-04-20]
@@ -275,11 +157,11 @@ flowchart TD
            └─────────── feature-zhangsan-ods-usr-20260420 ✗ (PR 合入后自动删除)
 ```
 
-##### 4.6.1.3 保护策略
+##### 3.4.1.3 保护策略
 
 `master`、`release`、`feature` 三个分支在仓库层面禁用远程推送,所有变更必须通过 PR(Pull Request / Merge Request)流转,仅允许管理员通过合并操作更新。
 
-#### 4.6.2 代码流转路径
+#### 3.4.2 代码流转路径
 
 ```mermaid
 flowchart LR
@@ -290,7 +172,7 @@ flowchart LR
 
 代码单向汇聚到 `master`,各合并节点由管理员操作,`release` → `master` 的合并提交需打 Tag。
 
-#### 4.6.3 开发者工作流
+#### 3.4.3 开发者工作流
 
 ```mermaid
 sequenceDiagram
@@ -338,17 +220,17 @@ sequenceDiagram
 
 日常通过 PyCharm 的 Git 面板与仓库网页端完成上述操作即可。
 
-#### 4.6.4 要求使用 Rebase 而非 Merge
+#### 3.4.4 要求使用 Rebase 而非 Merge
 
 - **历史线性整洁**:没有冗余的 merge 提交,可视化合并树清晰
 - **二分查找友好**:`git bisect` 定位问题提交更精准
 - **Review 聚焦**:PR 里只有本次任务的提交,Reviewer 不会看到与本次无关的 merge commit
 
-#### 4.6.5 Hotfix 紧急修复流程
+#### 3.4.5 Hotfix 紧急修复流程
 
 线上 `release` 分支出现紧急故障时,走独立的 hotfix 流程,避免等待 `feature` 中未完成功能的流转。
 
-##### 4.6.5.1 流转路径
+##### 3.4.5.1 流转路径
 
 ```mermaid
 flowchart LR
@@ -362,7 +244,7 @@ flowchart LR
 
 > 为什么不是 `release` 合入 `feature`?`release` 本身由大量 merge commit 构成,反向合入会污染 `feature` 的线性历史。用 hotfix 分支发两个 PR,两边拿到的都是同一个独立的修复提交。
 
-##### 4.6.5.2 操作步骤
+##### 3.4.5.2 操作步骤
 
 1. 开发者基于最新 `origin/release` 创建 `hotfix-xxx` 分支,**只做 bug 修复,不夹带其他改动**
 2. 提 PR #1 至 `release`,管理员 Review 通过后合入,**暂不删除 hotfix 分支**
@@ -371,15 +253,15 @@ flowchart LR
 5. 管理员 Review 通过后合入 `feature`,删除 hotfix 分支
 6. 管理员将 `release` 合入 `master` 并打 hotfix tag
 
-##### 4.6.5.3 冲突异常处理
+##### 3.4.5.3 冲突异常处理
 
 正常情况下 PR #2 不应产生冲突——hotfix 职责单一,`feature` 上不应存在针对同一代码的并行修改。
 
 **若产生冲突,说明 `feature` 上有人改动了 hotfix 修复的同一区域**。此时**不要自行解决冲突**,否则会出现 `release` 与 `feature` 修复版本不一致,后续发布可能导致 bug 复现。正确做法:暂停合并,由管理员召集 hotfix 作者与 `feature` 侧的改动者协调,确认最终版本后再继续。
 
-#### 4.6.6 分支 / Tag 命名
+#### 3.4.6 分支 / Tag 命名
 
-##### 4.6.6.1 个人分支命名
+##### 3.4.6.1 个人分支命名
 
 格式:`feature-<姓名拼音>-<描述>-<日期>`
 
@@ -389,7 +271,7 @@ flowchart LR
 | `feature-wangwu-dim-shp-20260419` | 王五开发商品维度,2026-04-19 建分支 |
 | `feature-zhangsan-ods-usr-20260420` | 张三开发用户域 ODS 层,2026-04-20 建分支 |
 
-##### 4.6.6.2 Hotfix 分支命名
+##### 3.4.6.2 Hotfix 分支命名
 
 格式:`hotfix-<姓名拼音>-<故障简述>-<日期>`
 
@@ -399,7 +281,7 @@ flowchart LR
 | `hotfix-lisi-ads-prd-null-20260422` | 修复产品宽表空值异常 |
 | `hotfix-wangwu-dws-mkt-stale-20260423` | 修复营销宽表数据滞后 |
 
-##### 4.6.6.3 Tag 命名
+##### 3.4.6.3 Tag 命名
 
 格式:`<描述>-<类型>-<日期>`
 
@@ -414,7 +296,41 @@ flowchart LR
 - 阶段类型:`smoke`(冒烟通过)、`hotfix`(紧急修复)
 - Tag 打在 `release` → `master` 的合并提交上,由管理员操作
 
-## 5. 测试规范
+#### 3.4.7 Commit 信息(Conventional Commits)
+
+每条 commit message 必须以 `<type>: <简短描述>` 开头,type 从下面固定列表里选一个;长说明放正文,与标题空一行。
+
+| type | 用途 | 示例 |
+|------|------|------|
+| `feat` | 新功能 / 新 job / 新表 | `feat(raw/crm): 新增 ods_crm_ent_contact_di` |
+| `fix` | Bug 修复 / 数据订正 | `fix(dwd/trd): 修复订单金额币种换算错误` |
+| `docs` | 只改文档(含 `kb/`、注释、README) | `docs(kb): 更新 21-命名规范.md §3.9 示例` |
+| `refactor` | 不改变外部行为的重构 | `refactor(dw_base): tendata → dw_base 模块改名` |
+| `perf` | 性能优化 | `perf(dws): 拆 tmp 表减少 shuffle` |
+| `test` | 只增/改测试 | `test(udf): 补 safe_cast_decimal 边界用例` |
+| `chore` | 构建、依赖、CI、打包 | `chore: 精简 requirements.txt` |
+| `style` | 空白 / 格式 / import 顺序(不改逻辑) | `style: sql_style.xml 全局格式化` |
+| `build` | 打包脚本 / publish.sh / Dockerfile | `build: publish.sh 支持 -env 参数` |
+| `ci` | DolphinScheduler / GitHub Actions 配置 | `ci: DS 工作流加质量校验节点` |
+| `ops` | 运维类操作(补数、回刷、重跑、人工干预) | `ops(dwd/trd): 补 20260101-20260131 订单分区` |
+| `revert` | 撤销某次提交 | `revert: feat(raw/crm): ...` |
+
+**约定**:
+
+1. **标题 ≤ 50 字符**,祈使句(「新增 xxx」而不是「新增了 xxx」)
+2. **scope 可选但推荐**:数仓项目里 scope 常取 `{层}/{域}`(如 `dwd/trd`)或模块名(`dw_base`、`bin`、`kb`、`conf`)
+3. **破坏性变更**:标题末尾加 `!`,正文以 `BREAKING CHANGE:` 开头说明迁移方式
+   - 例:`refactor(dw_base)!: 拆分 __init__.py` + `BREAKING CHANGE: 需要在调用处显式 import findspark`
+4. **一次提交做一件事**:不要把"新增表 + 顺手修 bug + 改文档"塞一起,按 type 拆成 3 个 commit
+5. **关联 TPAD / issue**:正文末尾加 `Refs: TPAD-1234` 或 `Closes: #42`
+
+**反例**(会被 reject):
+
+- `update` / `修改` / `提交` —— 没有 type,描述空洞
+- `feat: xxx\nfix: yyy\ndocs: zzz` —— 一条 commit 混多个 type
+- `feat: 新增了一大堆表` —— scope 和具体目标不明
+
+## 4. 测试规范
 
 见 `90-重构路线.md` §6。核心要点:
 - UDF 单测:纯 Python,不依赖 Spark
@@ -422,7 +338,7 @@ flowchart LR
 - Spark 集成测试:`local[*]` 模式
 - 数据质量校验:行数、空值率、主键唯一性
 
-## 6. manual/ 临时 SQL 规范
+## 5. manual/ 临时 SQL 规范
 
 `manual/` 目录存放**一次性、非幂等**的 SQL 脚本,与 `jobs/` 的语义完全独立。详细目录约定见 `00-项目架构.md` §8,这里只列开发团队必须遵守的核心规则:
 
@@ -437,7 +353,7 @@ flowchart LR
    - 脏数据订正 → `manual/fix/`,必须附 TPAD 工单号
 6. **归档策略**:执行完成后保留 3-6 个月作为审计证据,过期后移入 `manual/archive/` 或直接删除
 
-## 7. 相关文档
+## 6. 相关文档
 
 - [命名规范](21-命名规范.md)
 - [数仓分层与建模](20-数仓分层与建模.md)

+ 1 - 1
kb/90-重构路线.md

@@ -537,7 +537,7 @@ record_per_channel = 100000
 | `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 直接删除,不保留"暂留"。
+**标准**:每个占位模块必须带 README,4 节(职责 / 接口 / 依赖 / 状态)—— 规则见项目根 `CLAUDE.md`(架构规划专用约定,普通开发不涉及)。空 `__init__.py` + 无 README 直接删除,不保留"暂留"。
 
 ### 2.12 通用 UDF 注释完整化 + 自查表(B 延伸) [聚簇 B]
 

+ 3 - 3
kb/92-重构进度.md

@@ -174,11 +174,11 @@
 | 2026-04-20 | **恢复 `dw_base/__init__.py:16` 的 `HADOOP_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` + `LOCATION` 再 `INSERT 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_dw2`(`workspace/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 为 annotated tag 指向本次 commit,本地 + 远程均可见 | — |
+| 2026-04-20 | **里程碑:DataX + Spark SQL 双入口在新 CDH 环境首次端到端冒烟跑通(tag `milestone/datax+spark-smoke-2026-04-20`)**:链路 DataX 导入 PG `dim_calendar` → Hive `test.dim_calendar_dw2`(`workspace/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-开发规范.md` 或 `CLAUDE.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 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 状态改"推进中 / 部分提前完成" | — |
-| 2026-04-21 | **kb/30 §4.4 Conventional Commits type 表补 `ops`**:新增 `ops` 类型覆盖运维类操作(补数、回刷、重跑、人工干预),插在 `ci` 与 `revert` 之间,示例 `ops(dwd/trd): 补 20260101-20260131 订单分区` | — |
-| 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 图的李四/王五/张三对齐)。inbox 原文件本次不动,后续处理 | — |
+| 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` | — |

+ 1 - 1
kb/README.md

@@ -44,7 +44,7 @@
 
 | 文档 | 内容 |
 |----|----|
-| [30-开发规范](30-开发规范.md) | 数据开发流程、任务规范、代码 / SQL 规范(IDE 格式化 scheme 见 `conf/sql_style.xml`) |
+| [30-开发规范](30-开发规范.md) | TPAD 任务规范、数仓数据开发流程、代码 / SQL 规范、Git 协作规范(IDE 格式化 scheme 见 `conf/sql_style.xml`) |
 
 ### 9x 过渡资料