# API 接口约定 本文件是后端接口路径、请求响应格式、错误码和分页格式的唯一事实源。spec 只描述业务边界,不重复完整接口返回。 ## 1. 通用规则 1. 所有业务接口使用 `/api` 前缀。 2. 请求和响应使用 JSON。 3. 时间字段使用 ISO 8601 字符串,并统一保存为服务器时区感知时间。 4. 列表接口默认分页。 5. 动作类接口使用 `POST /api/{resources}/{id}/{action}`。 6. 飞书回调接口必须单独记录原始 payload。 7. 后端必须做权限校验,不能只靠前端隐藏入口。 8. 涉及权限、安全、日志脱敏、飞书验签和幂等时,以 `docs/contracts/安全权限日志约定.md` 为准。 ## 2. 统一响应格式 成功: ```json { "success": true, "data": {}, "error": null, "request_id": "req_20260622_xxx" } ``` 失败: ```json { "success": false, "data": null, "error": { "code": "permission_denied", "message": "当前用户无权执行该操作", "detail": {} }, "request_id": "req_20260622_xxx" } ``` 分页: ```json { "success": true, "data": { "items": [], "page": 1, "page_size": 20, "total": 0 }, "error": null, "request_id": "req_20260622_xxx" } ``` ## 3. 通用错误码 | code | HTTP | 含义 | | --- | --- | --- | | `validation_error` | 400 | 请求字段校验失败 | | `unauthenticated` | 401 | 未登录或登录态失效 | | `permission_denied` | 403 | 当前用户无权操作 | | `not_found` | 404 | 对象不存在或不可见 | | `state_conflict` | 409 | 当前状态不允许该操作 | | `idempotency_conflict` | 409 | 幂等键冲突或重复请求 | | `card_expired` | 409 | 飞书卡片、通知或一次性操作链接已失效 | | `ai_parse_failed` | 422 | AI 输出无法解析或不符合结构 | | `ai_model_failed` | 502 | 百炼或模型网关失败,重试后仍不可用 | | `missing_person_mapping` | 422 | 缺少人员映射 | | `memory_store_failed` | 500 | AI 对话记忆、消息或 BotContext 保存/读取失败 | | `draft_convert_failed` | 500 | 草稿确认后转换任务或提醒失败 | | `feishu_signature_invalid` | 401 | 飞书回调验签失败 | | `feishu_api_failed` | 502 | 飞书接口调用失败 | | `reminder_trigger_failed` | 500 | 定时提醒触发失败 | | `internal_error` | 500 | 未分类服务端错误 | ## 4. 用户与人员映射 | 方法 | 路径 | 作用 | 权限 | | --- | --- | --- | --- | | GET | `/api/users/me` | 获取当前用户 | 已登录 | | GET | `/api/users` | 用户列表 | 管理员 / AI 团队 | | GET | `/api/auth/feishu/login` | 发起飞书扫码登录 / 身份登录 | 公开 | | GET | `/api/auth/feishu/callback` | 飞书登录回调 | 公开回调 | | POST | `/api/auth/logout` | 退出登录 | 已登录 | | GET | `/api/person-mappings` | 人员映射列表 | 管理员 / AI 团队 | | POST | `/api/person-mappings` | 新增人员映射 | 管理员 / AI 团队 | | PATCH | `/api/person-mappings/{id}` | 修改人员映射 | 管理员 / AI 团队 | | POST | `/api/person-mappings/{id}/resolve-feishu` | 根据手机号或邮箱解析飞书身份 | 管理员 / AI 团队 | ## 5. Prompt 上下文 | 方法 | 路径 | 作用 | 权限 | | --- | --- | --- | --- | | GET | `/api/prompt-contexts` | 查看提示词上下文配置 | 管理员 / AI 团队 | | PATCH | `/api/prompt-contexts/{id}` | 修改提示词上下文配置 | 管理员 / AI 团队 | | POST | `/api/prompt-contexts/{id}/activate` | 启用某个提示词上下文版本 | 管理员 / AI 团队 | ## 6. AI 草稿 | 方法 | 路径 | 作用 | 权限 | | --- | --- | --- | --- | | POST | `/api/secretary/handle-message` | 统一老板消息入口,返回草稿、追问、普通回复、上下文回顾或错误降级 | 老板;调试入口需管理员 token | | GET | `/api/ai-drafts` | 草稿列表 | 相关用户、程经理、管理员 | | GET | `/api/ai-drafts/{id}` | 草稿详情 | 相关用户、程经理、管理员 | | PATCH | `/api/ai-drafts/{id}` | 修改草稿字段 | 草稿发起人、待确认程经理 | | POST | `/api/ai-drafts/{id}/confirm` | 确认草稿 | 草稿发起人、待确认程经理 | | POST | `/api/ai-drafts/{id}/cancel` | 取消草稿 | 草稿发起人 | | POST | `/api/ai-drafts/{id}/convert` | 转换为事项或提醒 | 草稿发起人、待确认程经理 | | POST | `/api/ai-drafts/{id}/follow-up` | 根据补充/重说重新生成草稿 | 草稿发起人 | `POST /api/secretary/handle-message` 请求示例: ```json { "source": "feishu", "message_id": "msg_xxx", "sender": { "open_id": "ou_xxx", "name": "老板", "role": "boss" }, "text": "明天上午提醒东东给我订会议室", "context": {} } ``` 响应 `data` 建议包含: - `intent` - `reply_type` - `answer` - `draft` - `questions` - `context_summary` - `failure` `reply_type` 建议取值: - `draft_preview` - `follow_up_question` - `plain_answer` - `context_summary` - `unsupported` - `error` `note` / `unknown` / `qa` / `realtime_qa` / `need_more_info` / `unsupported` 不得创建事项、提醒或通知;如需留痕,只返回回复、追问、上下文摘要或失败信息。 兼容接口 `/api/ai-drafts/parse`、`/api/demo/boss-message` 可以保留,但内部必须转发到 `/api/secretary/handle-message`。 ## 7. 事项 | 方法 | 路径 | 作用 | 权限 | | --- | --- | --- | --- | | GET | `/api/tasks` | 事项列表 | 相关用户、程经理、管理员 | | POST | `/api/tasks` | 手动创建事项 | 老板、程经理 | | GET | `/api/tasks/{id}` | 事项详情 | 相关用户、程经理、管理员 | | PATCH | `/api/tasks/{id}` | 修改事项 | 发起人、程经理 | | POST | `/api/tasks/{id}/manager-confirm` | 程经理确认复杂事项 | 指定程经理 | | POST | `/api/tasks/{id}/cancel` | 取消事项 | 发起人、程经理 | | POST | `/api/tasks/{id}/notify` | 发送或补发通知 | 发起人、程经理、管理员 | | POST | `/api/tasks/{id}/feedback` | 平台内反馈 | 接收人 | ## 8. 定时提醒 | 方法 | 路径 | 作用 | 权限 | | --- | --- | --- | --- | | GET | `/api/reminders` | 提醒列表 | 相关用户、程经理、管理员 | | POST | `/api/reminders` | 创建提醒 | 已登录;给别人创建需老板或程经理 | | GET | `/api/reminders/{id}` | 提醒详情 | 相关用户、程经理、管理员 | | PATCH | `/api/reminders/{id}` | 修改提醒 | 创建人、发起人、管理员 | | POST | `/api/reminders/{id}/pause` | 暂停提醒 | 创建人、发起人、管理员 | | POST | `/api/reminders/{id}/resume` | 恢复提醒 | 创建人、发起人、管理员 | | POST | `/api/reminders/{id}/cancel` | 取消提醒 | 创建人、发起人、管理员 | | POST | `/api/reminders/{id}/notify` | 手动补发提醒通知 | 创建人、发起人、管理员 | | POST | `/api/reminders/{id}/feedback` | 平台内反馈 | 接收人 | ## 9. 通知、反馈和失败 | 方法 | 路径 | 作用 | 权限 | | --- | --- | --- | --- | | GET | `/api/notifications` | 通知记录列表 | 相关用户、程经理、管理员 | | GET | `/api/notifications/{id}` | 通知详情 | 相关用户、程经理、管理员 | | POST | `/api/notifications/{id}/retry` | 通知补发 | 发起人、程经理、管理员 | | GET | `/api/feedbacks` | 反馈列表 | 相关用户、程经理、管理员 | | GET | `/api/failure-records` | 失败记录列表 | 管理员 / AI 团队;必要时程经理 | | GET | `/api/failure-records/{id}` | 失败详情 | 管理员 / AI 团队;必要时程经理 | | PATCH | `/api/failure-records/{id}` | 更新处理状态 | 管理员 / AI 团队 | | POST | `/api/failure-records/{id}/resolve` | 填写处理结果并标记已处理 | 管理员 / AI 团队 | ## 10. 飞书回调 | 方法 | 路径 | 作用 | 权限 | | --- | --- | --- | --- | | POST | `/api/feishu/events` | 飞书事件回调,包含机器人消息事件 | 飞书验签 | | POST | `/api/feishu/bot/messages` | 可选:单独承接机器人私聊消息 | 飞书验签 | | POST | `/api/feishu/card-callback` | 飞书卡片回调 | 飞书验签 | 飞书回调要求: 1. 必须验签。 2. 必须记录原始 payload 到 `feishu_events`。 3. 必须使用 `event_id` 幂等;没有稳定 `event_id` 时必须使用 `idempotency_key`。 4. 验签失败不得执行业务动作。 5. 草稿确认类卡片必须校验 `ai_drafts.active_card_notification_id`。 6. 旧卡片、失效卡片、已替代草稿和已过期通知的回调只记录 `feishu_events`,不写业务对象。 7. 回调处理失败必须写入 `failure_records`。 ## 11. 敏感信息返回边界 1. API 不返回 API Key、App Secret、飞书 token。 2. 手机号和邮箱默认脱敏返回,除非管理员维护页确有需要。 3. 飞书通知只发送摘要和链接,不发送敏感全文。 4. 模型调用日志对外接口默认不返回完整 prompt 和原始大段上下文。 5. 飞书原始 payload、模型原始请求/响应、OAuth code/state、一次性操作 token 和回调验签密钥的访问边界以 `安全权限日志约定.md` 为准。