# CLAUDE.md — ERP项目 Claude Code 主指令文件 > 本文件是 Claude Code 的"操作手册"。Claude Code 启动时会自动读取此文件。 --- ## 🎯 项目概述 - **项目名称**: 小羚羊 - **项目简述**: 测试ERP - **目标用户**: 企业内部管理人员 - **部署方式**: 私有化部署 --- ## 🔄 B 阶段开发流程(后端模块循环 → 前端整体阶段) B 阶段分两段,**全部固化到 skills**。入口:`/erp-workflow:coding-start`。 ### 阶段路由(coding-start 内,只做分发) `coding-start` 每次入口做两段完成性检查后真值表派发: - 后端完成性检查 → `backend_done`(扫 docs/08 § 二 + GitLab state) - 前端完成性检查 → `frontend_done`(扫 docs/08 § 三 整体 MR + state) | `backend_done` | `frontend_done` | 派发 | |---|---|---| | `false` | 任意 | `module-start`(写后端) | | `true` | `false` | `frontend-start`(写前端) | | `true` | `true` | "所有阶段已完成" | 前端阶段前置(prototype/ 门禁)由 `frontend-start` 自带,不在 coding-start。`module-start` 与 `frontend-start` **互不感知对方**。 ### 后端阶段(每模块一个 MR) - **模块循环(外)**:`module-start` → `test-gate(phase=backend)` → `module-report` → `mr-create` → 人工 Approve MR → 用户重跑 coding-start → coding-start 再次路由 - **功能循环(内,每 REQ-XXX-NNN 一遍)**:`feature-brainstorm` → `feature-plan` → `feature-tdd` → `feature-verify` → `feature-review` - 后端阶段任务严格落在 `backend/` 路径下;docs/01 REQ 卡片的 UI 描述在此阶段忽略,UI 推迟到前端阶段。 ### 前端阶段(整体一个 MR,所有后端模块 merged 后启动) - **FE 清单(AI 自主推导,无审阅断点)**:`frontend-start` 进入时扫 prototype + docs/01 + docs/05 → AI 自主推导 FE 业务功能清单写入 `docs/08 § 三`(已有则加载)。**FE 是业务功能粒度,与 prototype HTML 文件数无关**——一个 HTML 可拆多个 FE,多个 HTML 也可合成一个 FE。FE 清单的合理性由 fe-feature-review / mr-create 在整体 MR 提交时一并校核(人工只在 MR Approve+Merge 处介入)。 - **FE 循环(外)**:`frontend-start` → fe-feature 循环 → `test-gate(phase=frontend)` → `module-report(phase=frontend)` → `mr-create`(分支 `frontend-phase`,docs/08 § 三 整体 MR)。 - **FE 功能循环(内,每个 FE-NN 一遍)**:`fe-feature-brainstorm` → `fe-feature-plan` → `fe-feature-tdd` → `fe-feature-verify` → `fe-feature-review`(专用 `fe-code-reviewer` agent,硬编码 7 维 review checklist) - 前端阶段任务严格落在 `frontend/` 路径下;布局以 `prototype/` 为权威。 ### MR 前测试闸门 - `test-gate`:后端阶段子会话跑 `scripts/test.sh`(含本模块新增 + 已合并模块回归);前端阶段子会话跑 vitest + playwright。 - `.githooks/pre-push` 兜底;`git push --no-verify` 被 `deny-no-verify.sh` 硬拦。 --- ## ✅ 阶段完成判定规则 `docs/08-模块任务管理.md` 分两段: - `§ 二`:后端模块元数据表(每个模块一行 bullet,记录依赖 / 路径 / MR iid / 功能子项) - `§ 三`:前端阶段元数据(整体 MR + FE 子项清单,由 `frontend-start` 在所有后端模块 merged 后填入) **阶段完成判定**统一以 `MR:` 字段(§ 二 各模块) / `整体 MR:` 字段(§ 三)+ `GitLab API state=merged` 判定;子项勾选只作可视化进度,不参与完成判定。 ### 后端模块格式 每个后端模块在 docs/08 § 二 中长这样: ```markdown - module_0 系统管理 - 依赖: — - 路径: backend/module/sys/ - MR: — - 功能: - [ ] REQ-SYS-001 用户登录 - [ ] REQ-SYS-002 用户注册 ``` - `MR:` 字段由 `mr-create` 在创建 MR 时从 `—` 改为 `!`。 - 每个 `REQ-*` 子项由 `feature-review` 在 `verdict=approve` 时自动勾选为 `[x]`。 - 路径限定为后端目录(如 `backend/module/sys/`);前端代码不在此阶段产生。 ### 前端阶段格式(§ 三) ```markdown - 整体 MR: — - 功能: - [ ] FE-01 用户登录与注册 | 关联 REQ:REQ-SYS-001, REQ-SYS-002 | 关联原型:prototype/auth.html - [ ] FE-02 仪表盘总览 | 关联 REQ:REQ-DASH-001 | 关联原型:prototype/dashboard.html ``` - `整体 MR:` 字段由 `mr-create` 在创建前端 MR 时从 `—` 改为 `!`。 - "功能:" 列表由 `frontend-start` 进入时由 AI 自主推导写入(无人工审阅断点)。FE 是业务功能粒度,与 prototype HTML 文件数无关;合理性由 fe-feature-review / 整体 MR 时统一校核。 - 每个 `FE-NN` 子项由 `fe-feature-review` 在 `verdict=approve` 时自动勾选为 `[x]`。 - 进入前端阶段前 `frontend-start` 步骤 1 自带 prototype/ 门禁,强制检查项目根 `prototype/` 至少含 1 个 `*.html` mockup。 ### 状态语义(后端模块 + 前端阶段共用) | `MR:` 字段 | `GitLab API state` | 含义 | 你(Claude Code)的行为 | |---|---|---|---| | `—` | — | 该阶段未开始(未创建 MR) | ✅ 开始该阶段开发 | | `!` | `opened` / `closed` | 阶段开发中 / 打回 | ✅ 继续推进该阶段 | | `!` | `merged` | 阶段**已完成** | 🟢 后端:进入下一未完成模块;后端全完 → 前端阶段;前端 merged → 全部完成 | ### 模块完成报告 由 `module-report` skill 产出,模板位于 由 module-report skill 持有(12 节标准化,含跨模块改动等 CLAUDE.md 软规则映射节)。CC 不手写模块报告,仅填模板。 --- ## 🏷️ 占位符统一约定 项目文档里有 **2 种填写占位** + **1 种提示占位**: | 格式 | 谁填 | 使用阶段 | 说明 | |------|-----|---------|------| | `【人工填写:<简短说明>】` | 人 | 仅 A 阶段文档 | 密钥 / 账密 / 包名 / 命名约定 / 小版本号等人工才能决定的值;B 阶段 plan/spec 禁止出现,查不到真值时用 `AskUserQuestion` 问用户 | | `TBD(<责任人>)` | CC 自动 | A 或 B | 后缀附带责任方(如 `TBD(A3 自动补)` / `TBD(A5 自动补)`);由对应 skill 就地补填,`module-report` § ⑦ 检查 `TBD(CC 补)` 残留 | **HTML 注释 ``**:提示占位,是**插件内部大纲模板**里给 LLM 的**填空提示 / 章节引导**,指引 LLM 按结构填实际内容。skill 生成时会**剥除**这些注释,最终产物里注释不会保留。 --- ## 📐 编码行为约束 ### 你必须做的 ✅ 1. **严格遵循** `docs/04-技术规范.md`——命名 / 编码 / 统一响应 / 异常处理 / 数据访问 / 配置与安全 等项目专属技术规约全部在此 2. **严格遵循** `docs/09-项目目录结构.md`——文件放对位置 3. **每个后端接口** 必须先在 `docs/05-API接口契约.md` 定义,再编码实现 4. **每个功能可追溯到 `REQ-XXX-NNN`**——commit tag + 代码注释(如 `// REQ-SYS-001: 用户登录`)+ plan/spec 文件名均用此 tag 5. **遇到跨模块改动**(动到非当前模块的代码)——按 § 🟡 软规则 **S2** 执行(允许改,但必须留痕) 6. **遇到技术栈外组件引入**(`docs/04 § 零` 技术栈表外的框架 / 中间件 / 关键库),按 § 🟡 软规则 **S1** 执行(允许引入,但必须先 AskUserQuestion) ### 你禁止做的 🚫 1. **主会话直接 `mysql -e` 跑业务 DDL**(只读查询 / 临时本地调试 / A4 `db-init` 首次 apply V1 验证除外)——业务 schema 必须走 `sql/migrations/V_n__*.sql`,详见下方 Schema 演化规约。**A4 例外**:`db-init` 在 A 阶段 setup-test-db 后会一次性手工 `mysql < V1__initial_schema.sql` 把 V1 灌入测试库,并校验 `SHOW TABLES` 行数 = docs/03 表数量,用于 DDL 自检;B 阶段(Spring Boot 启动后)Flyway 会重建 schema 并 apply 全部 migration(包括 V1),手工 apply 不会污染 Flyway 历史。 2. **手动 Edit `docs/08 § 二/§ 三` 的 `MR:` / `整体 MR:` 字段**,必须要由 `mr-create` 自动回写 ### Schema 演化规约(Flyway migration) 1. **文件命名**:`sql/migrations/V__.sql`,例:`V5__add_user_email_unique_index.sql` 2. **版本号分配**:建文件前 `ls sql/migrations/V*.sql` 查当前最大 n,新文件 `n_max + 1` 3. **Apply 方式**:Spring Boot 启动 / 测试启动时 Flyway 自动 apply(项目必须在 `pom.xml` 声明 `flyway-core` + `flyway-mysql` 依赖)。`scripts/setup-test-db.sh` 只负责清空库,不做 apply 4. **已合并的 migration 永不修改**:发现错了写一个补救 migration(如 `V7__fix_V5_index_name.sql`),旧 `V_n.sql` 5. **临时调试 DDL**:临时在本地试字段/索引可手动 `mysql -e`,但不写 migration;下次 `setup-test-db.sh` 会 drop+create 清掉 6. **A4 生成的 V1**:`V1__initial_schema.sql` 是 A 阶段由 `db-init` 从 `docs/03-数据库设计文档.md`(A3 正向设计的 schema SSoT)翻译生成的初始版本;后续 V2/V3/... 由 B 阶段每个 REQ 按需写入,**同时**反向同步更新 docs/03 对应表小节以保持 SSoT 一致 --- ## 🗂️ Git 提交规范 每次提交必须遵循以下格式: ``` (): ``` - `scope`: 模块名,如 `user` / `inventory` / `order` - `subject`: 简短描述;业务类(feat / fix / test)必须带 `REQ-XXX-NNN` 后缀 `type` 含义: | type | 看到它意味着 | |-----|-------------| | `feat` | **新能力上线**——用户多了一个功能、接口、页面或业务规则 | | `fix` | **修 bug**——原来行为错了,这次改对 | | `refactor` | **重构**——外部行为不变,只改代码结构 / 命名 / 抽象 | | `docs` | **文档改动**——只动 Markdown / 代码注释,不动实现 | | `style` | **格式调整**——空白 / 缩进 / import 顺序,逻辑 0 变化 | | `test` | **只动测试代码**——补用例 / 修 fixture,不碰实现 | | `chore` | **流程维护**——构建 / 依赖 / 工具 / 证据档案 / MR 元数据等非业务动作 | --- ## 🚩 中断机制 功能循环(每个功能 REQ-XXX 的 Brainstorm → Plan → TDD → Verify → AI 自审)默认 **静默编程**,但触发以下任何一条必须**立刻停下、记录原因、等人决策**,不得自行绕过: | # | 中断 | 例子 | | - | --- | --- | | 1 | **测试反复失败** | 同一测试同一功能内连续 **10 次**修复失败 | | 2 | **要改密钥 / 账密 / 包名** | `docs/07-环境配置.md` 里由人工标注必须填的字段 | | 3 | **外部接口不可达** | 第三方 API 无法连接、证书失效等环境问题,并无法自行解决 | > 其余需要人类判断的场景一律走普通 `AskUserQuestion` Q&A,不中断、不写 Blocker 文件。 **触发中断时的固定动作:** 1. 在当前功能的 plan 文件里追加一节 `## 🚩 Blocker`(报告格式由 `interrupt-check` 的 `interrupt-block-template.md` 持有) 2. 停止后续所有功能的静默执行 3. 在主会话输出一句话摘要 + 指向 blocker 文件的路径,等人回复 --- ## 🟡 软规则(允许继续,但有强制后续动作) 以下情况 **不触发中断**,CC 可自行继续推进,但必须在约定位置留痕,模块完成时统一审计。 | # | 软规则 | 允许动作 | 强制后续 | | - | ----- | ------- | ------- | | S1 | **技术栈外组件引入** | 用 `AskUserQuestion` 给用户三选一:接受引入 / 换方案 / 拒绝 | ① **接受** → 同会话直接在 `docs/04 § 零` 追加一行 → 继续流程 ② **换方案 / 拒绝** → 视为常规歧义澄清,继续 Q&A 收敛 ③ 不写 Blocker、不中断流程 | | S2 | **跨模块改动** | **默认不改**,仅为当前模块实现所必需时允许修改 | ① hook `log-cross-module.sh` 自动落存根 ② `module-report` 一次性调用 `cross-module-log` skill 批量补齐「原因 / 影响评估」+ 「跨模块改动」节完整贴入《模块完成报告》 | --- ## 🧭 通用工作准则(General Principles) ### 1. Think Before Coding **Don't assume. Don't hide confusion. Surface tradeoffs.** Before implementing: - State your assumptions explicitly. If uncertain, ask. - If multiple interpretations exist, present them - don't pick silently. - If a simpler approach exists, say so. Push back when warranted. - If something is unclear, stop. Name what's confusing. Ask. ### 2. Simplicity First **Minimum code that solves the problem. Nothing speculative.** - No features beyond what was asked. - No abstractions for single-use code. - No "flexibility" or "configurability" that wasn't requested. - No error handling for impossible scenarios. - If you write 200 lines and it could be 50, rewrite it. Ask yourself: "Would a senior engineer say this is overcomplicated?" If yes, simplify. ### 3. Surgical Changes **Touch only what you must. Clean up only your own mess.** When editing existing code: - Don't "improve" adjacent code, comments, or formatting. - Don't refactor things that aren't broken. - Match existing style, even if you'd do it differently. - If you notice unrelated dead code, mention it - don't delete it. When your changes create orphans: - Remove imports/variables/functions that YOUR changes made unused. - Don't remove pre-existing dead code unless asked. The test: Every changed line should trace directly to the user's request. ### 4. Goal-Driven Execution **Define success criteria. Loop until verified.** Transform tasks into verifiable goals: - "Add validation" → "Write tests for invalid inputs, then make them pass" - "Fix the bug" → "Write a test that reproduces it, then make it pass" - "Refactor X" → "Ensure tests pass before and after" For multi-step tasks, state a brief plan: ``` 1. [Step] → verify: [check] 2. [Step] → verify: [check] 3. [Step] → verify: [check] ``` Strong success criteria let you loop independently. Weak criteria ("make it work") require constant clarification.