--- name: feature-tdd description: 统一功能循环第 2 步(后端 REQ / 前端 FE 共用,由 phase 参数区分)。按 plan 逐任务做 TDD(失败测试 → 实现 → 通过 → commit),所有测试运行强制派发到 Agent 子会话,主会话只接收 JSON 结果。 user-invocable: false allowed-tools: Read Write Edit Agent Skill Bash(git add *) Bash(git commit *) --- **所有输出必须使用中文。** # feature-tdd 按合并文档(spec + plan)的任务级计划逐任务做 TDD:写失败测试 → 写最小实现 → 确认通过 → commit。**所有测试运行强制派发到 Agent 子会话**,主会话只接收 JSON 结果。 **入参(由 feature-spec 传入):** - `phase`:`backend` | `frontend` - `id`:`REQ-XXX-NNN`(backend)或 `FE-NN`(frontend) --- ## 阶段差异 ### phase=backend - 工作分支:`module-` - `impl_file` 不得以 `frontend/` 开头(见护栏) - 测试命令:`./scripts/test.sh`(由子会话执行) - Schema 改动前置:有 migration 需求时,第一个任务必须是写 migration + 同步 docs/03 - 提交 trailer:`REQ-XXX-NNN` 标签(内嵌在 commit subject 中) ### phase=frontend - 工作分支:`frontend-phase` - `impl_file` 必须以 `frontend/` 开头(见护栏) - 测试命令:从 `docs/04-技术规范.md § 零 frontend` 取: - `frontend.unit_test_runner`:vitest / jest(默认 vitest) - `frontend.e2e_runner`:playwright(默认 playwright) - `frontend.test_command` / `frontend.e2e_command`(缺失则用 `pnpm test:ci` / `pnpm e2e:ci`) - **无** SQL migration 步骤 - 提交 trailer:`REQ_ID: FE-NN`(作为 commit trailer 行) --- ## 执行步骤 1. **加载 spec + plan**:读取 `docs/superpowers/specs/-.md`,定位 `## 任务级计划` 节。 2. **Schema 改动前置**(仅 `phase=backend`,且 plan 声明需要时):第一个任务必须是写 migration 文件 + 同步更新 docs/03,并一起 commit。 - 文件命名 `V__.sql`,`` = 现有 `sql/migrations/V*.sql` 最大版本号 + 1;文件只含 DDL - **同步**把新 CREATE / ALTER 反向更新到 `docs/03-数据库设计文档.md` 对应表小节,保持 docs/03 是 schema 的 SSoT;新增表按表小节模板追加 - migration + docs/03 改动**同一 commit**,避免 SSoT 与 migration 分裂 - 测试运行时 Spring Boot 启动 Flyway 会自动 apply 新 migration 3. **按顺序处理每个代码类任务**: a. 在 `test_file::test_name` 处写**失败**测试: - `phase=backend`:JUnit / 框架测试 - `phase=frontend`,`测试先行类型=jsdom`:在 jsdom 环境下用 vitest/jest 写组件单测(render + 断言 DOM / 交互后状态变化) - `phase=frontend`,`测试先行类型=e2e`:在 `frontend/e2e/` 写 Playwright 测试(headless) b. 派发 Agent 子会话(general-purpose)运行该测试,子会话只返回 `{command, exit_code, failing_assertion}` JSON,确认失败 c. 在 `impl_file` 处写**最小**实现使测试通过。**严格遵守**: - `phase=backend`:`impl_file` 不得以 `frontend/` 开头(违反 → 护栏硬停) - `phase=frontend`:`impl_file` 必须以 `frontend/` 开头(违反 → 护栏硬停);色值用 `var(--color-*)`(来自 spec「Design Tokens 引用清单」节),不硬编码 hex;业务校验按 spec「业务规则前端复刻清单」节在 form-level 复刻 d. 再次派发子会话确认通过 e. 同一测试 >10 次修复仍失败 → 调用 `Skill(interrupt-check)`(中断 #1:测试反复失败) f. 按 `${CLAUDE_SKILL_DIR}/templates/commit-message-template.md` 格式 commit: - `phase=backend`:`scope` = 任务模块;`subject` ≤ 50 字符;trailer `REQ_ID: REQ-XXX-NNN` - `phase=frontend`:`scope` = 组件名(如 `dashboard` / `user-form`);`subject` ≤ 50 字符;trailer `REQ_ID: FE-NN` 4. **全部任务完成** → 调用 `Skill(feature-review)` 传入 `{ phase, id }` --- ## 护栏 - **绝不**在主会话直接跑任何测试命令(`mvn test` / `pnpm test` / `scripts/test.sh` / `pnpm playwright` / `vitest`),必须通过子会话 - **绝不**在主会话直接 `mysql -e "ALTER ..."`;业务 schema 改动一律走 `sql/migrations/V*.sql` 文件(只读查询 / 临时调试除外) - **后端阶段路径硬护栏(phase=backend)**:任务表里的 `impl_file` 路径以 `frontend/` 开头 → 硬停并打印: ``` feature-tdd 后端阶段不允许写前端代码:。请检查 plan 任务定义;UI 推迟到前端阶段(phase=frontend)。 ``` - **前端阶段路径硬护栏(phase=frontend)**:`impl_file` 路径**不以** `frontend/` 开头,或命中 `backend/` / `sql/` / `scripts/` → 硬停并打印: ``` feature-tdd 前端阶段不允许写非前端文件:。前端阶段任务的 impl_file 必须落在 frontend/ 目录下。 ``` - 不硬编码颜色 hex(`phase=frontend`);token 引用必须对齐 spec「Design Tokens 引用清单」节 --- ## 参考 - `${CLAUDE_SKILL_DIR}/templates/commit-message-template.md` - 守门:`interrupt-check`(仅在步骤 3.e 触发,条件 1) - 原则参考:`superpowers:test-driven-development`(外部 TDD 原则手册,本 skill 已固化"子会话跑测试 + REQ-tagged commit"流程,不做运行时 invoke) - 上游:`feature-spec` - 下游:`feature-review`