--- name: zentao-story description: "禅道需求管理:用户故事(story)、业务需求(epic)、用户需求(requirement)三条需求线的创建、变更、关闭、激活。当用户说「提个需求」「这个需求变更一下」「需求关闭了」「史诗需求」时使用。" --- # 禅道需求管理(story / epic / requirement) **前置:先读 `zentao-shared`(尤其"路径参数不出现在 inputSchema 里"一节——本技能的 `get_epics_storyID`/`get_requirements_storyID` 就是那条规则里点名的例外命名)。** --- ## 三条需求线是什么关系 禅道把"需求"拆成三种独立实体,**不是同一张表的三个状态**,是三套平行的 API: | | 中文 | 路径前缀 | 典型用途 | |---|---|---|---| | story | 用户故事 | `/stories` | 敏捷开发里最常用的最小需求单元 | | epic | 业务需求 | `/epics` | 更粗粒度、跨多个 story 的业务目标 | | requirement | 用户需求 | `/requirements` | 来自用户侧的原始需求,未必等于最终交付的 story | 三者创建字段结构完全一样(`productID`/`title` 必填,`pri`/`module`/`parent`/`estimate`/ `spec`/`category`/`source`/`verify`/`assignedTo`/`reviewer` 可选),管理动作也对称 (改 / 变更 change / 关闭 close / 激活 activate / 删除),**用户说"需求"时先确认是要 哪一种**,不要默认都当 story 处理——三者互不包含,建错类型对方看不到。 --- ## 详情接口的路径参数命名例外(必读) ``` get_stories_storyID(storyID) 需求详情 get_epics_storyID(storyID) 业务需求详情 —— 参数字面叫 storyID,不是 epicID get_requirements_storyID(storyID) 用户需求详情 —— 参数字面叫 storyID,不是 requirementID ``` 这是禅道官方 API 本身的命名(不是这个 MCP 网桥引入的),照抄传 `storyID` 就行,别自己 "纠正"成语义上更合理的名字,传错名字会静默返回空结果(见 `zentao-shared`)。 --- ## 查 ``` get_products_productID_stories(productID, browseType?, orderBy?, recPerPage?, pageID?) get_projects_projectID_stories(projectID, ...) get_executions_executionID_stories(executionID, ...) get_products_productID_epics(productID, ...) get_products_productID_requirements(productID, ...) ``` `browseType` 常见取值:`allstory` 全部 | `assignedtome` 指派给我 | `openedbyme` 我创建 | `reviewbyme` 待我评审 | `draftstory` 草稿——不传默认是 `unclosed`(未关闭的)。 --- ## 建 ``` post_stories({ payload: { productID, title, pri?, module?, parent?, estimate?, spec?, category?, source?, verify?, assignedTo?, reviewer?, project?, execution? } }) post_epics({ payload: { productID, title, ... 同上(无 project/execution) } }) post_requirements({ payload: { productID, title, ... 同上(无 project/execution) } }) ``` `productID`/`title` 必填,其余可选。`reviewer` 一旦设置,**该需求就必须经过评审**—— 问清楚用户是否真的需要评审流程再决定填不填。`category`/`source` 是受限枚举(类别/来源), 取值以工具 description 为准,写错直接报错。 只有 story 能挂 `project`/`execution`(关联具体项目或迭代),epic/requirement 没有这两个字段。 --- ## 变更(change) ``` put_stories_storyID_change({ storyID, payload: { reviewer, title?, spec?, verify? } }) put_epics_epicID_change({ epicID, payload: { reviewer, title?, spec?, verify? } }) put_requirements_requirementID_change({ requirementID, payload: { title?, spec?, verify? } }) ``` **`reviewer` 必填这条规则只对 story 和 epic 成立**——变更这两类需求必须指定评审人, 不能跳过评审直接改。**requirement 的变更接口没有 `reviewer` 这个参数,也没有任何必填 字段**,三者看起来对称,实际上 requirement 少一层评审约束,不要照搬 story/epic 的调用 方式给 requirement 传 `reviewer`(传了会被当成多余字段,不生效)。 注意这里改的路径参数名恢复正常(`epicID`/`requirementID`),跟上面"详情接口"那个 `storyID` 例外命名不是一回事,两套接口的路径参数名不一样,调用前对照工具名确认。 --- ## 关闭(close) ``` put_stories_storyID_close({ storyID, payload: { closedReason, comment? } }) ``` `closedReason` 必填,受限枚举:`done` 已完成 | `subdivided` 已拆分 | `duplicate` 重复 | `postponed` 延期 | `willnotdo` 不做 | `cancel` 已取消 | `bydesign` 设计如此。 **关闭前必须先跟用户确认关闭原因**(`zentao-shared` 的全局约定:状态流转类操作先确认), 不要因为用户说"这个需求做完了"就自动挑一个理由关掉——`done` 和用户实际想表达的可能 不是一回事(比如其实是想选 `subdivided` 已拆成子需求)。 --- ## 激活(activate) ``` put_stories_storyID_activate({ storyID, payload: { assignedTo?, comment? } }) put_epics_epicID_activate({ epicID, payload: { assignedTo?, comment? } }) put_requirements_requirementID_activate({ requirementID, payload: { assignedTo?, comment? } }) ``` 三者字段结构一样,都没有必填字段,用于把已关闭/已拆分的需求重新打开。 --- ## 删 ``` delete_stories_storyID({ storyID }) delete_epics_epicID({ epicID }) delete_requirements_requirementID({ requirementID }) ``` 不可逆,删除前必须确认(`zentao-shared` 全局约定)。