Commit 22b5005b6d34f0fd5ce2a9aada9ee1b9dca9efce

Authored by zichun
1 parent 840dcf7f

workflow: req_id 子模块代码/功能名改大驼峰(不限长度)

- 子模块代码:大写短码(USR/ROLE) → 大驼峰英文名、不限长度(UserInfo/Role)
- 功能名:英文大写 [A-Z0-9_]/下划线(PWD_RESET) → 大驼峰 [A-Za-z0-9]/直接拼接(PwdReset)
- 模块代码不变(大写短码 USR);结构仍 <模块代码>-<子模块代码>-<功能名> 恒 3 段
- 规范示例统一 USR-USR-LOGIN → USR-UserInfo-Login;docs-01 五列示例行同步
- 同步 7 文件:README/coding.mjs/scope-lock/docs-01/CLAUDE/plan-start/docs-04
README.md
... ... @@ -133,7 +133,7 @@ erp-workflow-plugin/
133 133 | # | Skill | 作用 | 流程中谁调用 |
134 134 |---|---|---|---|
135 135 | A0 | `project-init` | • **依赖检查**:检测 git / mysql / node 是否在 PATH,缺失则按 OS 自动安装,装不上再停下提示用户<br>• 空目录初始化:用 Read/Write/Glob 工具拷模板创建 CLAUDE.md / docs/01/index.md / docs/08<br>• `git init` | `plan-start` |
136   -| A1 | `scope-lock` | • 引导填项目概述 / 技术栈 / 需求索引<br>• 按 `docs/01-需求清单/<module>/{_module.md, <req_id>.md}` 子目录结构生成 REQ 卡片(req_id = `<模块代码>-<子模块代码>-<功能名>`,如 `USR-USR-LOGIN`;CC 据 index.md 填 `{{req_id/title/goal/rules/constraints/acceptance}}` 6 个占位,模板其余内容含输入/输出示例字段表原样复制)<br>• **A1 终结校验**:REQ 6 个占位均填真实数据、无 `{{` 残留、`config-vars.yaml` **全部配置**(包名 / 端口 / 初始账号 + DB 凭据 / 密钥占位)已锁、各 stack 的 build/lint/unit/e2e 命令写入 docs/04 § 零;缺失则在此(Plan 期)用 `AskUserQuestion` 问清(敏感凭据由用户自填,不进会话)<br>• 据模板直接 `Write` 生成 `_module.md` / `<req_id>.md`<br>• 终结校验通过后**自动**调用 `Skill(skeleton-gen)` 进入 A2(不停下) | A0 |
  136 +| A1 | `scope-lock` | • 引导填项目概述 / 技术栈 / 需求索引<br>• 按 `docs/01-需求清单/<module>/{_module.md, <req_id>.md}` 子目录结构生成 REQ 卡片(req_id = `<模块代码>-<子模块代码>-<功能名>`,如 `USR-UserInfo-Login`;CC 据 index.md 填 `{{req_id/title/goal/rules/constraints/acceptance}}` 6 个占位,模板其余内容含输入/输出示例字段表原样复制)<br>• **A1 终结校验**:REQ 6 个占位均填真实数据、无 `{{` 残留、`config-vars.yaml` **全部配置**(包名 / 端口 / 初始账号 + DB 凭据 / 密钥占位)已锁、各 stack 的 build/lint/unit/e2e 命令写入 docs/04 § 零;缺失则在此(Plan 期)用 `AskUserQuestion` 问清(敏感凭据由用户自填,不进会话)<br>• 据模板直接 `Write` 生成 `_module.md` / `<req_id>.md`<br>• 终结校验通过后**自动**调用 `Skill(skeleton-gen)` 进入 A2(不停下) | A0 |
