--- name: feature-spec description: 统一功能循环第 1 步(后端 REQ / 前端 FE 共用,由 phase 参数区分)。交互式 Q&A → 产出"规格 + 任务级 TDD 计划"合并文档到 docs/superpowers/specs/,链入 feature-tdd。 user-invocable: false allowed-tools: Read Write Grep Glob Skill AskUserQuestion Bash(mysql *) --- **所有输出必须使用中文。** # feature-spec 统一功能循环第 1 步,后端(REQ-XXX-NNN)和前端(FE-NN)共用,由 `phase` 参数区分范围与上下文。交互式 Q&A → 产出"规格 + 任务级 TDD 计划"合并文档 → 链入 `feature-tdd`。 **入参(由上游 skill 传入):** - `phase`:`backend` | `frontend` - `id`:`REQ-XXX-NNN`(backend)或 `FE-NN`(frontend) - `name`:功能名称 - `associated_reqs[]`:(仅 frontend)关联的 REQ 卡片 id 列表 - `associated_prototypes[]`:(仅 frontend)关联的 prototype 文件路径列表 --- ## 占位符规则 本 skill 写的 spec 是 CC 内部推理产物,不是用户审阅文档。**不允许** `【人工填写:...】` 占位符——A 阶段标记只在 `docs/01~10` / `CLAUDE.md` / `.env.local` 使用。需要具体值时: 1. **先查** `.env.local` + `docs/04 §零环境` / `CLAUDE.md` / 现有代码 / 关联 prototype(frontend 时)。值已落地某处 → spec 中引用源(例 "JWT_SECRET 从 `.env.local` 读取,`application.yml` 用 `${JWT_SECRET}` 注入") 2. **再问**:查不到 → `AskUserQuestion` 问用户,记录答案到 spec 3. **绝不**留 `【人工填写:】` 占位符;若 1 + 2 都解决不了,spec 必须写出具体阻塞点(不是泛化占位符),Q&A 继续直到解决 --- ## 阶段范围 ### phase=backend 产出范围限定为:controller / service / repository / DTO / 校验 / SQL migration / REST 契约。 读 `docs/01-需求清单//.md` 时**忽略 UI 描述**(输入控件类型、按钮位置、列表布局等),但**校验规则、业务规则**仍要落到后端 DTO + service。UI 实现统一推迟到前端阶段(`phase=frontend`)。 上下文来源: - REQ 卡片 `docs/01-需求清单//.md` - 涉及的数据表定义(取自 `docs/03-数据库设计文档.md` 或实时 `mysql` 查询) ### phase=frontend 产出范围限定为:组件树 / 页面状态机 / 交互流程 / API 调用 / Design Tokens 引用 / 业务校验前端复刻。**不涉及** SQL / migration / controller / service / DTO(后端阶段已完成)。 一个 FE 是**业务功能**粒度,可能关联多个 prototype 文件区域和多个 REQ。 上下文来源: - **页面骨架**:Read 所有 `associated_prototypes[]`(含 anchor 时聚焦相应区域),作为布局权威 - **业务规则**:Read 所有 `associated_reqs[]` 对应的 `docs/01-需求清单//.md`,提取业务校验规则、acceptance、UI 描述 - **API 契约**:Read `docs/05-API接口契约.md`,按 `associated_reqs[]` 过滤出本 FE 消费的端点 - **Design Tokens / 交互约定**:Read `docs/04-技术规范.md`「前端 Design Tokens / 交互约定」段(lite 已把原 docs/06 内容并入 docs/04),作为色值 / 状态色 / 交互规范的引用源 - **前端组件库**:Read `docs/04-技术规范.md § 零` 找 `frontend.ui_lib`(如 Ant Design / Element Plus),决定组件选型 --- ## 执行步骤 ### 步骤 1:收集上下文 按上方"阶段范围"对应的上下文来源读取所有相关文档。 ### 步骤 2:评估 scope - 单 spec 容纳得下吗? - `phase=backend`:跨多个独立子系统(如"含登录 + 文件存储 + 计费 + 分析")→ 先提示分解,每个子项目独立 brainstorm - `phase=frontend`:跨多页 / 多业务 → 提示拆分,每个 FE 应独立可测试 ### 步骤 3:交互式 Q&A 参考下方"Q&A 原则"进行交互式问答: - `phase=backend`:聚焦 goal / 输入输出 / 业务规则 / 约束 / schema / API 引用 / acceptance criteria - `phase=frontend`:聚焦组件树、页面状态机、交互流程、API 调用一致性、Design Tokens 引用、业务校验前端复刻。**不要**讨论 SQL / migration / controller / service / DTO **一次一问** `AskUserQuestion`,仅对真模糊点;多选题优先。决策完成后挑一种 approach;trade-off 直接内嵌 spec,**不设确认 gate**。 ### 步骤 4:写合并文档 写到 `docs/superpowers/specs/-.md`(`id` = `REQ-XXX-NNN` 或 `FE-NN`): - 按 `${CLAUDE_SKILL_DIR}/templates/feature-spec-plan-template.md` 渲染 - **只填写当前 phase 对应的规格小节**(另一 phase 的小节留空或删除) - 规格后紧接任务级计划(plan 部分) - 计划粒度:每任务 2-5 分钟,= 一个 red-green-commit 单元 **计划写作原则(两 phase 通用):** - Plan 告诉 TDD 执行者**做什么**,不是**怎么写代码** - Plan 锁定**文件边界 + 测试意图 + API / Props 形状 + 完成判据**;代码由 TDD 红绿循环产出 - **禁止 dump 整个文件内容**到 plan(pom.xml / entity 类 / vue 组件源码 / config 文件) - `phase=backend` 任务:`impl_file` 禁止以 `frontend/` 开头;`phase=frontend` 任务:`impl_file` 必须以 `frontend/` 开头 - 每个任务含 4 步:写失败测试 → 实现最小代码 → 子会话验证 PASS → commit - `phase=frontend` 每个任务必须标注"测试先行类型":`jsdom 组件测试` 或 `Playwright E2E` 文件已存在 → 征求用户确认后覆盖。 ### 步骤 5:Spec + Plan 自审(inline 修,无须用户等待) **Spec 部分:** - **占位符扫描**:`TBD` / `TODO` / `【人工填写:】` / 含糊段 → 修(按"占位符规则"流程解决) - **内部一致性**:节与节是否矛盾?架构是否匹配功能描述? - **范围检查**:单 plan 能消化吗?还是需要分解 - **歧义检查**:任何 requirement 两种解读?挑一个写明 - `phase=frontend` 额外检查:全文不得出现 `TBD` / `@todo` / `controller` / `SQL` / `service` / `migration` → 命中则修正后重渲染 **Plan 部分:** - **占位符扫描**:`TBD` / `TODO` / `implement later` / `fill in details` / `【人工填写:】` → 修 - **Spec coverage**:skim spec 每节,能指向至少一个 task 吗?list gaps 并补 task - **类型一致性**:tasks 之间签名 / 方法名 / 属性名 / 错误码一致(Task 3 的 `clearLayers()` 和 Task 7 的 `clearFullLayers()` 是 bug) - `phase=frontend`:每个任务的 `impl_file` 路径必须以 `frontend/` 开头;命中 `backend/` / `sql/` / `scripts/` → 修正后重渲染 ### 步骤 6:输出 + 链 feature-tdd (**直接做这两件事,不要输出"回交父 skill / 交给 caller / 等下一步 / 准备好了请检查"之类的桥接叙述**——那些会被解读为 turn 结束信号) - 输出一行 `feature-spec: ` - **同一 turn 内立即** `Skill(feature-tdd)` 传入 `{ phase, id }` --- ## Q&A 原则 - **一次一问** — 不堆问题 - **多选题优先** — 答更快 - **仅对真模糊点问** — 不造确认问题 - **YAGNI** — 删 spec 中不必要的功能 - **渐进理解** — 不明白就问 - **无审批 gate** — 写 spec 即 commit;分歧落地为具体 Q&A 项,不靠"等用户确认" --- ## 任务原则 ### Plan 文件头 每个合并文档的 plan 部分必须以以下头部开始: ```markdown # [Feature Name] Implementation Plan > **Execution:** Parent skill `feature-tdd` executes this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. **Goal:** [一句话描述] **Architecture:** [2-3 句方法论] **Tech Stack:** [关键技术 / 库] --- ``` ### Task 结构 每个 task 是 red-green-commit 单元。捕获意图和边界,代码留给 TDD: ````markdown ### Task N: [组件名 / 类名] **Files:** - Create: `exact/path/to/File.java`(或 `frontend/src/...`) - Modify: `exact/path/to/Existing.java:123-145` - Test: `tests/exact/path/to/FileTest.java` - 测试先行类型: jsdom 组件测试(仅 phase=frontend 需标注) **API shape / Props shape**(只写需要约束实现的签名;内部实现留给 TDD): - `LoginService#login(LoginRequest req) : LoginResponse` - [ ] **Step 1: 写失败测试** - 测试名: `LoginServiceTest#loginWithBadPassword_incrementsFailCount_returns40101` - 意图: 错误密码 → `iLoginFailCount += 1`;第 5 次 → 设置 `tLockUntil = now + 15min`;返回码 40101 - 子会话确认 FAIL(函数/类不存在) - [ ] **Step 2: 实现最小代码** - 目标: 让 Step 1 测试通过;不多做 - 涉及文件: `LoginService.java`, `SftLoginInfoMapper.java` - [ ] **Step 3: 子会话验证 PASS** - [ ] **Step 4: Commit** - `git add <文件>` - `git commit -m "feat(sys): 登录失败计数 + 锁定 REQ-SYS-001"` ```` ### 允许的代码块场景 少数例外,需要写死而非让 TDD 自由发挥: - **DDL / migration 文件**(phase=backend):`V_n__*.sql` 的 ALTER/CREATE 语句——schema 是事实源 - **合同级常量**:API 错误码表、JWT claim 名、Redis key 模式——跨模块消费,必须锁定 - **路由配置**(phase=frontend):`routes.ts` 中 path 注册(路径是契约级) - **API client 契约**(phase=frontend):fetch 包装函数签名 + headers + 错误码 mapping - **Design Tokens 名称**(phase=frontend):`var(--color-primary)` 列表 - **测试断言形状**(可选):一句话说不清"测什么"时,给个 3-5 行断言 sketch 除此之外一律散文 + 签名描述,**不贴完整文件**。 ### 记住 - Exact file paths always - Exact commands with expected output(测试运行 + git 操作) - API signatures / class names / error codes / contract values — **必须写死** - Internal implementation code — **不写**;留给 TDD 阶段 - DRY、YAGNI、TDD、frequent commits --- ## 参考 - `${CLAUDE_SKILL_DIR}/templates/feature-spec-plan-template.md` - 上游(backend):`module-start` - 上游(frontend):`frontend-start` - 下游:`feature-tdd`