Files
hepu/CONTRIBUTING.md
aomin 983191628e docs(config): 补 .env.example 并修正 .gitignore 误伤模板
.gitignore 的 `.env.*` 会把 `.env.example` 一起排除,等于把变量清单挡在仓库外,
接手的人只能翻 application.yml 逐个猜要配什么。加 `!.env.example`(含
`.sample`、`.template`)例外,规则顺序放在忽略之后。

同时补 .env.example:从 application.yml 与代码里实际提取 20 个变量,分组注明
默认值与是否必须替换。三个必改项(DB_PASS 无默认、GATEWAY_TOKEN 占位、
BIZ_TOKEN_SECRET 与 BIZ_PII_KEY 为 dev-only)单独标出。

本文件只放占位值;真实的 .env 仍不入库。另注明工程不自动读 .env
(未引入 dotenv),必须由启动脚本加载或 docker compose --env-file 注入——
这一条不说清,会有人建了 .env 直接启动然后发现 DB_PASS 还是缺。
2026-11-13 17:38:08 +08:00

7.6 KiB
Raw Permalink Blame History

协作规范

本仓库是 M-Z 业务层的唯一主干。以下规则不是风格偏好,每一条都对应过一类实际事故,改动前请先读完。

一、分支模型

分支 用途 说明
main 主干,随时可构建 不直接提交。只接受合并
feat/<简短英文> 新功能 如 feat/notify-retry
fix/<简短英文> 缺陷修复 如 fix/raw-ref-null
docs/<简短英文> 仅文档 如 docs/j00-v18
hotfix/<简短英文> 生产应急 合并后必须回写 main

分支名用英文小写与连字符。不建长期存在的个人分支——长期分支与主干拉开两周以上,合并冲突的代价远高于当时直接改主干。

二、提交信息

格式:

<类型>(<范围>): <一句话说明>

<可选正文:为什么这么改,以及这样改的代价>

类型只有六种:

类型 用于
feat 新增能力
fix 修缺陷
refactor 不改行为的重构
docs 文档与契约
chore 构建、依赖、配置
revert 回退

范围写模块名,不写人名。示例:

fix(internal): I-12 原文缺失返回 404 而不是 500

rawRef 指向不存在的行时,原先抛 NPE 被全局兜底成 500,
接入侧无法区分"我写错了"和"你这边崩了"。改为显式 404 + 原因码 RAW_REF_NOT_FOUND。

一条提交只做一件事。 把"改接口"和"顺手格式化整个文件"混在一条提交里,出问题时无法单独回退其中一件。

不要写"按某人要求修改"。 写清楚改了什么、为什么,谁要求的写在会签与议题里,不写在提交信息里。

三、绝不入库的东西

类别 具体
凭据 口令、token、AK/SK、私钥、.pem、.key、.jks、证书
本地配置 .env、application-local.yml、*.local.yml
构建产物 target/、*.jar、*.war、*.class
IDE 与系统 .idea/、*.iml、.vscode/、Thumbs.db、.DS_Store
运行产物 日志、*.jsonl、证据 raw/、截图
公司无关资料 员工绩效、客户名单、采购函、其他项目报价

唯一例外是 .env.example。 它是变量清单模板,必须入库——不入库接手的人就不知道要配哪些变量,只能去翻 application.yml 逐个猜。模板里只放占位值,真实值填在本地 .env 里。新增环境变量时同步更新它,否则清单很快就不准了。

.gitignore 已经覆盖上述路径,但它只挡新增,不挡已提交。加文件前先 git status 看一眼。

判断标准很简单:这个文件一旦公开,会不会造成损失? 会,就不要放进来。Git 的历史是追加式的,删除只影响最新版本,历史里那份永远在。