137 137 | A2 | `skeleton-gen` | • 生成架构文档:docs/04 § 一+<br>• 生成跨平台工具脚本:`scripts/*.mjs`(**无 chmod**;凭据 / 配置统一在 A1 产出的 config-vars.yaml)<br>• 据 `gitignore-append-template` 用 Read/Write 并入项目 .gitignore | `plan-start` |
138 138 | A3 | `db-design-gen` | • 套用固定 ERP 约定(列前缀 `i/s/t`、`iIncrement` 主键、`sBrandsId`/`sSubsidiaryId` 租户列)从 docs/01 REQ 卡片正向设计 `docs/03-数据库设计文档.md`(schema SSoT)<br>• 回填 REQ 卡片依赖表(`TBD(A3 自动补)` → 实际表名)<br>• **停下**等人工审阅 docs/03,审阅完毕用 `/plan-start` 续进 A4 | A2 |
139 139 | A4 | `db-init` | • LLM 解析 docs/03 → `sql/migrations/V1__initial_schema.sql`(DDL only)<br>• `node ${CLAUDE_PLUGIN_ROOT}/lib/validate-ddl.mjs` 校验 DDL ↔ docs/03(5 维:表/列名/列类型/索引/FK),fail-closed<br>• `node ${CLAUDE_PLUGIN_ROOT}/lib/apply-ddl.mjs config-vars.yaml V1.sql`(读取 config-vars.yaml database: 段 + mysql2 apply) | A3 |
... ...
skills/plan/plan-start/SKILL.md
... ... @@ -46,7 +46,7 @@ A 阶段 checkbox 全部 `[x]` 后先跑下面 4 项前移闸门; 全过才放
46 46 1. **REQ 卡片真实数据**(来自 A1 scope-lock)
47 47 - `Glob` 找出全部 REQ 卡片(如 `docs/01-需求清单/**/*.md`)。
48 48 - 对每张卡片 `Grep` 命中以下任一即缺口: `【人工填写` / `TBD` / `{{`(`{{` = 6 个标量占位未替换;`TBD` = A3/A5 应回填的依赖表/依赖接口仍未补——A1 时这些 `TBD(A3/A5 自动补)` 是合法保留,到本闸必须已解析,故此处比 scope-lock E.1 多查 `TBD`/`【人工填写`)。
49   - - 缺口表述示例:`USR-USR-LOGIN 仍含 TBD / {{title}} 占位未替换`。
  49 + - 缺口表述示例:`USR-UserInfo-Login 仍含 TBD / {{title}} 占位未替换`。
50 50  
51 51 2. **全部配置全锁**(来自 A1 写入 `config-vars.yaml` 的非敏感配置 + 敏感凭据,单一文件)
52 52 - `Read` `config-vars.yaml`(项目全部配置,含敏感凭据,随项目提交):校验所有字段均无 `【人工填写`/`TBD`;除 `database.password` 可显式为空串外,其余字段不得为空——含非敏感项(`backend`/`frontend` 包名 / 端口、`admin_init.username`、`database.host/port/user/schema`)与敏感项(`admin_init.password`、`secrets.*`)。
... ... @@ -95,7 +95,7 @@ A 阶段 checkbox 全部 `[x]` 后先跑下面 4 项前移闸门; 全过才放
95 95  
96 96 <逐条列出每个缺口,格式:[闸门] 缺口描述 → 回填位置>
97 97 例:
98   - [REQ 真实数据] USR-USR-LOGIN 仍含 {{goal}} 占位未替换 → docs/01-需求清单/...
  98 + [REQ 真实数据] USR-UserInfo-Login 仍含 {{goal}} 占位未替换 → docs/01-需求清单/...
