[Bug] 修复飞书直通接口的分页约束与角色权限适配
- Dominant language
- TypeScript
- Stars
- 2.7k
- Forks
- 395
- Avg merge
- 21h 48m
- Merged PRs (30d)
- 776
Description
## 问题描述
XD Feishu 插件生成的部分 OpenAPI 直通工具与飞书实际接口契约不一致,导致插件向模型暴露了会被服务端拒绝的参数,且新版多维表格角色接口在当前 OAuth 授权下不可用。
### 1. `calendar.v4.calendar.list` 缩小分页后失败
- 插件将 `page_size` 描述为任意 `num`。
- 飞书官方要求 `page_size` 为整数,取值范围为 `50–1000`。
- `page_size: 20` 会被插件接受并发送到服务端,随后返回 `field validation failed`。
### 2. `calendar.v4.calendarEvent.list` 的合法参数组合无法被可靠使用
- 该接口同样缺失 `page_size` 的 `50–1000` 约束。
- `page_size: 1` 会先被服务端拒绝,掩盖 `start_time`、`end_time` 等其他参数的验证结果。
- 当前源码实际会把 `page_size`、`start_time`、`end_time` 正确序列化到 URL query,因此问题不是 query 未转发,而是插件暴露的参数契约不完整。
### 3. 多维表格角色列表存在废弃接口和 OAuth scope 错配
- 插件仍暴露已废弃的 `bitable.v1.appRole.list`。
- 推荐接口 `base.v2.appRole.list` 已经暴露,但插件 OAuth scopes 缺少该接口要求的 `base:role:read`,导致已连接账号无法调用新版接口。
- v1 返回 `OperationTypeError` 时,飞书官方含义是多维表格未启用或不支持高级权限,不能据此判断 v1 服务端已经停止提供服务;但官方已经明确推荐迁移到 v2。
## 根因
1. `packages/lizi-mcps/src/feishu/mcp/generated/zod/calendar_v4.ts` 中两个接口的 `page_size` 仅声明为 `z.number()`,没有整数、最小值和最大值约束。
2. `scripts/gen-feishu-ghost-ops.mts` 将 Zod/JSON Schema 压缩成参数说明时只保留字段类型,没有保留 `minimum`、`maximum` 等校验信息;生成的 `main.js` 也不会在出网前校验这些约束。
3. 直通接口生成策略没有过滤或降级标记已有替代接口的 Deprecated 工具。
4. `apps/desktop/resources/builtin-ghosts/xd-feishu/ghost.json` 申请了 `bitable:app`,但没有申请新版角色接口唯一要求的 `base:role:read`。
## 期望行为
- 两个日历接口明确展示并校验 `page_size` 为 `50–1000` 的整数。
- 无效参数在插件本地返回可读错误,不向飞书发送必然失败的请求。
- `calendar.v4.calendarEvent.list` 支持 `start_time`、`end_time` 与合法 `page_size` 的组合。
- 角色列表默认引导使用 `base.v2.appRole.list`。
- OAuth 申请 `base:role:read`,并为已连接账号提供明确的补授权路径。
- 不再把废弃 v1 接口作为普通可选接口展示;如果因兼容旧高级权限仍需保留,应明确标记适用范围和 v2 替代接口。
## 验收标准
- [ ] `page_size: 50` 和 `page_size: 1000` 可正常发起请求。
- [ ] `page_size: 1`、`page_size: 20`、`page_size: "20"` 在本地被拒绝且不出网。
- [ ] 回归测试断言两个日历接口生成的 URL 包含完整 query。
- [ ] 使用合法 `page_size` 时,`calendar.v4.calendarEvent.list` 的 `start_time`、`end_time` 可以正常传递。
- [ ] `base.v2.appRole.list` 在补授权后可正常调用。
- [ ] `list_tools` 优先展示 v2,且不会误导模型调用废弃 v1。
- [ ] 增加参数约束、Deprecated 接口处理和 OAuth scope 的回归测试。
## 实现建议
### Commit 1:补齐直通接口参数约束与本地校验
- 改动:完善 vendored schema 的同步/覆盖机制和 `scripts/gen-feishu-ghost-ops.mts`,让生成结果保留整数、最小值、最大值等约束;在 `gop` 出网前执行确定性校验,并重新生成 `xd-feishu/main.js`。
- 验证:扩展 `builtinFeishuGhost.test.ts` 和 `genToolsDispatch.test.ts`,覆盖合法边界值、非法数字、字符串类型、query 序列化以及非法参数不出网。
### Commit 2:迁移角色列表到 v2 并补齐授权
- 改动:在 `ghost.json` 增加 `base:role:read`,调整生成过滤/展示策略,优先使用 `base.v2.appRole.list`,并处理已有连接账号的补授权提示或检测。
- 验证:更新 manifest scopes 契约测试和直通工具目录测试;使用已开启高级权限的多维表格完成一次 v2 角色列表实测。
## 参考文档
- [查询日历列表](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/calendar-v4/calendar/list)
- [获取日程列表](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/calendar-v4/calendar-event/list)
- [列出自定义角色(旧版)](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/bitable-v1/app-role/list)
- [列出自定义角色(新版)](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/bitable-v1/advanced-permission/base-v2/app-role/list)
Contributor guide
Research direction
Start with packages/lizi-mcps/src/feishu/mcp/generated/zod/calendar_v4.ts, scripts/gen-feishu-ghost-ops.mts, and apps/desktop/resources/builtin-ghosts/xd-feishu/ghost.json to trace schema constraints, tool generation, and OAuth scopes. Then read builtinFeishuGhost.test.ts and genToolsDispatch.test.ts and run the related tests. Done means local validation rejects invalid pagination without a request, valid query parameters survive, v2 role listing has the required scope, and deprecated v1 handling is covered by regression tests.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- api, authentication, tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 48/100