按周工交付的 SEC-Z-01 清理后源码建立 M-Z 主干,并按 Git 仓库惯例重排目录。 - aomin-gateway/ 后端工程 87 文件,原样保留,路径与构建命令未变 - demo/ 演示前端与设备模拟器 9 文件(原 02_前端与设备端),非正式三端 - docs/handover/ 交付与安全清理材料 6 份,内容未改 - docs/contract/ J-00 规格、OpenAPI、内部五接口、状态机、Mock 样例 - docs/reference/ 指纹与校验清单,含 84 个源码文件的 sha256 清单 目录重排只动位置不动内容:源码树 84 文件哈希与交付一致,逐文件自校验通过; 12 条 Flyway 迁移与交付包内镜像逐字节一致。 未纳入:迁移镜像目录(与工程内一套重复,改留指纹)、target/、证据 raw、 应急恢复脚本、评审用虚构台账数据。 安全:SEC-Z-01 15 处明文已清零,导入前重新扫描无新增命中,本仓库无历史污染。 行尾按交付字节原样保存(.gitattributes 设 * -text),不做归一化以免整树摘要失效。
7.3 KiB
协作规范
本仓库是 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/、截图 |
| 公司无关资料 | 员工绩效、客户名单、采购函、其他项目报价 |
.gitignore 已经覆盖上述路径,但它只挡新增,不挡已提交。加文件前先 git status 看一眼。
判断标准很简单:这个文件一旦公开,会不会造成损失? 会,就不要放进来。Git 的历史是追加式的,删除只影响最新版本,历史里那份永远在。
四、迁移脚本(Flyway)硬规则
- 只增不改。 已执行过的
V1.0.x__*.sql一个字节都不能动。改动会让校验和不符,已部署环境启动即失败(Migration checksum mismatch)。 - 不重命名、不删除、不调换顺序。 版本号是执行顺序的唯一依据。
- 编号连续递增,命名
V1.0.<n>__<英文小写下划线>.sql。当前终态1.0.28。 - 加列与加索引拆成两条
ALTER。 INSTANT 与 INPLACE 混在同一条语句里,MySQL 会整体降级为重建表,大表上表现为长时间锁表。 - 迁移里不写
ALGORITHM=INSTANT。 本机 MySQL 是 8.0.11,该语法 8.0.12 才有,写了后端起不来;确需指定用ALGORITHM=INPLACE, LOCK=NONE。 - 校验和不符不要手改
flyway_schema_history。 用flyway repair,它只重写校验和与描述,不改表结构。 - 一期与二期脚本分目录。二期脚本放
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' # 有没有硬编码凭据
第三条命中不一定是问题(变量名也会命中),但每一条都要能说清为什么不是问题。