## 1. 模块脚手架 - [x] 1.1 新建 `mjava-pro/`(非直接 cp mcli,精简依赖) - [x] 1.2 `pom.xml` artifactId=mjava-pro,依赖仅 mjava 基座 - [x] 1.3 `Boot.java` package=com.malk.pro,`@EnableScheduling` + `@EnableJpaAuditing` + scanBasePackages=com.malk - [x] 1.4 `application.yml` port=9010 / context-path=/api/pro / spel.scheduling=true / multiSource=false - [x] 1.5 根 `pom.xml` `` 追加 `mjava-pro` - [x] 1.6 `mvn -pl mjava-pro -am compile` 通过(2026-04-19 验证) ## 2. TenantContext 核心 - [x] 2.1 `TenantProfile` + `VendorCredential` 数据类 - [x] 2.2 `TenantContext`(ThreadLocal + set/current/clear/propagate + currentTenantId) - [x] 2.3 `TenantInterceptor`(preHandle 读 X-Tenant-Id → registry.get → TenantContext.set + MDC;afterCompletion clear;401 TENANT_REQUIRED / 403 TENANT_NOT_FOUND) - [x] 2.4 `ProWebConfig` 注册拦截器,排除 /_admin/** / /actuator/** / /static/** 等 - [ ] 2.5 TenantTaskDecorator(@Async 传播)— 延后,首次生产启用时评估 ## 3. TenantRegistry - [x] 3.1 `TenantRegistryService`(依赖 `YDClient_Form`,使用新原子接口 searchForm) - [x] 3.2 `loadAll()` 按 formUuid 分页查宜搭应用表 → mergeRow 合并同 tenantId 多 vendor → `Map` - [x] 3.3 `get(tenantId)` / `contains` / `size` 内存 Map 直查(缓存 miss 不触发单条拉取,等下次 TTL 刷新) - [x] 3.4 `@PostConstruct init()` + `@Scheduled(fixedDelayString=ttl*1000)` 定时刷新;failFast 开关控制启动失败行为 - [x] 3.5 `AdminController` `@Profile("dev") @NoAuth POST /_admin/reloadTenant` ## 4. Client / Service 透传 - [x] 4.1 `com.malk.pro.service.dingtalk.DynamicDDService`:从 TenantContext 取凭据 → 调基座 `DDClient.getAccessToken(appKey, appSecret)` → 走 `{tenantId}:dingtalk:{appKey}` namespace 缓存(2026-06-10) - [x] 4.2 `com.malk.pro.service.aliwork.DynamicYDService`:构造 `YDAuth`(accessToken 复用 DynamicDDService,appType/systemToken/userId 取自 extra)(2026-06-10) - [x] 4.3 UtilToken key namespace `{tenantId}:{vendor}:{appKey}` 已在 4.1/4.2 实现;基座不动 ## 5. 审计日志 - [x] 5.1 `tenantId` 通过 MDC 自动进审计(TenantInterceptor 已写 MDC + logback pattern 含 `[%X{tenantId:-}]`,不动基座 UtilHttp) - [ ] 5.2 logback-spring.xml 按租户分文件 `./log/{日期}/pro-%X{tenantId}.log` — 延后(pattern 已含 tenantId,分文件按实际部署需求评估) - [ ] 5.3 异步线程 MDC 传递 — 延后(依赖 Task 2.5 TenantTaskDecorator) ## 6. 配置与文档 - [x] 6.1 `application-dev.yml.example`(含 tenant.registry.* 占位)— 2026-04-26 - [x] 6.2 `application-prod.yml.example`(含 tenant.registry.* 占位)— 2026-04-26 复核已存在 - [x] 6.3 `mjava-pro/README.md`:调用范式 + 入驻 SOP + 隔离边界 + 配置(2026-06-10) - [ ] 6.4 ~~mjava-baseline.md~~ stale 引用(实际权威是 `后端/CLAUDE.md`);状态更新待 add-mjava-pro 整体 archive 时再回写 ## 7. 验证 - [ ] 7.1 单元测试:`TenantContextTest`(set/clear/异步传播) - [ ] 7.2 集成冒烟:两个租户配置 → 用不同 `X-Tenant-Id` 调同一接口 → 验证 token 隔离 + 审计日志分片 - [ ] 7.3 压测:100 QPS 下 TenantContext 无泄漏(ThreadLocal clear 正确) - [ ] 7.4 `/opsx:validate add-mjava-pro --strict` 通过