## 1. 模块脚手架 - [x] 1.1 新建 `mjava-com/`(非直接 cp mcli) - [x] 1.2 pom.xml artifactId=mjava-com,仅依赖 mjava - [x] 1.3 Boot.java package=com.malk.apigw(避免 com.malk.com 歧义) - [x] 1.4 application.yml port=9020 + context=/api/com - [x] 1.5 根 pom 追加 mjava-com module - [x] 1.6 `mvn -pl mjava-com -am compile` 通过(全 reactor 6 模块) ## 2. 调用方鉴权 - [x] 2.1 `CallerProfile` 数据类(callerId/secret/allowedActions/rateLimit/expireAt/enabled) - [x] 2.2 `CallerRegistryService` 查宜搭权限表 + 启动全量 + @Scheduled 定时刷新 - [x] 2.3 `CallerAuthInterceptor`:Header 齐全 → 时间窗 → callerId 查 + 启用/过期 → NonceCache → HMAC → 限流,**复用基座 UtilSignature + NonceCache** - [x] 2.4 `ComWebConfig` 注册拦截器,排除 /_admin/** 等 ## 3. 动作注册 - [x] 3.1 `ActionRegistry` Map - [x] 3.2 `ActionHandler` 函数式接口 `McR handle(CallerProfile, JSONObject)` - [ ] 3.3 `DingtalkActionRegistry` 首批 3 action(延后,等首个调用方接入时按需补) - [ ] 3.4 `AliworkActionRegistry` 首批 3 action(同上) - [x] 3.5 `CallerRegistryProperties.Actions` 读 com.actions.enabled 全局白名单 ## 4. 网关 Controller - [x] 4.1 `GatewayController` 路由 POST /{vendor}/{action} - [x] 4.2 三层校验(ActionRegistry 代码注册 / yml enabled / caller.allowedActions) - [x] 4.3 失败返回 McR.error(ACTION_NOT_FOUND / ACTION_FORBIDDEN / AUTH_FAILED / RATE_LIMITED / VENDOR_ERROR) ## 5. 限流 - [x] 5.1 `CallerRateLimiter` Guava RateLimiter per callerId(ConcurrentHashMap 存;rate 变更自动重建) - [x] 5.2 拦截器内直接调 rateLimiter.tryAcquire,429 RATE_LIMITED ## 6. 审计日志 - [x] 6.1 CallerAuthInterceptor 写 MDC `callerId` + 失败分支 log.warn(point logger) - [ ] 6.2 logback pattern 追加 `[%X{callerId:-}]`(延后) ## 7. 配置与文档 - [ ] 7.1 `application-dev.yml.example`(com.caller.registry.* + com.actions.enabled 示例) - [ ] 7.2 `application-prod.yml.example`(同上占位) - [ ] 7.3 `README.md`:外部系统对接步骤、signature 算法示例(Python / Node.js 样例代码) - [ ] 7.4 更新 `mjava-baseline.md` 表格里 mjava-com 状态为"已实施" ## 8. 验证 - [ ] 8.1 单元测试:`HmacSignatureTest` / `CallerRegistryTest` - [ ] 8.2 集成冒烟:模拟外部 Python 客户端签名 → 调 `/dingtalk/user.get` → 验证成功 & 失败(签名错、过期、限流、未启用 action) - [ ] 8.3 压测:单个 caller 限流准确性(RateLimiter 容差) - [ ] 8.4 `/opsx:validate add-mjava-com --strict` 通过