Files
th-hotel-simple/docs/project/security-access-control-boundary.md

236 lines
28 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# TH Hotel 接口暴露、权限与审计边界
## 1. 文档定位
本文是当前项目的接口安全边界总表,用于后续新增接口、大改调用方、调整权限或补审计时统一判断:
- 哪些接口给前端用户调用。
- 哪些接口给第三方系统调用。
- 哪些能力只能后端内部使用,不能暴露给前端或第三方。
- 每类接口应采用什么鉴权方式、权限码、酒店隔离和审计策略。
如本文与具体接口契约冲突:
- SuperAgent / MCP / AgentBus 对外契约以 `docs/project/integrations/superagent-api-contract.md``docs/project/integrations/superagent-mcp/README.md` 和对应集成文档为准。
- 前端展示和字段契约以 `docs/project/frontend-backend/README.md` 指向的当前有效文档为准。
- 权限、审计、暴露边界以本文为补充检查清单,接口变更时必须同步更新。
## 2. 调用方分类
| 分类 | 中文说明 | 典型调用方 | 默认鉴权方式 |
| --- | --- | --- | --- |
| `PUBLIC` | 公开基础接口,只能返回非敏感健康或登录入口信息 | 浏览器、运维探活 | 无登录;不能返回业务数据 |
| `FRONTEND_USER` | 普通业务前端接口 | 登录后的酒店业务用户 | Bearer session token + 权限码 + 酒店访问权 |
| `FRONTEND_ADMIN` | 系统管理后台接口 | 系统管理员 | Bearer session token + 管理权限码 + 管理审计 |
| `FRONTEND_DEBUG` | 调试或演示接口 | 开发、测试、受控管理员 | 环境开关 + 登录权限或临时 access key + 调试审计 |
| `THIRD_PARTY_SUPERAGENT` | SuperAgent HTTP 对接接口 | SuperAgent Runtime / Skill | HMAC-SHA256 + timestamp + nonce + body hash |
| `THIRD_PARTY_AGENTBUS` | AgentBus 实时消息入口 | AgentBus WebSocket | AgentBus Token + 环境开关 + 入库幂等 |
| `THIRD_PARTY_MCP` | SuperAgent MCP 写入工具 | SuperAgent MCP Client | Bearer Token + 工具级能力限制 |
| `INTERNAL_ONLY` | 后端内部能力,不对外直接暴露 | Worker、Adapter、Repository、Mapper | 不提供外部入口;通过 Service / Port 调用 |
## 3. 当前接口边界矩阵
### 3.1 公开和登录接口
| 接口 / 能力 | 分类 | 当前管控 | 目标管控 | 审计要求 |
| --- | --- | --- | --- | --- |
| `GET /api/health` | `PUBLIC` | 无登录;只返回健康状态 | 保持公开,但不得返回配置、版本 Secret 或数据库细节 | 不需要业务审计 |
| `POST /api/auth/login` | `PUBLIC` | 用户名密码登录,返回一次性 `access_token` | 增加登录失败频率控制和登录安全审计可后置 | 建议补登录安全审计 |
| `GET /api/auth/me` | `FRONTEND_USER` | 必须 Bearer token | 保持强制登录,返回权限、菜单和酒店上下文 | 不需要每次写业务审计 |
| `POST /api/auth/logout` | `FRONTEND_USER` | 必须 Bearer token | 保持强制登录,撤销当前 session | 可记录安全审计 |
### 3.2 前端业务接口
| 接口 / 能力 | 分类 | 当前管控 | 目标管控 | 审计要求 |
| --- | --- | --- | --- | --- |
| `GET /api/reservation/tasks` | `FRONTEND_USER` | 已强制 Bearer 登录 + `RESERVATION_TASK_READ`;支持可选 `hotel_id` 并校验酒店访问权 | 保持登录 + `RESERVATION_TASK_READ` + 酒店访问权 | 只读查询默认不写业务审计 |
| `GET /api/reservation/orders` | `FRONTEND_USER` | 已强制 Bearer 登录 + `RESERVATION_ORDER_READ`;支持可选 `hotel_id` 并校验酒店访问权 | 保持登录 + `RESERVATION_ORDER_READ` + 酒店访问权 | 只读查询默认不写业务审计 |
| `GET /api/reservation/orders/{orderId}` | `FRONTEND_USER` | 已强制 Bearer 登录 + `RESERVATION_ORDER_READ`;按订单实际所属酒店校验访问权;已返回旧 `tasks[]` 和 V4 `v4_order_tasks[]` 安全摘要时间线 | 保持登录 + `RESERVATION_ORDER_READ` + 订单所属酒店访问权V4 时间线读取按订单酒店过滤 | 只读查询默认不写业务审计;不得在 `v4_order_tasks[]` 返回邮件正文、附件 URL、AI 原始 payload 或来源通知原始 payload |
| `GET /api/reservation/tasks/{taskId}` | `FRONTEND_USER` | 已强制 Bearer 登录 + `RESERVATION_TASK_READ`;按任务实际所属酒店校验访问权 | 保持登录 + `RESERVATION_TASK_READ` + 任务所属酒店访问权 | 只读查询默认不写业务审计 |
| `GET /api/reservation/workbench-items` | `FRONTEND_USER` | 已实现 M002 V4 CP5强制 Bearer 登录 + `RESERVATION_TASK_READ` + 酒店访问权 | 保持登录 + `RESERVATION_TASK_READ` + 酒店访问权;统一返回 V4 业务订单任务和 S10/S99 来源通知摘要 | 只读查询默认不写业务审计;不得返回邮件正文、附件 URL、AI 原始 payload 或来源通知原始 payload同来源时间下使用 `updated_at` / `created_at` / 数字 ID 稳定排序 |
| `GET /api/reservation/order-tasks` | `FRONTEND_USER` | 已实现 M002 V4 CP5强制 Bearer 登录 + `RESERVATION_TASK_READ` + 酒店访问权 | 保持登录 + `RESERVATION_TASK_READ` + 酒店访问权;只返回 V4 业务订单任务,不返回 S10/S99 来源通知 | 只读查询默认不写业务审计;不得返回 AI 原始 payload`card_status` 只匹配业务 / 可处理卡,固定来源邮件展示卡不参与筛选 |
| `GET /api/reservation/order-tasks/{orderTaskId}` | `FRONTEND_USER` | 已实现 M002 V4 CP5强制 Bearer 登录 + `RESERVATION_TASK_READ` + 订单任务所属酒店访问权 | 保持登录 + `RESERVATION_TASK_READ` + 订单任务所属酒店访问权 | 只读查询默认不写业务审计;邮件正文和附件读取仍走 SourceMessage 原文权限;不得返回 `ai_payload_json` 或附件 URL同批次 `adapter_contract_errors[]` 只返回白名单诊断字段;前端普通业务卡如遇 URL-like 附件字符串必须二次脱敏 |
| `GET /api/reservation/source-notifications/{notificationId}` | `FRONTEND_USER` | 已实现 M002 V4 CP5强制 Bearer 登录 + `RESERVATION_TASK_READ` + 来源通知所属酒店访问权 | 保持登录 + `RESERVATION_TASK_READ` + 来源通知所属酒店访问权 | 只读查询默认不写业务审计;邮件正文和附件读取仍走 SourceMessage 原文权限;不得返回来源通知原始 payload 或附件 URL前端普通通知卡如遇 URL-like 附件字符串必须二次脱敏 |
| `GET /api/reservation/lookups/accounts` | `FRONTEND_USER` | 已实现 M002 V4 CP11强制 Bearer 登录 + `RESERVATION_TASK_READ` + 酒店访问权 | 保持登录 + `RESERVATION_TASK_READ` + 酒店访问权;只返回 Account code、显示名、派生 Market / Source 和目录安全元数据 | 只读查询默认不写业务审计;不得返回 PMS 原始响应、Secret 或外部同步错误详情 |
| `GET /api/reservation/lookups/room-types` | `FRONTEND_USER` | 已实现 M002 V4 CP11强制 Bearer 登录 + `RESERVATION_TASK_READ` + 酒店访问权 | 保持登录 + `RESERVATION_TASK_READ` + 酒店访问权;只返回当前酒店可选 ACTIVE 房型目录快照 | 只读查询默认不写业务审计;不得返回 PMS 原始响应、价格敏感细节或跨酒店房型 |
| `GET /api/reservation/lookups/rate-codes` | `FRONTEND_USER` | 已实现 M002 V4 CP11强制 Bearer 登录 + `RESERVATION_TASK_READ` + 酒店访问权 | 保持登录 + `RESERVATION_TASK_READ` + 酒店访问权;只返回当前酒店可选 ACTIVE Rate Code 目录快照,不做真实价格计算 | 只读查询默认不写业务审计;不得返回 PMS 原始响应、价格明细、Secret 或跨酒店 Rate Plan |
| `PUT /api/reservation/tasks/{taskId}/draft` | `FRONTEND_USER` | 第一版未全量强制登录actor 仍待迁移 | 登录 + `RESERVATION_TASK_EDIT` + 酒店访问权 | 写草稿审计可按业务需要记录 |
| `POST /api/reservation/tasks/{taskId}/confirm` | `FRONTEND_USER` | 第一版未全量强制登录actor 仍待迁移 | 登录 + `RESERVATION_TASK_CONFIRM` + 酒店访问权 | 必须写业务审计 |
| `POST /api/reservation/order-tasks/{orderTaskId}/cards/{cardId}/confirm` | `FRONTEND_USER` | 已实现 M002 V4 CP6/CP8/CP11强制 Bearer 登录 + `RESERVATION_TASK_CONFIRM` + 订单任务所属酒店访问权 + version 并发校验 + 当前酒店数据库目录校验 | 保持Basic Information 前置确认,确认后卡片锁定,不返回 AI 原始 payloadBasic Account、Room Type、Rate Code 目录错误返回 `V4_FIELD_VALIDATION_FAILED` | 必须写业务审计actor 使用当前登录用户 |
| `POST /api/reservation/order-tasks/{orderTaskId}/cards/{cardId}/review-resolution` | `FRONTEND_USER` | 已实现 M002 V4 CP7/CP8/CP11强制 Bearer 登录 + `RESERVATION_MANUAL_REVIEW_RESOLVE` + 订单任务所属酒店访问权 + version 并发校验 + 当前酒店数据库目录校验 | 保持;仅用于 V4 `REVIEW_REQUIRED` 卡,不开放普通任务任意切换订单;字段指针只允许当前卡可编辑业务字段,优先按显式 `missing_fields[]`、未解决叶子值或 `validation_errors_json` 指向字段收口;订单归属未解决时必须提交当前酒店下真实可见订单 ID`RESOLVED` 的订单任务不得换绑不同订单 | 必须写业务审计,记录复核字段指针、复核说明和订单归属确认摘要;不返回或写入 AI 原始 payload |
| `POST /api/reservation/source-notifications/{notificationId}/ack` | `FRONTEND_USER` | 已实现 M002 V4 CP6强制 Bearer 登录 + `RESERVATION_TASK_CONFIRM` + 来源通知所属酒店访问权 + version 并发校验 | 保持;只用于 `route_code=S10/S99` 的 V4 来源通知确认已读 / 已处理,不创建订单、不参与订单阻塞;重复 ack 幂等返回当前状态且不新增审计 | 首次确认必须写业务审计,记录已读 / 已处理确认actor 使用当前登录用户 |
| `POST /api/reservation/tasks/{taskId}/manual-review-conversions` | `FRONTEND_USER` | 第一版已写业务审计,但 actor 待迁移 | 登录 + `RESERVATION_MANUAL_REVIEW_RESOLVE` + 酒店访问权 | 必须写业务审计和原因 |
| `POST /api/reservation/tasks/{taskId}/manual-review-resolutions` | `FRONTEND_USER` | 第一版已写业务审计,但 actor 待迁移 | 登录 + `RESERVATION_MANUAL_REVIEW_RESOLVE` + 酒店访问权 | 必须写业务审计 |
| `POST /api/reservation/tasks/{taskId}/opera-operations/{operationId}/execute` | `FRONTEND_USER` | 当前为 OPERA 模拟 | 登录 + `RESERVATION_OPERA_SIM_EXECUTE` + 酒店访问权 | 必须写业务审计和 attempt |
| `POST /api/reservation/tasks/{taskId}/opera-operations/{operationId}/retry` | `FRONTEND_USER` | 当前为 OPERA 模拟 | 登录 + `RESERVATION_OPERA_SIM_EXECUTE` + 酒店访问权 | 必须写业务审计和 attempt |
| `GET /api/reservation/tasks/{taskId}/audits` | `FRONTEND_USER` | 已强制 Bearer 登录 + `RESERVATION_AUDIT_READ`;按任务实际所属酒店校验访问权 | 保持登录 + `RESERVATION_AUDIT_READ` + 酒店访问权 | 查询审计不再写审计 |
| `POST /api/reservation/invoices/manual-generations` | `FRONTEND_USER` | 已实现 M009 CP2强制 Bearer 登录 + `RESERVATION_INVOICE_GENERATE` + 酒店访问权;`task_id` / `order_id` 可为空,传入时反查对象所属酒店 | 保持登录 + `RESERVATION_INVOICE_GENERATE` + 酒店访问权;后续如增加历史列表或预填接口需单独登记权限 | 写业务审计,记录来源类型、模板版本、生成结果摘要;生成失败写入生成记录安全错误摘要 |
| `POST /api/reservation/rooming-lists/generations` | `FRONTEND_USER` | 已实现 M010 CP1multipart 上传来源名单并直接下载 `.xlsx`;已在 multipart 参数绑定前前置校验登录和生成权限 | 登录 + `RESERVATION_ROOMING_LIST_GENERATE` + 酒店访问权;第一版不落库、不上传 OSS | CP1 不落生成记录表;错误响应不得记录完整名单和证件信息,后续若增加历史记录再补业务审计 |
### 3.3 来源邮件接口
| 接口 / 能力 | 分类 | 当前管控 | 目标管控 | 审计要求 |
| --- | --- | --- | --- | --- |
| `GET /api/source-messages` | `FRONTEND_USER` | 已强制 Bearer 登录 + `SOURCE_MESSAGE_READ`;列表条件中的酒店按当前用户可访问酒店校验 | 保持登录 + `SOURCE_MESSAGE_READ` + 酒店访问权 | 只读摘要不写审计 |
| `GET /api/source-messages/{id}` | `FRONTEND_USER` | 已强制 Bearer 登录 + `SOURCE_MESSAGE_READ`;按消息实际所属酒店校验访问权 | 保持登录 + `SOURCE_MESSAGE_READ` + 消息所属酒店访问权 | 只读摘要不写审计 |
| `GET /api/source-messages/{id}/conversation` | `FRONTEND_USER` | 已强制 Bearer 登录 + `SOURCE_MESSAGE_READ` + `SOURCE_MESSAGE_ORIGINAL_READ`;按消息实际所属酒店校验访问权;返回会话完整 text/html 和媒体 URL | 保持登录 + `SOURCE_MESSAGE_READ` + `SOURCE_MESSAGE_ORIGINAL_READ` + 消息所属酒店访问权 | 必须写原文读取审计actor 使用当前登录用户稳定 ID |
| `GET /api/source-messages/{id}/original` | `FRONTEND_USER` | 已强制 Bearer 登录 + `SOURCE_MESSAGE_READ` + `SOURCE_MESSAGE_ORIGINAL_READ`;按消息实际所属酒店校验访问权;不再使用原文读取 access key | 保持登录 + `SOURCE_MESSAGE_READ` + `SOURCE_MESSAGE_ORIGINAL_READ` + 消息所属酒店访问权 | 必须写原文读取审计actor 使用当前登录用户稳定 ID |
### 3.4 系统管理后台接口
| 接口 / 能力 | 分类 | 当前管控 | 目标管控 | 审计要求 |
| --- | --- | --- | --- | --- |
| `/api/admin/users/**` | `FRONTEND_ADMIN` | 已强制登录和 `SYSTEM_USER_MANAGE` | 保持;禁用用户撤销 session | 写操作必须记录 `platform_admin_audit_log` |
| `/api/admin/roles/**` | `FRONTEND_ADMIN` | 已强制登录和 `SYSTEM_ROLE_MANAGE` | 保持;内置角色只读 | 写操作必须记录管理审计 |
| `/api/admin/permissions` | `FRONTEND_ADMIN` | 已强制登录和 `SYSTEM_ROLE_MANAGE` | 保持只读;前端不能自造权限码 | 不需要写审计 |
| `/api/admin/menus/**` | `FRONTEND_ADMIN` | 已强制登录和 `SYSTEM_MENU_MANAGE``GET /tree``PUT /tree-order` 已沿用该权限 | 保持;菜单可见性不替代后端权限;批量树排序只允许修改 `parent_id``sort_order``sort_order` 为空时按请求顺序生成稳定排序 | 写操作必须记录管理审计,树排序审计记录调整前后的父级和排序;树查询不写审计 |
| `/api/admin/hotels/**` | `FRONTEND_ADMIN` | 已强制登录和 `HOTEL_MANAGE` | 保持;单酒店阶段只能一家 `ACTIVE` | 写操作必须记录管理审计 |
| `/api/admin/reservation/catalogs/**` | `FRONTEND_ADMIN` | 已实现目录管理后台 CP1前端入口为 `/system/reservation-catalogs`;强制登录、`RESERVATION_CATALOG_MANAGE` 和目标酒店访问权 | 保持;第一版只开放 Account、Room Type、Rate Code 列表、新增、启用 / 停用Market / Source 独立管理和真实 PMS 同步后置;停用目录不再进入普通 lookup | 新增和状态实际变化必须记录管理审计;重复提交相同状态按幂等返回,不新增审计;列表查询不写审计;不得返回 PMS 原始响应、Secret 或外部同步错误详情 |
| `GET /api/admin/audits` | `FRONTEND_ADMIN` | 已强制登录和 `SYSTEM_ADMIN_CONSOLE_ACCESS` | 保持;不返回 Secret、密码或 token | 查询审计不再写审计 |
### 3.5 调试和系统接口
| 接口 / 能力 | 分类 | 当前管控 | 目标管控 | 审计要求 |
| --- | --- | --- | --- | --- |
| `POST /api/system/debug/eml-superagent-runs` | `FRONTEND_DEBUG` | 环境开关 + `X-TH-Hotel-Debug-Upload-Key` | dev/test 可保留 access key长期目标为登录 + `SYSTEM_DEBUG_EML_RUN` + 环境开关 | 写 Debug run必要时补管理 / 调试审计 |
| `GET /api/system/debug/eml-superagent-runs/{runId}` | `FRONTEND_DEBUG` | 环境开关 + access key | 登录 + `SYSTEM_DEBUG_EML_RUN`;避免向普通用户暴露 AI 原始结果 | 只读调试可记录访问日志 |
| `POST /api/system/debug/eml-superagent-runs/stream` | `FRONTEND_DEBUG` | 环境开关 + access key | 登录 + `SYSTEM_DEBUG_EML_RUN`;生产默认关闭 | 写 Debug run 和安全错误摘要 |
| `POST /api/system/document-conversions/excel-to-pdf` | `FRONTEND_DEBUG` | 环境开关 + `X-TH-Hotel-Document-Conversion-Key`;只支持 `.xls` / `.xlsx`PDF 输出到 OSS | 长期目标为登录 + 文件转换调试权限 + 环境开关;生产默认关闭 | CP2 不落库;必要时通过网关访问日志和 OSS 对象路径追踪,后续自动转换任务落库后补转换审计 |
| `GET /api/system/agentbus-probe` | `FRONTEND_DEBUG` | 当前系统状态接口 | 登录 + `SYSTEM_AGENTBUS_PROBE_READ` 或系统管理入口权限 | 不返回 Token、raw frame 或邮件正文 |
| `POST /api/system/reservation/demo-data` | `FRONTEND_DEBUG` | 环境开关 + demo access key | dev/test 使用;生产必须关闭 | 写入演示数据时建议记录调试审计 |
### 3.6 第三方机器接口
| 接口 / 能力 | 分类 | 当前管控 | 目标管控 | 审计要求 |
| --- | --- | --- | --- | --- |
| `POST /api/ai-query/v1/case-context` | `THIRD_PARTY_SUPERAGENT` | HMAC 鉴权 | 保持 HMAC不使用用户 Bearer token | 记录请求 ID、client_id 和安全错误 |
| `POST /api/ai-query/v1/object-detail` | `THIRD_PARTY_SUPERAGENT` | HMAC 鉴权 | 保持 HMAC返回最小必要上下文 | 记录请求 ID、client_id 和安全错误 |
| `POST /api/ai-query/v1/conversation-tasks` | `THIRD_PARTY_SUPERAGENT` | HMAC 鉴权 | 保持 HMAC不返回邮件原文 | 记录请求 ID、client_id 和安全错误 |
| `POST /api/ai-query/v1/conversation-source` | `THIRD_PARTY_SUPERAGENT` | HMAC 鉴权 | 保持 HMAC只按契约返回需要字段 | 记录请求 ID、client_id 和安全错误 |
| `POST /api/integrations/superagent/task-results` | `THIRD_PARTY_SUPERAGENT` | HMAC + nonce + timestamp + body hash | 保持V4 / V3 / V2 共存期均必须用外部 `source_message_id` 匹配 Inbox技术契约错误只落 adapter error不创建用户可处理任务V4 普通业务包额外写入 V4 订单任务 / 多卡模型V4 S10/S99 写入来源通知且不创建旧任务 | 记录 batch、transition、adapter error、幂等结果和安全错误 |
| `/mcp` | `THIRD_PARTY_MCP` | Bearer Token提交工具可独立开关 | 保持;工具级能力限制,不暴露无关接口 | 记录工具调用结果和业务入站结果 |
| AgentBus WebSocket | `THIRD_PARTY_AGENTBUS` | AgentBus Token + capture 开关 | 保持;只入 SourceMessage不直接建业务任务 | 记录 SourceMessage、payload hash 和 dispatch run |
### 3.7 后端内部能力
| 能力 | 分类 | 暴露规则 | 审计 / 追踪 |
| --- | --- | --- | --- |
| Repository / Mapper / Entity | `INTERNAL_ONLY` | 不对 Controller、前端或第三方直接暴露 | 通过 Service 写审计 |
| SuperAgent Open API Client | `INTERNAL_ONLY` | 只能后端 Adapter 使用Secret 不出后端 | 通过 debug run 或 dispatch run 追踪 |
| OSS Adapter | `INTERNAL_ONLY` | 前端只能拿后端返回的安全 URL不能拿 OSS Secret | 上传和读取入口记录安全摘要 |
| AgentBus dispatch worker | `INTERNAL_ONLY` | 只由后端调度或受控管理入口触发 | `platform_superagent_dispatch_run` |
| Booking Excel 附件预处理 | `INTERNAL_ONLY` | M011 CP1 / CP2 / CP3 已接入 Debug EML 与 AgentBus dispatch只允许后端在调用 SuperAgent 前通过 Service / Port 使用,不单独暴露给前端或第三方 | 记录安全 warning、附件名、hash 前缀、sheet 名、行号和高亮业务行摘要;不得记录完整 Excel、完整附件 URL、签名参数、API Key、Cookie、Secret 或名单类客户敏感原文 |
| Flyway / bootstrap 初始化 | `INTERNAL_ONLY` | 不提供运行时外部接口 | 通过部署记录和数据库 history 追踪 |
| 未来 OPERA / OHIP Adapter | `INTERNAL_ONLY` | 浏览器不得直接调用;只能业务服务触发 | 必须记录操作、attempt 和外部结果摘要 |
## 4. 权限码规划口径
当前管理后台权限码已经落地。业务接口收口时建议新增或确认以下权限码,不要求一次性全部实现:
| 权限码 | 中文含义 | 适用接口 |
| --- | --- | --- |
| `RESERVATION_ORDER_READ` | 查看订单列表和订单详情 | 订单列表、订单详情 |
| `RESERVATION_TASK_READ` | 查看任务列表和任务详情 | 任务列表、任务详情 |
| `RESERVATION_TASK_EDIT` | 保存任务草稿或编辑可写字段 | 草稿保存 |
| `RESERVATION_TASK_CONFIRM` | 最终确认任务 | 任务确认 |
| `RESERVATION_MANUAL_REVIEW_RESOLVE` | 处理人工复核和 Fallback 转换 | 复核解阻、Fallback 转换 |
| `RESERVATION_OPERA_SIM_EXECUTE` | 执行或重试 OPERA 模拟 / 未来真实操作 | OPERA execute / retry |
| `RESERVATION_AUDIT_READ` | 查看业务审计流水 | 任务审计列表 |
| `RESERVATION_INVOICE_GENERATE` | 生成 Reservation Proforma Invoice | Manual Invoice 生成、未来任务 / 订单预填生成 |
| `RESERVATION_ROOMING_LIST_GENERATE` | 生成 Reservation Rooming List Excel | Rooming List 上传名单并生成 `.xlsx` 下载 |
| `RESERVATION_CATALOG_MANAGE` | 维护 Reservation 受控目录 | 已用于 `/api/admin/reservation/catalogs/**`;第一版支持 Account、Room Type、Rate Code 管理Market / Source 独立管理后置 |
| `SOURCE_MESSAGE_READ` | 查看来源邮件安全摘要 | SourceMessage 列表、详情、会话摘要 |
| `SOURCE_MESSAGE_ORIGINAL_READ` | 查看邮件正文、HTML 和附件外链 | original / conversation 完整正文;必须叠加 `SOURCE_MESSAGE_READ` 使用 |
| `SYSTEM_DEBUG_EML_RUN` | 使用 Debug EML 调试链路 | Debug EML 上传、查询、stream |
| `SYSTEM_AGENTBUS_PROBE_READ` | 查看 AgentBus 安全状态 | AgentBus probe |
如果新增权限码,必须同步:
1. `PlatformPermissionCode` 枚举。
2. 内置角色权限矩阵。
3. `docs/project/security-access-control-boundary.md`
4. 前后端协作文档中对应页面按钮或菜单说明。
### 4.1 新增接口权限固定流程
后续新增需要前端用户或管理员调用的接口时,必须按同一套流程维护权限,避免“接口能调用但系统设置里管不了”或“前端隐藏了但后端没拦”的不一致。
固定流程:
1. **确认接口分类。** 先判断接口属于 `FRONTEND_USER``FRONTEND_ADMIN``FRONTEND_DEBUG`、第三方机器接口还是 `INTERNAL_ONLY`。只有前端用户和管理员接口进入用户角色权限模型SuperAgent、AgentBus、MCP 继续使用机器鉴权,不使用用户 Bearer 权限码。
2. **定义稳定权限码。**`PlatformPermissionCode` 增加稳定英文权限码,例如 `RESERVATION_TASK_ASSIGN`。权限码只表达能力边界,不绑定中文文案、不绑定某个按钮样式。
3. **补启动同步元数据。** 在权限启动同步逻辑中补权限名称、权限分组和状态,确保 `platform_permission` 能自动拥有该权限码。
4. **补内置角色默认矩阵。** 明确 `SYSTEM_ADMIN`、业务操作员、只读角色等内置角色是否默认拥有该权限。内置角色矩阵仍以代码为准;自定义角色后续通过系统设置页面分配。
5. **后端接口强制校验。** 在 Controller 或统一入口中显式调用对应鉴权服务,例如 `requirePermission(PlatformPermissionCode.X.name())`。只读接口同时校验对象所属酒店;写接口还要校验状态、幂等、事务和审计。
6. **前端类型和交互同步。** 在前端权限类型中加入新权限码,路由、菜单、按钮和操作入口按 `/api/auth/me` 返回的 `permissions[]` 控制展示。前端控制只提升体验,不能替代后端权限校验。
7. **系统设置可分配。** 权限启动同步后,系统设置的角色权限页面应能看到该权限码;需要给自定义角色授权时,通过系统设置勾选,用户重新登录或刷新上下文后生效。
8. **补测试。** 至少覆盖无 token、无权限、有权限、跨酒店或对象归属校验。第三方接口要补“不被用户登录拦截误伤”的回归测试。
9. **补文档。** 本文矩阵中登记接口分类、权限码、酒店隔离和审计要求;影响前端时同步 `docs/project/frontend-backend/backend-to-frontend-notes.md`;影响 SuperAgent / MCP / AgentBus 时同步对应集成契约。
最小验收口径:
- 新接口没有 token 时返回该分类约定的 401。
- 已登录但缺权限时返回该分类约定的 403。
- 有权限但访问无权酒店或无权对象时返回酒店 / 对象访问拒绝。
- 权限码能在系统设置角色权限页面看到并分配给自定义角色。
- 前端只做路由、菜单、按钮显示控制,后端仍能拦截直接调用。
- 第三方机器接口不被用户 Bearer 权限模型误拦截。
## 5. 酒店隔离规则
- 前端用户接口必须从当前登录用户解析可访问酒店集合。
- 显式传入 `hotel_id` 时,后端必须校验该用户是否可访问该酒店。
- 未传 `hotel_id` 时,单酒店阶段可按用户默认酒店或系统唯一 `ACTIVE` 酒店解析。
- 直接按 `taskId``orderId``sourceMessageId` 定位的接口,必须反查对象所属 `hotel_id` 并校验访问权;当前已覆盖 Reservation 订单详情、任务详情、任务审计列表和 SourceMessage 摘要详情。
- 第三方 SuperAgent 接口第一版不依赖用户酒店权限,但必须使用系统酒店解析 SourceMessage并防止跨酒店误匹配。
- AgentBus 入站不接受外部随意指定酒店;单酒店阶段由系统唯一 `ACTIVE` 酒店解析。
## 6. 审计分层
| 审计类型 | 当前载体 | 必须记录的动作 |
| --- | --- | --- |
| 管理审计 | `platform_admin_audit_log` | 用户、角色、权限、菜单、酒店的写操作 |
| 业务审计 | `workflow_reservation_audit_log` | 任务确认、人工复核、订单归属确认、OPERA 执行 / 重试 |
| 邮件原文读取审计 | `platform_source_message_original_access_audit` | 读取邮件正文、HTML、附件外链 |
| SuperAgent 入站追踪 | `workflow_reservation_ai_batch``workflow_reservation_ai_transition` | task-results / MCP 提交、路由、adapter error |
| AgentBus 分发追踪 | `platform_superagent_dispatch_run` | SourceMessage 自动分发 SuperAgent、重试、失败摘要 |
| 安全审计 | 后续可新增平台安全审计表 | 登录失败、签名失败、nonce 重放、越权访问 |
业务侧后续收口重点:
- 业务写操作 actor 从本地占位迁移到当前登录用户。
- 第三方入站 actor 保持机器身份,例如 `SUPERAGENT``MCP``AGENTBUS`
- 审计快照不得写入密码、token、secret、完整邮件正文、附件签名 URL 或支付敏感信息。
## 7. 接口变更同步规则
新增或修改任何 Controller、第三方入口、调试入口或后台 worker 触发入口时,必须先回答:
1. 这个接口给谁调用:前端用户、管理员、第三方系统,还是内部 worker
2. 是否需要登录?如果需要,权限码是什么?
3. 是否涉及 `hotel_id`?如何校验用户可访问酒店?
4. 是否返回敏感数据正文、HTML、附件 URL、AI 原始 payload、trace、Secret
5. 是否是写操作写什么审计actor 从哪里来?
6. 是否生产允许?是否需要环境开关?
7. 是否影响 SuperAgent、MCP、AgentBus 或前端契约?
如果任一答案为“是”,必须同步更新以下文档中相关部分:
- 本文档。
- `AGENTS.md``docs/project/backend-development-guidelines.md` 中的开发规则,如果新增了通用规范。
- `docs/project/frontend-backend/backend-to-frontend-notes.md`,如果影响前端。
- `docs/project/integrations/superagent-api-contract.md` 或 MCP / AgentBus 集成文档,如果影响第三方。
- 对应需求文档,例如 M002、M004、M006、M007。
## 8. 建议实施顺序
后续开发权限收口时建议按以下顺序推进:
1. 已完成 CP1Reservation / SourceMessage 第一批只读查询接口已收口登录、权限码和酒店访问权包括任务列表、订单列表、订单详情、任务详情、任务审计列表、SourceMessage 摘要列表和摘要详情。
2. 已完成 CP2邮件原文和会话完整正文读取已迁移到 `SOURCE_MESSAGE_READ` + `SOURCE_MESSAGE_ORIGINAL_READ`,并按消息所属酒店校验访问权;原文读取审计 actor 使用当前登录用户稳定 ID。
3. 再收口 Reservation 写操作草稿、确认、人工复核、OPERA 模拟。
4. 迁移业务审计 actor 到当前登录用户。
5. 最后处理 Debug、Demo、Replay、AgentBus Probe 等系统调试入口。
每一步都应保持第三方机器接口不被误拦截SuperAgent / MCP / AgentBus 继续使用机器鉴权。