--- name: zentao-misc description: "禅道反馈、工单、应用管理、附件改名。当用户说「提个反馈」「开个工单」「工单关掉」「建个应用」「改一下附件名字」时使用。" --- # 禅道反馈 / 工单 / 应用 / 附件 **前置:先读 `zentao-shared`(尤其"路径参数不出现在 inputSchema 里"一节)。** --- ## 反馈(feedback) ``` get_products_productID_feedbacks(productID, ...) get_feedbacks_feedbackID(feedbackID) post_feedbacks({ payload: { product, title, module?, type?, desc?, feedbackBy?, source? } }) put_feedbacks_feedbackID({ feedbackID, payload: {...} }) delete_feedbacks_feedbackID({ feedbackID }) put_feedbacks_feedbackID_close({ feedbackID, payload: { closedReason, comment? } }) put_feedbacks_feedbackID_activate({ feedbackID, payload: {...} }) ``` **创建字段名注意:所属产品叫 `product`,不是 `productID`**(跟大多数其他实体不一致, `zentao-plan` 的 build/release 也是这个坑)。 **"没有反馈/工单"和"参数传错"在这两个接口上长得一模一样**:实测发现某个产品下没有 反馈/工单记录时,后端返回的是 `HTTP 200` + **完全空的响应体**,跟 `zentao-shared` 里说的 "路径参数传漏/传错 → 静默返回空结果"是同一种表现。`zentao-shared` 那条"先怀疑参数 传漏了,再怀疑数据本身"的排查顺序在这两个接口上不管用——换任何一个真实存在的 `productID` 都可能一样是空的。真要鉴别,换个已知有数据的接口(比如 `get_products`) 确认这个 productID 本身没写错,或者直接问用户这个产品下是否本来就没有反馈/工单。 `type`(反馈类型)受限枚举:`story` 需求 | `task` 任务 | `bug` Bug | `todo` 待办 | `advice` 建议 | `issue` 问题 | `risk` 风险 | `opportunity` 机会——这个类型决定了反馈 可能被后续转化成对应的实体,跟用户确认清楚类型再提交。 `closedReason` 关闭必填,受限枚举:`commented` 已处理 | `repeat` 重复 | `refuse` 不予采纳。 关闭前按 `zentao-shared` 全局约定跟用户确认原因。 --- ## 工单(ticket) ``` get_products_productID_tickets(productID, ...) get_tickets_ticketID(ticketID) post_tickets({ payload: { product, title, module?, type?, desc?, assignedTo?, deadline?, openedBuild? } }) put_tickets_ticketID({ ticketID, payload: {...} }) delete_tickets_ticketID({ ticketID }) put_tickets_ticketID_close({ ticketID, payload: { closedReason, comment } }) put_tickets_ticketID_activate({ ticketID, payload: {...} }) ``` 同样是 `product` 不是 `productID`。`type`(工单类型)受限枚举:`code` 程序报错 | `data` 数据错误 | `stuck` 流程卡断 | `security` 安全问题 | `affair` 事务。 `openedBuild`(影响版本)**是字符串数组**,可以关联多个版本,不是单个 ID,跟 `zentao-bug` 里 `openedBuild` 的数组结构是同一个模式。 **关闭工单 `closedReason` 和 `comment` 都必填**(反馈关闭只要求 `closedReason`,工单 两个都要)——`closedReason` 枚举:`commented` 已处理 | `repeat` 重复 | `refuse` 不予处理。 --- ## 应用(system) ``` get_products_productID_systems(productID, ...) post_systems({ payload: { productID, integrated, children, name, desc? } }) put_systems_systemID({ systemID, payload: {...} }) ``` **没有查询单条应用详情、也没有删除应用的接口**(只有创建/修改),这跟其他实体都不一样, 需要删除或者查看单条详情要引导用户去网页端。 **`get_products_productID_systems` 实测对部分账号会返回 `HTTP 403 Access not allowed`**—— 应用管理看起来受账号权限控制,不是所有 Token 都能查。403 时先怀疑是权限不够(提示用户 去禅道网页确认自己有没有应用管理权限),不要当成参数错误去排查。 四个必填字段里 `integrated`(是否集成应用:`0` 否 | `1` 是)和 `children`(集成应用需要 包含哪些其他应用的 ID 列表,非集成应用传空数组 `[]`)都容易漏传——创建前先问清楚这个 应用是不是"集成应用"(把多个子应用打包发布的那种),决定这两个字段怎么填。 --- ## 附件改名(file) ``` put_files_fileID({ fileID, payload: { fileName } }) ``` **这套 MCP 工具里附件相关能力只有改名这一个**(`zentao-shared` 已提过):上传新附件、 删除附件都不在工具列表里,需要引导用户去网页端操作。`fileName` 必填,改名会连带更新 附件的扩展名(如果新文件名里带了不同的后缀)。