spec.md 2.6 KB

ADDED Requirements

Requirement: 统一入口

mjava-com SHALL 提供单一网关路由 POST /api/com/{vendor}/{action},每个 action MUST 对应基座某个 Client 方法。

Scenario: vendor + action 路由

  • WHEN 收到 POST /api/com/dingtalk/user.get
  • THEN 根据 ActionRegistry 查找 dingtalk.user.get 注册的 handler
  • AND 调用基座 DDClient_Contacts.getUser_v2(...)
  • AND 请求体字段名必须与 Client 方法参数一致

Requirement: 签名校验

网关 SHALL 在 Auth 拦截阶段校验调用方签名。校验逻辑 MUST 复用基座 add-request-auth-replay-guard 提供的 UtilSignatureNonceCache,不重新实现 HMAC。

Scenario: 四层校验顺序

  • WHEN 请求到达
  • THEN 依次执行:时间戳窗口 → callerId 注册表查 secret → HMAC-SHA256 比对 → 调用方 enabled
  • AND 任一失败返回 401 { code: "AUTH_FAILED" }
  • AND 响应 message 不暴露具体失败环节

Requirement: 动作白名单

每个开放的 action MUST 通过三层校验:ActionRegistry 代码注册 + yml com.actions.enabled 启用 + 调用方 allowedActions 包含。

Scenario: 代码未注册

  • WHEN 请求 action 未在 ActionRegistry 注册
  • THEN 返回 404 { code: "ACTION_NOT_FOUND" }

Scenario: yml 未启用

  • WHEN com.actions.enabled 不含该 action
  • THEN 返回 403 { code: "ACTION_FORBIDDEN" }

Scenario: 调用方无权限

  • WHEN callerId 的 allowedActions 不含该 action
  • THEN 返回 403 { code: "ACTION_FORBIDDEN" }

Requirement: 响应格式

网关 SHALL 统一返回 McR<T>。第三方原始响应 MUST 放在 data 字段保留原结构。

Scenario: 成功透传

  • WHEN 基座 Client 返回成功
  • THEN McR.success(result)data = 原始 Map 或 DTO

Scenario: 第三方失败映射

  • WHEN 基座 Client 抛 McException(vendor 返回错误)
  • THEN McR.fail(code, message)data 含 vendor 原始错误信息

Requirement: 限流

网关 SHALL 按 callerId 做本地限流,阈值取自宜搭权限表单 rateLimit 字段。

Scenario: 超限拒绝

  • WHEN 同一 callerId 请求速率超过配置 QPS
  • THEN 返回 429 { code: "RATE_LIMITED", retryAfter: 1 }

Requirement: 审计扩展

网关审计日志 MUST 在 mjava-baseline §3.5 字段基础上追加 callerId / vendorAction / signatureValid。

Scenario: 每请求按 caller 分片

  • WHEN 请求进入
  • THEN 日志落入 ./log/{日期}/com-{callerId}.log
  • AND MDC 含 callerIdvendorAction