Files
saas-mbr/abacus.springboot.example/.project.agents/VIBECODING_GUIDE.md
T

251 lines
12 KiB
Markdown
Raw 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.
# 项目开发实践指南(VIBECODING GUIDE
> 本文档是基于"踩过的坑"沉淀下来的项目工作方式约定,适用于本仓库及后续所有同性质的项目。
> 它的姊妹文件是 [`SELF_CONSTRAINTS.md`](./SELF_CONSTRAINTS.md) —— 那是 Agent 每次开工前必须自查的硬约束清单。
> 本文回答 "为什么这么做"`SELF_CONSTRAINTS.md` 回答 "具体不许做什么"。
---
## 0. 三条核心教训(本指南的来由,优先级严格递减)
1. **版本控制必须从第 0 天开始。**
不是 "等做出点东西再说",是写第一行代码之前先初始化仓库、写好 ignore 规则、提交一个空骨架。
理由:高频改动 + 频繁推翻是 AI 协作的常态,没有版本控制兜底就等于在悬崖边裸奔。
2. **文档必须在写代码之前定下来。**
需求、架构、路线图、开发规范、目录结构、命名规范、模块边界 —— 这些不是"做完之后补的",是"做之前定的"。
理由:一旦上下文被代码细节占满,后续每个新会话都只能 freestyle,项目会朝不可逆的方向漂移。
3. **架构 > UI > 用户体验。**
最致命的不是界面丑、不是体验差,而是模块互相纠缠到无法定位问题。
一个出问题就能立刻指认 "是 X 模块的责任" 的项目,比一个好看但耦合一团的项目,存活率高一个数量级。
理由:耦合一旦发生,AI 协作模式会迅速放大它 —— 因为每次新会话都看不全全貌,只会在原有耦合上继续添乱。
> 这三条的优先级是严格递减的:先有版本控制,再有文档,再谈架构;架构稳了之后才轮到 UI 和体验。
---
## 1. 项目启动 ChecklistDay 0
下列每一项都必须在写第一行业务代码之前完成。顺序即优先级。
### 1.1 仓库与版本控制
- [ ] 初始化版本控制并立即建立 ignore 规则(语言 / IDE / 系统三类至少齐全)
- [ ] 提交一个 **空骨架 commit**README + ignore 规则 + 空目录结构),作为"零点参照系"
- [ ] 约定分支模型(最简:主干 + 短命的功能分支;不要等到分叉时才想)
- [ ] 约定 commit message 风格(推荐 Conventional Commits,至少要求动词开头 + 一句话原因)
### 1.2 文档骨架(必须先于代码存在)
`.project.agents/docs/context` 下建立以下文件,**哪怕只有大纲也比没有强**:
| 文件 | 角色 | 上下游关系 |
|---|---|---|
| `PRD.md` | 产品需求(要做什么) | 上游 |
| `ARCHITECTURE.md` | 架构(怎么拆) | 上游 |
| `ROADMAP.md` | 路线图(什么时候做哪一块) | 由需求 + 架构推导 |
| `CONVENTIONS.md` | 开发规范(命名、目录、提交、风格) | 上游 |
| 派生文档(实现 spec / 资产清单等) | 屏幕级实现 / 资产清单 | **派生**,由上游产生 |
**判断标准**:如果一个新会话的 Agent 只读需求 + 架构 + 开发规范就能正确开始一个任务 —— 文档就算合格。
### 1.3 Agent 协作配置
- [ ]`CLAUDE.md` 写明项目级规则(已有,保持更新)
- [ ] 在本文件 + `SELF_CONSTRAINTS.md` 中固化经验
- [ ]`.project.agents/settings.json` 中配置必要的 hook / 权限(不要散落到根目录或全局)
---
## 2. 架构原则
### 2.1 三条硬规则
1. **单一职责到模块级**
每个模块只回答一个问题。
反例:"一个模块既管数据持久化,又管网络请求,又管 UI 状态" —— 这种模块必须拆。
2. **依赖方向单向**
高层依赖低层,UI 依赖业务,业务依赖数据;**反向依赖一律禁止**,遇到就用接口/事件/回调倒置。
依赖关系必须能画成一张**有向无环图(DAG)**,且这张图要在 `ARCHITECTURE.md` 里画出来。
3. **跨模块只走"接口契约"**
模块 A 想用模块 B 的能力,只能通过 B 暴露的接口/协议,不能 reach into B 的内部实现。
接口契约必须在 `ARCHITECTURE.md` 中显式声明(哪怕只是函数签名清单)。
### 2.2 判断架构是否健康的三个问句
随时可以用这三个问句自检:
1. **指认问题**:现在出 bug 了,我能否在 30 秒内指出"这是哪个模块的责任"?
2. **替换实现**:如果要把模块 X 整体换掉(换数据库、换框架),改动是否能控制在 X 内部 + 一个接口适配层?
3. **新增功能归属**:用户要加一个新功能,我能否立刻说出它"属于哪个模块、或需要新增哪个模块"?
任何一个回答不出来,架构就有问题,**先停下修架构,再写代码**。
### 2.3 反耦合纪律
- **不在新功能开发时顺手重构无关模块**(重构走单独 commit + 单独会话)
- **不在 UI 层做业务判断**(UI 只接收状态、发送意图)
- **不让数据模型自己跑业务逻辑**(模型类保持瘦,业务放 Service / UseCase
- **不要"为了少写一个文件"把两个模块塞进同一个文件**
---
## 3. 项目架构文档生成流程
这是从零到 `ARCHITECTURE.md` 的标准流程。每一步都有产出物,下一步必须基于上一步的产出物。
### Step 1 — 需求收敛(产出 `PRD.md`
- 列功能清单,按 **核心 / 增强 / 可选** 三档分类
- 每个核心功能写一句 "用户故事"("作为 X,我想 Y,以便 Z"
- **冻结 MVP 范围**:圈出 MVP 包含哪些核心功能,其余明确标 "Out of MVP"
### Step 2 — 领域建模(产出 `ARCHITECTURE.md` §1 领域模型)
- 列出所有**名词实体**(用户、订单、会话…)
- 标注每个实体的字段、关系、生命周期
- 标记哪些是**持久化实体**,哪些是**瞬态状态**
### Step 3 — 模块划分(产出 `ARCHITECTURE.md` §2 模块清单)
对照领域模型与需求功能清单,拆分模块。每个模块写一张卡片:
```
## 模块名:<Name>
- 职责:一句话
- 不负责:明确写出"不做什么"(防止职责蔓延)
- 输入:从哪些模块/外部来
- 输出:暴露给谁
- 关键类型/接口:列签名(不写实现)
- 持有状态:有没有自己的状态?
```
**经验**:如果一个模块的"不负责"写不出来,说明它的职责还没想清楚,回到 Step 2。
### Step 4 — 依赖图(产出 `ARCHITECTURE.md` §3 依赖图)
- 画出模块间依赖箭头(推荐 Mermaid,纯文本可 diff
- **手动验证 DAG**:从任一节点 DFS 不应回到自己
- 标出"接口边界":哪些依赖是接口注入,哪些是直接调用
### Step 5 — 路线图(产出 `ROADMAP.md`
按依赖图的拓扑顺序排开发节奏:
- 先做被依赖最多的底层模块
- 每个 milestone 必须能独立通过编译/构建并跑出某种"可见行为"
- 写明每个 milestone 完成的"验收标准"(不是"做完了",是"做完了之后能演示什么")
### Step 6 — 开发规范(产出 `CONVENTIONS.md`
- 命名(类型 / 文件 / 目录 / 资产)
- 代码风格(缩进 / 注释策略 / 错误处理边界)
- 提交规范
- 测试策略(哪些必须有测试,哪些不要求)
### Step 7 — 派生文档(产出实现 spec / 资产清单等)
**只有上面 6 步都齐了,才能开始写派生文档**。
派生文档必须显式引用上游章节("对应 `ARCHITECTURE.md` §2.3 的 XxxService 模块"),方便后续 diff 校验。
---
## 4. 文档变更协议
文档不是写完就锁死的,但变更必须**沿着上下游传播**:
| 变更点 | 必须同步更新 |
|---|---|
| 需求加/删/改功能 | 架构模块清单、路线图、派生文档 |
| 架构调整模块边界 | 依赖图、开发规范(如有命名调整)、派生文档 |
| 加新模块 | 架构 §2 + §3、路线图、开发规范(如新目录) |
**权威链**`PRD.md > ARCHITECTURE.md > CONVENTIONS.md > 派生文档`
派生文档永远不能**反向**修改上游。如果在派生文档中发现矛盾,回去改上游,再让派生文档重新对齐。
**代码与架构漂移 > 24 小时即违规。**
---
## 5. 实施日志(execution log
写代码 / 执行路线图期间,**每完成一个可独立验收的"部分",必须在 `.project.agents/log` 写一份日志**。日志是给"下一个会话的我"看的 —— 让接手的会话能在不读所有代码的情况下知道:刚才完成了什么、哪些提交、下一步是什么。
### 5.1 何时写日志
- 完成一个路线图 milestone
- 完成一个 milestone 内独立可验收的子任务
- 完成一次非平凡的重构 / bug 修复
- 当前会话即将结束时(兜底,把上下文沉淀下来)
**判断标准**:如果这段工作下一个会话需要知道,就写。
### 5.2 日志文件命名
`.project.agents/log/YYYY-MM-DD-<slug>.md`
- `<slug>` = 简短动词 + 范围,kebab-case
- 同日多份日志按写作顺序累积(不覆盖、不合并),文件名加序号后缀:`-1``-2`
### 5.3 日志内容模板
```markdown
# <一句话标题:完成了什么>
- **日期**YYYY-MM-DD
- **关联**:路线图 M<N> / 子任务名 / 关联文档
- **会话上下文**:(可选)本会话从哪开始接手的
## 做了什么
- bullet 1
- bullet 2
## 提交
- `<short hash>` <commit subject>
(若本段未提交:明确写"未提交,工作树状态:…"并说明原因)
## 状态变更
- 架构文档:是否动过?动了哪一节?
- 需求/UI 文档:是否触发回归?
- 测试:跑了什么,结果
## 下一步
- 接下来要做的第一件事(具体到任务名)
- 已知阻塞 / 待澄清项
```
### 5.4 与提交的关系
日志**不替代** commit messagecommit message 仍按 `CONVENTIONS.md` 写;日志是提交的**索引与解释**。
### 5.5 不写日志的情况
- 还没完成一个"可独立验收"的部分 —— 不要"写日志凑数"
- 纯文档调整 —— commit 自身已足够说明
- 实验性探索(最终被回滚的内容)—— 用 commit message 记录即可
---
## 6. 出问题时的排查流程
bug 来了不要直接钻进代码。按下列顺序:
1. **复现并定位现象**:能在哪个入口 / 哪个调用稳定复现?
2. **回到架构图**:这个现象涉及哪些模块?沿着依赖图圈出可能责任方。
3. **审查接口契约**:跨模块调用是否符合 `ARCHITECTURE.md` 中声明的接口?输入输出是否符合契约?
4. **缩小到单模块**:把嫌疑缩小到一个模块后,再读该模块代码。
5. **修复并回写经验**:如果发现是架构层面的漏洞,修完代码后**必须更新 `ARCHITECTURE.md``CONVENTIONS.md`**。
**反模式**:bug 一来就 grep 关键字、改一行试一下、再改一行试一下 —— 这是死亡螺旋,必须用流程压下去。
---
## 7. 反模式清单("看到这些立刻警觉")
- 出现语义为空的模块名(`Manager` / `Helper` / `Util` / `Common` / `Misc` / `Tools`)且行数 > 100 行
- 一个文件 import 超过 10 个本地模块
- 改一个 UI 改动需要动 3 个以上其他模块
- 同一份业务逻辑在两个地方各写了一遍
- PR 描述写"顺便修了 X"
- 新增功能时发现"无处归属",于是塞进入口文件或主组件
- 文档与代码不一致超过 24 小时
- 出现没有在 `ARCHITECTURE.md` 中登记的新模块/新依赖方向
任何一条出现,**先停下来回到本指南或架构文档,不要继续往前推**。
---
## 8. 本项目当前阶段
> 本节随项目演进,不是规则的一部分。由 Agent 在每个 milestone 后更新。
<!-- 由 /ads:init2026-08-19Retrofit)填入:本项目为后端微服务模板,治理已入位。 -->
- 当前状态:后端模板(`abacus.springboot.example`)已完成治理落地(Retrofit),分层以示例模块实际结构为准(api/controller/dao/esb/pi/impl/repository/wsi/config/util/vo);前后端共享约束单源化于工作区 `docs/``../../../docs/coding-standards.md`)。
- 下一步合规动作:新业务模块按 `docs/coding-standards.md §5`(后端规范)与 §7(AI 生成工作流)开发;任何新增包、依赖方向或 SQL 变更先回写本仓库 `ARCHITECTURE.md``sql/` 约定,再写代码。