四、迁移脚本(Flyway)硬规则

  1. 只增不改。 已执行过的 V1.0.x__*.sql 一个字节都不能动。改动会让校验和不符,已部署环境启动即失败(Migration checksum mismatch)。
  2. 不重命名、不删除、不调换顺序。 版本号是执行顺序的唯一依据。
  3. 编号连续递增,命名 V1.0.<n>__<英文小写下划线>.sql。当前终态 1.0.28。
  4. 加列与加索引拆成两条 ALTER。 INSTANT 与 INPLACE 混在同一条语句里,MySQL 会整体降级为重建表,大表上表现为长时间锁表。
  5. 迁移里不写 ALGORITHM=INSTANT。 本机 MySQL 是 8.0.11,该语法 8.0.12 才有,写了后端起不来;确需指定用 ALGORITHM=INPLACE, LOCK=NONE。
  6. 校验和不符不要手改 flyway_schema_history。 用 flyway repair,它只重写校验和与描述,不改表结构。
  7. 一期与二期脚本分目录。二期脚本放 db/migration-phase2/,不要放进 spring.flyway.locations 指向的目录,否则一期启动会建出二期空表。

五、接口契约硬规则

本工程没有运行时 OpenAPI 生成(未引入 springdoc)。docs/contract/ 下的 md 与 yaml 是手工维护的唯一机读契约,因此"改了代码但没改文档"就是契约漂移,且没有任何工具会报错。

改动 必须同步
接口增删、字段增删、字段语义变化 docs/contract/6_J-00_接入接口规格_V1.8.md
同上,机读部分 docs/contract/6_J-00_接入接口规格_V1.8_OpenAPI.yaml
五个内部接口(I-01/I-02/I-05/I-12/I-18) docs/contract/内部五接口定义.md
状态、结果码、状态迁移 docs/contract/状态机.md

契约版本号升级时,文件名、正文、yaml 的 info.version 三处必须一致,旧版本文件保留不删。

以下是不许自己决定的判断题,先会签再改: 幂等键的构成、rawRef 的必填性与指向、时间来源与精度口径、命令状态数量、告警状态与动作的映射。这些一旦出现两套写法,表现是"两边都正常,数据互相不认"。

六、目录约定

  • 新增文档进 docs/,按性质放 handover/(交付与清理)、contract/(接口契约)、reference/(指纹与校验)。不要堆在仓库根。
  • 目录名用 ASCII(docs、demo、aomin-gateway),避免跨平台与 URL 编码问题。
  • 文件名可用中文。docs/ 下的历史文件保留原始文件名,因为会签材料、复核记录按名字索引,改名等于让它失联。
  • 新增文档不要覆盖旧版:同主题改版新建文件、版本号 +1,旧件保留。

七、行尾与编码

文件 约定
.bat / .cmd GBK 编码 + CRLF,脚本内 chcp 936。用 UTF-8 编辑器"修正"会立刻让中文提示变乱码
新增源码与文档 UTF-8(无 BOM)+ LF
.jar / 图片 / 文档 二进制,禁止行尾转换

.gitattributes 里 * -text 是刻意的,不要改成 text=auto。 基线按交付字节原样保存,源码树摘要才可复现;一旦开启自动转换,克隆出来的树与交付包不是同一份字节,摘要对不上,复核会误判成"被改过"。归一化行尾属于基线变更,要走会签。

代价是:交付包内 14 个文件本来就是 CRLF,与新增的 LF 文件混在一起,git diff 遇到"整文件行尾变化"时看不出实质改动。改老文件前先确认它的行尾,别让编辑器顺手整篇转换。

Windows 上建议开启中文路径正常显示:

git config --global core.quotepath false

八、评审

改动类型 至少几人看 谁必须看
迁移脚本、表结构 2 数据库负责人
接口契约、内部五接口 2 架构一致性负责人
权限、鉴权、加解密 2 架构一致性负责人
其他代码 1 模块负责人
纯文档 1 —

评审看三件事,不看代码风格:改了会不会影响已验收的东西;有没有第二套实现;文档跟上了没有。

九、大文件

单个文件超过 5 MB 不要直接提交。演示素材、证据、构建产物走受控目录或发布附件,仓库只放需要版本追溯的内容。

已经提交进去的大文件,删除也只是"最新版本没有",.git 里仍然存在。真要清理得重写全部历史,代价远高于当初不放进来。

十、开工前自检

git status                    # 有没有把 target/ 和 .env 带进来
git diff --cached --stat      # 改动范围是否符合预期
git grep -nIE 'password|secret|token' --cached -- ':!docs'   # 有没有硬编码凭据

第三条命中不一定是问题(变量名也会命中),但每一条都要能说清为什么不是问题。