99 99 [配置] database.password 仍是占位(如本地空密码请显式填 `''`)→ config-vars.yaml
100 100 [docs/04 §零] node 栈缺 e2e 命令 → docs/04-技术规范.md §零
101 101  
... ...
skills/plan/project-init/templates/CLAUDE-template.md
... ... @@ -20,7 +20,7 @@
20 20 1. **严格遵循** `docs/04-技术规范.md`——命名 / 编码 / 统一响应 / 异常处理 / 数据访问 / 配置与安全 等项目专属技术规约全部在此
21 21 2. **严格遵循** `docs/04-技术规范.md § 1.2 分层结构 / § 2.1 目录约定`——文件放对位置
22 22 3. **每个后端接口** 必须先在 `docs/05-API接口契约.md` 定义,再编码实现
23   -4. **每个功能可追溯到 req_id `<模块代码>-<子模块代码>-<功能名>`**——commit tag + 代码注释(如 `// USR-USR-LOGIN: 用户登录`)+ plan/spec 文件名均用此 tag
  23 +4. **每个功能可追溯到 req_id `<模块代码>-<子模块代码>-<功能名>`**——commit tag + 代码注释(如 `// USR-UserInfo-Login: 用户登录`)+ plan/spec 文件名均用此 tag
24 24 5. **遇到跨模块改动**(动到非当前模块的代码)——允许改,但必须在《模块完成报告》记录原因 / 影响评估(留痕)
25 25  
26 26 ### 你禁止做的 🚫
... ... @@ -56,7 +56,7 @@
56 56 ```
57 57  
58 58 - `scope`: 模块名,如 `user` / `inventory` / `order`
59   -- `subject`: 简短描述;业务类(feat / fix / test)必须带 req_id(`<模块代码>-<子模块代码>-<功能名>`,如 `USR-USR-LOGIN`)后缀
  59 +- `subject`: 简短描述;业务类(feat / fix / test)必须带 req_id(`<模块代码>-<子模块代码>-<功能名>`,如 `USR-UserInfo-Login`)后缀
60 60  
61 61 `type` 含义:
62 62  
... ...
skills/plan/project-init/templates/docs-01-index-template.md
1 1 # 需求清单
2 2  
3   -> 本目录按模块组织所有功能需求。每个模块一个子目录,含 `_module.md`(模块头)和 `<req_id>.md`(每张 REQ 卡片一个文件;req_id = `<模块代码>-<子模块代码>-<功能名>` 恒 3 段,如 `USR-USR-LOGIN`——功能名由 CC 据核心功能点推断:英文大写短词、字符集 `[A-Z0-9_]`、多词用下划线如 `PWD_RESET`、同一 模块-子模块 内唯一)。下方核心功能点供 CC 拆分出 req_id + 标题 + 草拟规则;卡片内输入 / 输出的简述句和 N 张字段表由人工编辑。
  3 +> 本目录按模块组织所有功能需求。每个模块一个子目录,含 `_module.md`(模块头)和 `<req_id>.md`(每张 REQ 卡片一个文件;req_id = `<模块代码>-<子模块代码>-<功能名>` 恒 3 段,如 `USR-UserInfo-Login`——模块代码为大写短码(如 `USR`);子模块代码用大驼峰英文名、不限长度(如 `UserInfo`);功能名由 CC 据核心功能点推断:大驼峰英文、字符集 `[A-Za-z0-9]`、多词直接拼接如 `PwdReset`、同一 模块-子模块 内唯一)。下方核心功能点供 CC 拆分出 req_id + 标题 + 草拟规则;卡片内输入 / 输出的简述句和 N 张字段表由人工编辑。
4 4  
5 5 ## 模块索引
6 6  
... ... @@ -9,5 +9,5 @@
9 9 | 模块代码 | 模块名称 | 子模块代码 | 子模块名称 | 核心功能点(简要) |
10 10 |----------|----------|------------|------------|--------------------|
11 11 | 【人工填写:模块代码】 | 【人工填写:模块名称】 | 【人工填写:子模块代码】 | 【人工填写:子模块名称】 | 【人工填写:核心功能点】 |
12   -| USR | 用户管理 | USR | 用户账户 | 登录/注销/改密 等 |
13   -| USR | 用户管理 | ROLE | 角色权限 | 角色 CRUD/权限分配 等 |
  12 +| USR | 用户管理 | UserInfo | 用户信息 | 增加用户/修改用户/查询用户/登录 等 |
  13 +| USR | 用户管理 | Role | 角色权限 | 角色 CRUD/权限分配 等 |
... ...
skills/plan/scope-lock/SKILL.md
... ... @@ -21,14 +21,14 @@ allowed-tools: Read Write Edit Grep Glob Skill AskUserQuestion Bash(mkdir *)
21 21  
22 22 - **A**:`CLAUDE.md` § 🎯 项目概述。占位符含项目名称 / 简述 / 目标用户 / 部署方式。
23 23 - **B**:`docs/04-技术规范.md` § 零。让用户检查 / 调整默认技术栈表(删不需要的行 / 改技术 / 加条目)。
24   -- **C**:`docs/01-需求清单/index.md`。让用户按业务列出所有子模块(一行一个子模块,五列:模块代码/模块名称/子模块代码/子模块名称/核心功能点;同一模块有多个子模块时写多行,如 USR-USR / USR-ROLE / PUR-ORD),「核心功能点」给关键词即可,CC 会拆 REQ 卡片。
  24 +- **C**:`docs/01-需求清单/index.md`。让用户按业务列出所有子模块(一行一个子模块,五列:模块代码/模块名称/子模块代码/子模块名称/核心功能点;同一模块有多个子模块时写多行,如 USR-UserInfo / USR-Role / PUR-Order),「核心功能点」给关键词即可,CC 会拆 REQ 卡片。
25 25  
26 26 ### D. 生成 REQ 卡片骨架并停下等人工审阅
27 27  
28 28 1. 读 `index.md` 解析模块索引(五列,一行一个子模块;按「模块代码」聚合——同一模块的多行共用一个模块子目录);读两个模板 `${CLAUDE_SKILL_DIR}/templates/_module-template.md`、`${CLAUDE_SKILL_DIR}/templates/req-card-template.md` 作为卡片结构参照。
29 29 2. **每模块/每 REQ 直接 `Write`**:对每个模块先 `mkdir -p "docs/01-需求清单/<MOD>-<模块名>"`,再照模板结构 `Write`,`<MOD>` / `<模块名>` / `<req_id>` 按 `index.md` 实际值替换:
30 30 - **模块头** `_module.md`:据 `index.md` 填 `module_code` / `module_name` / `module_brief`(module_brief 汇总该模块全部子模块行的核心功能点);`依赖模块: TBD(A5 自动补)` / `涉及表: TBD(A3 自动补)` 两行原样保留。
31   - - **每个 REQ** `<req_id>.md`(req_id = `<模块代码>-<子模块代码>-<功能名>` 恒 3 段,如 `USR-USR-LOGIN`;功能名由 CC 据该行核心功能点推断:英文大写短词、字符集 `[A-Z0-9_]`、多词用下划线如 `PWD_RESET`、同一 模块-子模块 内唯一;文件名 == req_id):**照模板原样 `Write`**,只把 `{{req_id}}` / `{{title}}` / `{{goal}}` / `{{rules}}` / `{{constraints}}` / `{{acceptance}}` 这 6 个占位替换为据 `index.md` 推断的真实值;模板其余内容(`输入` / `输出` 示例字段表、`依赖表: TBD(A3 自动补)` / `依赖接口: TBD(A5 自动补)` 两行)**原样复制不动**;模板顶部 HTML 引导注释**不写进产物**。
  31 + - **每个 REQ** `<req_id>.md`(req_id = `<模块代码>-<子模块代码>-<功能名>` 恒 3 段,如 `USR-UserInfo-Login`;模块代码为大写短码、子模块代码用大驼峰英文名不限长度(如 `UserInfo`)、功能名由 CC 据该行核心功能点推断:大驼峰英文、字符集 `[A-Za-z0-9]`、多词直接拼接如 `PwdReset`、同一 模块-子模块 内唯一;文件名 == req_id):**照模板原样 `Write`**,只把 `{{req_id}}` / `{{title}}` / `{{goal}}` / `{{rules}}` / `{{constraints}}` / `{{acceptance}}` 这 6 个占位替换为据 `index.md` 推断的真实值;模板其余内容(`输入` / `输出` 示例字段表、`依赖表: TBD(A3 自动补)` / `依赖接口: TBD(A5 自动补)` 两行)**原样复制不动**;模板顶部 HTML 引导注释**不写进产物**。
32 32 3. 用 `Edit` 在 `docs/08-模块任务管理.md` 勾选(A1 子项):
33 33 - ` - [ ] REQ 卡片骨架已生成(docs/01-需求清单/<module>/<req_id>.md,业务内容留待人工填写)`
34 34 4. 打印「请人工填写 REQ 卡片」横幅并提示用户填完后回来继续:
... ...
skills/plan/skeleton-gen/templates/docs-04-skeleton-template.md
... ... @@ -34,7 +34,7 @@
34 34 ## 三、共同约定
35 35  
36 36 ### 3.1 Git 提交
37   -`<type>(<scope>): <subject> <req_id>`(req_id = `<模块代码>-<子模块代码>-<功能名>`,如 `USR-USR-LOGIN`)
  37 +`<type>(<scope>): <subject> <req_id>`(req_id = `<模块代码>-<子模块代码>-<功能名>`,如 `USR-UserInfo-Login`)
38 38  
39 39 ### 3.2 分页查询
40 40  
... ...
workflows/coding.mjs
... ... @@ -237,7 +237,7 @@ function featureStageContract(phase) {
237 237 `- **阶段 = ${fe ? '前端(frontend)' : '后端(backend)'}**。路径作用域:${fe
238 238 ? '实现文件必须落在 `frontend/` 下;命中 `backend/` / `sql/` / `scripts/` 即越界,硬停。'
239 239 : '产出范围限定 controller / service / repository / DTO / 校验 / SQL migration / REST 契约;**禁止**写 `frontend/` 路径下的实现(UI 推迟到前端阶段)。'}`,
240   - `- id 形态:${fe ? '前端为 `FE-NN`(业务功能粒度,可关联多个 prototype 区域与多个 REQ)。' : '后端为 `<模块代码>-<子模块代码>-<功能名>`(3 段大写 req_id,如 `USR-USR-LOGIN`)。'}`,
  240 + `- id 形态:${fe ? '前端为 `FE-NN`(业务功能粒度,可关联多个 prototype 区域与多个 REQ)。' : '后端为 `<模块代码>-<子模块代码>-<功能名>`(3 段 req_id,模块代码大写短码 + 子模块代码/功能名大驼峰,如 `USR-UserInfo-Login`)。'}`,
241 241 ].join('\n')
242 242 }
243 243  
... ... @@ -1321,7 +1321,7 @@ function classifyCrossModulePromptM(moduleId, files) {
1321 1321 '- 落在共享根(如 `docs/`、`scripts/`、`sql/migrations/`、`README.md` 等)→ **不算**跨模块。',
1322 1322 '',
1323 1323 '## 输出(CROSS_CLASSIFY_SCHEMA)',
1324   - '- `{ "crossModule": [ { "file": "...", "targetModule": "module_x", "reason": "<本模块哪个 REQ(req_id,如 USR-USR-LOGIN)迫使改它,1 句>", "impact": "<目标模块哪些 API/行为/调用方/测试受影响,1-3 句>" }, ... ] }`',
  1324 + '- `{ "crossModule": [ { "file": "...", "targetModule": "module_x", "reason": "<本模块哪个 REQ(req_id,如 USR-UserInfo-Login)迫使改它,1 句>", "impact": "<目标模块哪些 API/行为/调用方/测试受影响,1-3 句>" }, ... ] }`',
1325 1325 '- 无跨模块改动:`{ "crossModule": [] }`',
1326 1326 '- **不要留 `TBD(CC 补)`**:本步骤就是补齐的唯一时机;推不出原因 / 影响 → 整步失败(schema 失败即可,调用方会 halt)。',
1327 1327 ].join('\n')
... ...