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

145 lines
7.6 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 协作规范
本仓库是 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 上建议开启中文路径正常显示:
```bash
git config --global core.quotepath false
```
## 八、评审
| 改动类型 | 至少几人看 | 谁必须看 |
|---|---|---|
| 迁移脚本、表结构 | 2 | 数据库负责人 |
| 接口契约、内部五接口 | 2 | 架构一致性负责人 |
| 权限、鉴权、加解密 | 2 | 架构一致性负责人 |
| 其他代码 | 1 | 模块负责人 |
| 纯文档 | 1 | — |
评审看三件事,不看代码风格:**改了会不会影响已验收的东西;有没有第二套实现;文档跟上了没有。**
## 九、大文件
单个文件超过 5 MB 不要直接提交。演示素材、证据、构建产物走受控目录或发布附件,仓库只放需要版本追溯的内容。
已经提交进去的大文件,删除也只是"最新版本没有",`.git` 里仍然存在。真要清理得重写全部历史,代价远高于当初不放进来。
## 十、开工前自检
```bash
git status # 有没有把 target/ 和 .env 带进来
git diff --cached --stat # 改动范围是否符合预期
git grep -nIE 'password|secret|token' --cached -- ':!docs' # 有没有硬编码凭据
```
第三条命中不一定是问题(变量名也会命中),但每一条都要能说清为什么不是问题。