拆分顺序:客户输入与纵向验证 → 通用 SPI → 数据/安全 → 登录 → 通讯录 → 消息 → 待办/回调 → 管理端 → 上线门禁 每个任务完成后同步回填
spec.md、test-spec.md和execution-log.md
/apply 实施 P0/P1。code-copilot/rules/automated-testing-standard.md 读取本变更四份文档及 memory 基线。| 顺序 | 优先级 | 任务 | 完成标志 | 依赖 |
|---|---|---|---|---|
| 1 | P0 | Task 0:企微纵向连通验证 | Token、部门、成员、标签、测试消息、回调解密全部通过 | 客户资料 |
| 2 | P0 | Task 1-4C:SPI、模块、数据、配置、凭据安全和兼容迁移 | 通用插件装配、迁移、连接/应用/身份存储和 Secret 生命周期合同通过 | Task 0 |
| 3 | P0 | Task 5:安全登录协议 | 前端无法伪造外部身份,企微映射登录通过 | Task 2-4C |
| 4 | P1 | Task 6-11:企微通讯录与同步运维 | 全量/增量/标签/冲突/定时校准闭环 | Task 1-5 |
| 5 | P1 | Task 12-13:企微消息 | 逐人投递、部分失败、补偿、记录闭环 | Task 6-11 |
| 6 | P2 | Task 14-15:企微待办与安全回调 | 创建/转派/完成/撤回联动和安全动作闭环 | Task 5、Task 7、Task 12-13 |
| 7 | P1/P2 | Task 18 后端接口/资源 → Task 16-17 管理端与运维页面 | 管理员可配置、观察、处理、重试 | 对应核心服务任务 |
| 8 | P0/P1 | Task 19A:M1 自动化、真实企微 UAT 与上线门禁 | 目录、登录、消息和一期运维可独立上线 | Task 0-13、Task 16-18 一期范围 |
| 9 | P2 | Task 19B:M2 待办 UAT 与上线门禁 | 待办、回调和补偿可独立上线,变更整体完成 | Task 14-15、Task 17-18 二期范围 |
/apply。mvn -pl forge-admin-server -am compile BUILD SUCCESS)。/apply。code-copilot/changes/unified-enterprise-collaboration/wecom-spike-report.md — 新增,记录非敏感配置清单、调用结果、错误码、速率和结论。forge-docs/guide/integration/wecom-setup.md — 新增,记录自建应用、权限、可信域名/IP、回调和测试步骤。code-copilot/changes/unified-enterprise-collaboration/execution-log.md — 追加实际命令、时间、结果和跳过项,不记录凭据或个人资料。forge-server/forge-framework/forge-starter-parent/forge-starter-collaboration/pom.xml — 新增 Starter 模块。forge-server/forge-framework/forge-starter-parent/pom.xml — 注册新模块。forge-server/forge-framework/forge-dependencies/pom.xml — 纳入 BOM。forge-server/forge-framework/forge-starter-parent/forge-starter-collaboration/src/main/java/com/mdframe/forge/starter/collaboration/CollaborationCapability.java — 定义 LOGIN/DIRECTORY/MESSAGE/TODO/CALLBACK。forge-server/forge-framework/forge-starter-parent/forge-starter-collaboration/src/main/java/com/mdframe/forge/starter/collaboration/provider/CollaborationProviderRegistry.java — Connector 注册、能力发现和重复 Provider 失败关闭。forge-server/forge-framework/forge-starter-parent/forge-starter-collaboration/src/main/java/com/mdframe/forge/starter/collaboration/provider/CollaborationProvider.java — Provider 元数据合同。forge-server/forge-framework/forge-starter-parent/forge-starter-collaboration/src/main/java/com/mdframe/forge/starter/collaboration/connector/CollaborationConnector.java、LoginConnector.java、DirectoryConnector.java、MessageConnector.java、TodoConnector.java、CallbackConnector.java、AccessTokenProvider.java、ExternalSecretResolver.java — 同目录下的基础、能力和外部 Secret 扩展接口。forge-server/forge-framework/forge-starter-parent/forge-starter-collaboration/src/main/java/com/mdframe/forge/starter/collaboration/todo/CollaborationFlowActionGateway.java — 外部待办动作调用 Forge 流程的低层反向 SPI,避免 Collaboration Plugin 依赖 Flow Plugin。forge-server/forge-framework/forge-starter-parent/forge-starter-collaboration/src/main/java/com/mdframe/forge/starter/collaboration/model/CollaborationExecutionContext.java、VerifiedSocialIdentity.java、ProviderError.java、ExternalDepartment.java、ExternalUser.java、ExternalTag.java、DirectorySnapshot.java、ProviderMessageRequest.java、ProviderMessageResult.java、ProviderTodoRequest.java、ProviderTodoResult.java、CollaborationTaskEvent.java、ExternalTodoAction.java、FlowActionResult.java — 同目录下的平台无关输入/输出记录。public final class CollaborationProviderRegistry {
public CollaborationProvider requireProvider(String platform);
public <T> T requireConnector(String platform, CollaborationCapability capability, Class<T> type);
}
- **验收**:Fake Provider 可只实现部分能力;缺能力和重复平台均明确失败;业务编排层无企微/飞书/钉钉 switch。
## Task 2:建立 Collaboration Plugin 与应用装配(P0)
- **目标**:承载连接管理、目录编排、企微适配器、消息/待办桥接,保持 Starter 不反向依赖业务插件。
- **涉及文件**:
- `forge-server/forge-framework/forge-plugin-parent/forge-plugin-collaboration/pom.xml` — 新增插件,依赖 Collaboration/Social/Crypto/Cache/Outbound/Message Starter 及 System Plugin;通过 Starter 渠道合同与 Message Plugin 运行时协作,不形成 Plugin 反向依赖。
- `forge-server/forge-framework/forge-plugin-parent/pom.xml` — 注册插件。
- `forge-server/forge-framework/forge-plugin-parent/forge-plugin-collaboration/src/main/java/com/mdframe/forge/plugin/collaboration/config/CollaborationPluginConfiguration.java` — 扫描 Mapper、Provider 和 Handler。
- `forge-server/forge-admin-server/pom.xml` — 主应用引入插件。
- `forge-server/forge-framework/forge-plugin-parent/forge-plugin-flow/pom.xml` — 仅依赖低层 Collaboration Starter 的待办发布 SPI。
- **关键签名**:
```java
@Configuration
public class CollaborationPluginConfiguration {
@Bean
CollaborationProviderRegistry collaborationProviderRegistry(
List<CollaborationProvider> providers,
List<CollaborationConnector> connectors);
}
COLLABORATION 渠道只注册一次。forge-server/db/migration/V1.0.57__add_collaboration_connection_foundation.sql — 扩展 sys_social_config/sys_user_social,新建应用、映射、同步、待办和回调表。forge-server/db/migration/V1.0.58__extend_message_delivery_for_collaboration.sql — 扩展消息主表、接收人和发送记录。forge-server/db/migration/V1.0.59__add_collaboration_resources_and_jobs.sql — 字典、权限、菜单、出站场景和 Job 配置。forge-server/db/全量初始化SQL.sql — 同步最新结构和内置数据,不写任何 Secret。del_flag BIGINT DEFAULT 0,活动唯一键包含 del_flag,删除写当前主键。sys_social_tag_member 是可重建纯关系表,允许物理替换;同步日志/回调日志仅由留存任务物理清理。information_schema/NOT EXISTS 防重复保护,tenant_id=1。forge-server/forge-framework/forge-starter-parent/forge-starter-crypto/src/main/java/com/mdframe/forge/starter/crypto/crypto/CryptoAlgorithm.java — 增加 AES_GCM 算法代码。forge-server/forge-framework/forge-starter-parent/forge-starter-crypto/src/main/java/com/mdframe/forge/starter/crypto/crypto/impl/AESGCMEncryptor.java — 使用 12-byte 随机 IV、128-bit 认证标签和现有 key ring 实现认证加密。forge-server/forge-framework/forge-starter-parent/forge-starter-crypto/src/main/java/com/mdframe/forge/starter/crypto/crypto/EncryptorFactory.java — 注册 AES_GCM,由 VersionedPersistentCryptoService 继续输出统一版本化密文。forge-server/forge-framework/forge-starter-parent/forge-starter-social/src/main/java/com/mdframe/forge/starter/social/security/SocialAppCredentialService.java、DefaultSocialAppCredentialService.java — 同目录下定义和实现加密、解密、掩码、空值保留、外部 Secret 解析和显式轮换,供登录和 Collaboration Plugin 共用。forge-server/forge-framework/forge-starter-parent/forge-starter-social/src/main/java/com/mdframe/forge/starter/social/security/SecretContext.java、SecretSummary.java — 同目录下定义租户/连接/应用/凭据类型绑定上下文和安全摘要,禁止 DTO 携带明文。forge-server/forge-framework/forge-starter-parent/forge-starter-social/pom.xml — 增加 Collaboration SPI 和持久化加密依赖,不把明文 Secret 交给上层 Controller。java
public interface SocialAppCredentialService {
String encrypt(char[] plaintext, SecretContext context);
char[] decrypt(String ciphertext, SecretContext context);
SecretSummary summary(String ciphertext);
String preserveOrRotate(String currentCiphertext, char[] requestedSecret, SecretContext context);
}
sys_social_config 从单一 OAuth 配置升级为连接根,并按能力安全读取独立应用;旧登录配置只在受控兼容期开启双读。forge-server/forge-framework/forge-starter-parent/forge-starter-social/src/main/java/com/mdframe/forge/starter/social/domain/entity/SysSocialConfig.java — 增加连接代码、企业 ID、权威策略、逻辑删除和审计字段,旧凭据字段标记兼容;能力集合不在连接实体重复保存。forge-server/forge-framework/forge-starter-parent/forge-starter-social/src/main/java/com/mdframe/forge/starter/social/domain/entity/SysSocialAppConfig.java、SysSocialCapabilityBinding.java — 新增物理应用和能力绑定实体,Secret 只保存一份密文或外部引用。forge-server/forge-framework/forge-starter-parent/forge-starter-social/src/main/java/com/mdframe/forge/starter/social/mapper/SysSocialConfigMapper.java、SysSocialAppConfigMapper.java、SysSocialCapabilityBindingMapper.java — 连接/应用/能力绑定查询和 CAS 签名。forge-server/forge-framework/forge-starter-parent/forge-starter-social/src/main/resources/mapper/SysSocialConfigMapper.xml、SysSocialAppConfigMapper.xml、SysSocialCapabilityBindingMapper.xml — 显式租户、连接、能力、状态和逻辑删除 SQL。forge-server/forge-framework/forge-starter-parent/forge-starter-social/src/main/java/com/mdframe/forge/starter/social/service/impl/SocialConfigServiceImpl.java、SocialAppConfigServiceImpl.java — 连接 CRUD、独立应用选择、缓存清理和旧配置兼容读取。forge-server/forge-framework/forge-starter-parent/forge-starter-social/src/main/java/com/mdframe/forge/starter/social/controller/SocialConfigController.java、forge-server/forge-framework/forge-starter-parent/forge-starter-social/src/main/java/com/mdframe/forge/starter/social/domain/vo/SocialConnectionSummaryVO.java — 旧管理接口在兼容期只返回脱敏 VO,并把写操作迁移到新连接接口。java
public SysSocialConfig selectConnectionByCode(String connectionCode);
public SysSocialAppConfig requireEnabledApp(Long tenantId, Long connectionId,
CollaborationCapability capability);
public boolean bindCapability(Long tenantId, Long connectionId,
CollaborationCapability capability, Long appConfigId);
public boolean updateApp(SocialAppSaveCommand command, String expectedCredentialCipher);
(platform, tenant) 读取只有唯一连接时才兼容,否则失败关闭。platform + uuid 在多企业下的冲突,并禁止用户 Token 明文落库。forge-server/forge-framework/forge-starter-parent/forge-starter-social/src/main/java/com/mdframe/forge/starter/social/domain/entity/SysUserSocial.java — 增加 connection/enterprise/source/status/hash/logic-delete 字段,访问/刷新 Token 标记弃用。forge-server/forge-framework/forge-starter-parent/forge-starter-social/src/main/java/com/mdframe/forge/starter/social/mapper/SysUserSocialMapper.java — 按租户/连接/外部 ID 和 Forge 用户查询签名。forge-server/forge-framework/forge-starter-parent/forge-starter-social/src/main/resources/mapper/SysUserSocialMapper.xml — 显式租户/连接/逻辑删除 SQL 和绑定 CAS。forge-server/forge-framework/forge-starter-parent/forge-starter-social/src/main/java/com/mdframe/forge/starter/social/service/ISocialUserService.java — 将所有企业身份方法增加 tenantId/connectionId。forge-server/forge-framework/forge-starter-parent/forge-starter-social/src/main/java/com/mdframe/forge/starter/social/service/impl/SocialUserServiceImpl.java — 连接内绑定、解绑、停用和兼容迁移;默认不保存用户 Token。java
public SysUserSocial selectBinding(Long tenantId, Long connectionId, String externalUserId);
public SysUserSocial selectBindingByUser(Long tenantId, Long connectionId, Long userId);
public boolean bindVerifiedIdentity(VerifiedSocialIdentity identity, Long forgeUserId);
client_secret 与缺少连接维度的身份绑定执行可盘点、可阻塞、可比较更新的迁移,不在 Flyway 中处理明文归属。forge-server/forge-framework/forge-plugin-parent/forge-plugin-collaboration/src/main/java/com/mdframe/forge/plugin/collaboration/service/CollaborationCredentialMigrationService.java — 旧配置 inventory、dry-run、完整预检、批次加密写入和旧列清空。forge-server/forge-framework/forge-plugin-parent/forge-plugin-collaboration/src/main/java/com/mdframe/forge/plugin/collaboration/service/CollaborationIdentityMigrationService.java — 按唯一租户/平台连接回填身份 connectionId,歧义数据形成阻塞报告。forge-server/forge-framework/forge-starter-parent/forge-starter-social/src/main/java/com/mdframe/forge/starter/social/mapper/SysSocialConfigMapper.java、SysSocialAppConfigMapper.java、SysUserSocialMapper.java 及对应 XML — 复用 Task 4A/4B 的单一 Mapper,补充 inventory 与 CAS SQL,不在 Collaboration Plugin 新建重复应用配置 Mapper。forge-server/forge-framework/forge-plugin-parent/forge-plugin-collaboration/src/main/java/com/mdframe/forge/plugin/collaboration/controller/CollaborationCredentialMigrationController.java — 仅授权管理员执行 inventory/dry-run/migrate,不返回明文或完整外部引用。java
public CryptoMigrationReport migrateCredentials(Long tenantId, String expectedActiveKeyId,
Integer batchSize, boolean dryRun);
public IdentityMigrationReport migrateIdentities(Long tenantId, Integer batchSize,
boolean dryRun);
forge-server/forge-framework/forge-starter-parent/forge-starter-social/src/main/java/com/mdframe/forge/starter/social/service/SocialOAuthStateService.java — Redis 一次性 state 和 socialTicket。forge-server/forge-framework/forge-starter-parent/forge-starter-social/src/main/java/com/mdframe/forge/starter/social/controller/SocialController.java — 按 connectionCode 发起授权,回调只返回票据,不记录/返回 AuthUser。forge-server/forge-framework/forge-starter-parent/forge-starter-social/src/main/java/com/mdframe/forge/starter/social/domain/dto/SocialLoginRequest.java、forge-server/forge-framework/forge-starter-parent/forge-starter-auth/src/main/java/com/mdframe/forge/starter/auth/domain/LoginRequest.java — 增加 connectionCode/socialTicket,弃用可信 socialUuid。forge-server/forge-framework/forge-plugin-parent/forge-plugin-system/src/main/java/com/mdframe/forge/plugin/system/strategy/SocialAuthStrategyImpl.java — 消费票据、按连接映射加载用户、关闭企业连接自动注册。forge-admin-ui/src/views/login/api.js、forge-admin-ui/src/views/login/callback.vue — 前端只传一次性票据。java
public String issueState(SocialOAuthIntent intent);
public SocialOAuthIntent consumeState(String state);
public String issueLoginTicket(VerifiedSocialIdentity identity);
public VerifiedSocialIdentity consumeLoginTicket(String ticket, LoginClientContext client);
forge-server/forge-framework/forge-plugin-parent/forge-plugin-collaboration/src/main/java/com/mdframe/forge/plugin/collaboration/provider/wecom/WeComProvider.java — 声明 LOGIN/DIRECTORY/MESSAGE/TODO/CALLBACK 能力。forge-server/forge-framework/forge-plugin-parent/forge-plugin-collaboration/src/main/java/com/mdframe/forge/plugin/collaboration/provider/wecom/WeComApiClient.java — 使用安全出站客户端调用固定官方端点,解析 errcode/errmsg/requestId。forge-server/forge-framework/forge-plugin-parent/forge-plugin-collaboration/src/main/java/com/mdframe/forge/plugin/collaboration/provider/wecom/WeComAccessTokenProvider.java — Token 读取、提前刷新、失效单次刷新和分布式锁。forge-server/forge-framework/forge-plugin-parent/forge-plugin-collaboration/src/main/java/com/mdframe/forge/plugin/collaboration/provider/wecom/WeComErrorClassifier.java — 将限流、Token 失效、永久参数错误、临时网络错误分类。forge-server/forge-framework/forge-starter-parent/forge-starter-outbound/src/main/java/com/mdframe/forge/starter/outbound/constant/OutboundScenes.java — 增加 COLLABORATION_PROVIDER。java
public String getAccessToken(CollaborationExecutionContext context, TokenType tokenType);
public <T> T execute(WeComRequest<T> request, CollaborationExecutionContext context);
public ProviderError classify(int httpStatus, int errorCode);
forge-server/forge-framework/forge-plugin-parent/forge-plugin-collaboration/src/main/java/com/mdframe/forge/plugin/collaboration/provider/wecom/WeComCallbackCrypto.java — URL 验证、SHA1 签名校验、AES 解密和 CorpId 校验。forge-server/forge-framework/forge-plugin-parent/forge-plugin-collaboration/src/main/java/com/mdframe/forge/plugin/collaboration/controller/CollaborationCallbackController.java — 接收 connectionCode + appCode 的 GET/POST 回调入口、请求大小/时间窗限制和快速应答。forge-server/forge-framework/forge-plugin-parent/forge-plugin-collaboration/src/main/java/com/mdframe/forge/plugin/collaboration/service/CollaborationCallbackInboxService.java — 事件 ID/规范摘要去重、加密负载、处理状态和重试。forge-server/forge-framework/forge-plugin-parent/forge-plugin-collaboration/src/main/java/com/mdframe/forge/plugin/collaboration/mapper/SocialCallbackEventMapper.java、forge-server/forge-framework/forge-plugin-parent/forge-plugin-collaboration/src/main/resources/mapper/SocialCallbackEventMapper.xml — 显式租户/连接查询和状态 CAS。java
public CallbackVerificationResult verifyAndDecrypt(WeComCallbackRequest request, CallbackCredential credential);
public CallbackAcceptResult accept(String connectionCode, String appCode, VerifiedCallback callback);
public int claimPendingEvents(Long tenantId, int batchSize, String workerId);
forge-server/forge-framework/forge-plugin-parent/forge-plugin-collaboration/src/main/java/com/mdframe/forge/plugin/collaboration/domain/entity/SocialOrgMapping.java、SocialPostMapping.java、SocialTag.java、SocialTagMember.java、SocialSyncLog.java、SocialSyncIssue.java — 同目录下新增实体。forge-server/forge-framework/forge-plugin-parent/forge-plugin-collaboration/src/main/java/com/mdframe/forge/plugin/collaboration/mapper/SocialDirectoryMappingMapper.java — 定义批量查询、upsert、last-seen 和停用签名。forge-server/forge-framework/forge-plugin-parent/forge-plugin-collaboration/src/main/resources/mapper/SocialDirectoryMappingMapper.xml — 部门/用户/岗位/标签映射 SQL。forge-server/forge-framework/forge-plugin-parent/forge-plugin-collaboration/src/main/java/com/mdframe/forge/plugin/collaboration/mapper/SocialSyncLogMapper.java、forge-server/forge-framework/forge-plugin-parent/forge-plugin-collaboration/src/main/resources/mapper/SocialSyncLogMapper.xml — 批次和问题单 SQL。java
List<SocialOrgMapping> selectOrgMappings(Long tenantId, Long connectionId, Collection<String> externalIds);
int markOrgSeen(Long tenantId, Long connectionId, String externalId, Long runId, String sourceHash);
int markUnseenOrgInactive(Long tenantId, Long connectionId, Long completedRunId);
Page<SocialSyncIssue> selectIssuePage(Page<?> page, Long tenantId, SocialSyncIssueQuery query);
tenant_id/connection_id/del_flag;批量同步不在 Service 构造 Wrapper;活动唯一键和 CAS 合同测试通过。forge-server/forge-framework/forge-plugin-parent/forge-plugin-collaboration/src/main/java/com/mdframe/forge/plugin/collaboration/provider/wecom/WeComDirectoryConnector.java — 分页读取部门、成员、成员详情、标签列表和标签详情。forge-server/forge-framework/forge-plugin-parent/forge-plugin-collaboration/src/main/java/com/mdframe/forge/plugin/collaboration/service/directory/DirectorySnapshotValidator.java — 校验重复 ID、父级、循环、根节点、分页完整性。forge-server/forge-framework/forge-plugin-parent/forge-plugin-collaboration/src/main/java/com/mdframe/forge/plugin/collaboration/service/directory/DirectorySyncPlanner.java — 计算 CREATE/UPDATE/UNCHANGED/INACTIVATE/ISSUE。forge-server/forge-framework/forge-plugin-parent/forge-plugin-collaboration/src/main/java/com/mdframe/forge/plugin/collaboration/service/directory/DirectorySyncOrchestrator.java — 锁、批次、阶段事务、last-seen 和完成后停用。forge-server/forge-framework/forge-starter-parent/forge-starter-collaboration/src/main/java/com/mdframe/forge/starter/collaboration/model/ExternalDepartment.java、ExternalUser.java、ExternalTag.java、DirectorySnapshot.java — Provider SPI 共用的外部快照模型;forge-server/forge-framework/forge-plugin-parent/forge-plugin-collaboration/src/main/java/com/mdframe/forge/plugin/collaboration/domain/model/DirectorySyncPlan.java — 编排层差异计划。java
public DirectorySnapshot fetchSnapshot(CollaborationExecutionContext context, DirectorySyncScope scope);
public void validate(DirectorySnapshot snapshot, DirectorySyncPolicy policy);
public DirectorySyncPlan plan(DirectorySnapshot snapshot, DirectoryMappingSnapshot current);
public DirectorySyncResult synchronize(Long connectionId, DirectorySyncCommand command);
sys_org/sys_user/sys_user_org,不覆盖 RBAC 和手工资产。forge-server/forge-framework/forge-plugin-parent/forge-plugin-collaboration/src/main/java/com/mdframe/forge/plugin/collaboration/service/directory/ForgeDirectoryWriter.java — 按父子顺序创建/更新映射拥有的组织和用户关系。forge-server/forge-framework/forge-plugin-parent/forge-plugin-collaboration/src/main/java/com/mdframe/forge/plugin/collaboration/service/directory/UserIdentityMatchPolicy.java — 已绑定、稳定员工编码、冲突和新建策略。forge-server/forge-framework/forge-plugin-parent/forge-plugin-collaboration/src/main/java/com/mdframe/forge/plugin/collaboration/service/directory/DirectorySyncIssueService.java — 建问题单、人工绑定/忽略/重试和审计。forge-server/forge-framework/forge-plugin-parent/forge-plugin-system/src/main/java/com/mdframe/forge/plugin/system/mapper/SysOrgMapper.java、SysUserMapper.java — 增加协同同步所需显式 Mapper 签名。forge-plugin-system/src/main/resources/mapper/SysOrgMapper.xml、SysUserMapper.xml — 租户和所有权边界 SQL。java
public DirectoryWriteResult apply(DirectorySyncPlan plan, DirectoryWriteContext context);
public IdentityMatchResult resolve(ExternalUser user, IdentityMatchContext context);
public void resolveIssue(Long issueId, SyncIssueResolution command, Long operatorId);
forge-server/forge-framework/forge-plugin-parent/forge-plugin-collaboration/src/main/java/com/mdframe/forge/plugin/collaboration/service/directory/DirectoryCallbackEventProcessor.java — 成员/部门/标签事件转平台无关命令。forge-server/forge-framework/forge-plugin-parent/forge-plugin-collaboration/src/main/java/com/mdframe/forge/plugin/collaboration/job/CollaborationDirectorySyncJobHandler.java — 全量/范围同步 Handler。forge-server/forge-framework/forge-plugin-parent/forge-plugin-collaboration/src/main/java/com/mdframe/forge/plugin/collaboration/job/CollaborationCallbackRetryJobHandler.java — 回调收件箱重试 Handler。forge-server/forge-framework/forge-plugin-parent/forge-plugin-collaboration/src/main/java/com/mdframe/forge/plugin/collaboration/job/CollaborationDeliveryRetryJobHandler.java — 消息/待办到期重试 Handler。forge-server/forge-framework/forge-plugin-parent/forge-plugin-collaboration/src/main/java/com/mdframe/forge/plugin/collaboration/service/CollaborationRetryPolicy.java — 指数退避、抖动、最大次数和永久失败分类。public RetryDecision nextAttempt(ProviderError error, int attempt, Instant now);
- **验收**:同连接并发 Job 只有一个执行;限流/网络/Token 失效策略正确;永久参数错误不无限重试;Job 日志不含个人资料或 Secret。
## Task 12:扩展消息核心的企业协同投递合同(P1)
- **目标**:消息中心向渠道提供 Forge 接收人,并保存逐人结果和并发安全幂等键。
- **涉及文件**:
- `forge-server/forge-framework/forge-starter-parent/forge-starter-message/src/main/java/com/mdframe/forge/starter/message/channel/ChannelType.java` — 增加 `COLLABORATION`。
- `forge-server/forge-framework/forge-starter-parent/forge-starter-message/src/main/java/com/mdframe/forge/starter/message/channel/MessageChannel.java` — 增加连接上下文、接收人和逐人结果模型,保持旧渠道兼容。
- `forge-server/forge-framework/forge-starter-parent/forge-starter-message/src/main/java/com/mdframe/forge/starter/message/sdk/MessageClient.java` — 能力路由和不存在渠道的稳定错误。
- `forge-server/forge-framework/forge-plugin-parent/forge-plugin-message/src/main/java/com/mdframe/forge/plugin/message/service/impl/MessageServiceImpl.java` — 批量接收人、幂等写入、部分失败和逐人状态。
- `forge-server/forge-framework/forge-plugin-parent/forge-plugin-message/src/main/resources/mapper/SysMessageMapper.xml`、`SysMessageReceiverMapper.xml` — 同目录下的原子幂等和投递状态 SQL。
- **关键签名**:
```java
public record ChannelSendRequest(Long tenantId, Long connectionId, Long messageId,
String idempotencyKey, List<ChannelRecipient> recipients,
String title, String content, Map<String, Object> params) {}
public record ChannelSendResult(String providerRequestId, List<RecipientDeliveryResult> deliveries) {}
forge-server/forge-framework/forge-plugin-parent/forge-plugin-collaboration/src/main/java/com/mdframe/forge/plugin/collaboration/provider/wecom/WeComMessageConnector.java — 组装 touser/agentid/msgtype,调用企微消息 API。forge-server/forge-framework/forge-plugin-parent/forge-plugin-collaboration/src/main/java/com/mdframe/forge/plugin/collaboration/message/CollaborationMessageChannel.java — 实现统一 COLLABORATION 渠道,按连接选择 Provider Connector。forge-server/forge-framework/forge-plugin-parent/forge-plugin-collaboration/src/main/java/com/mdframe/forge/plugin/collaboration/message/CollaborationRecipientResolver.java — 批量读取连接内用户映射,区分未映射/停用/可发送。forge-server/forge-framework/forge-plugin-parent/forge-plugin-collaboration/src/main/java/com/mdframe/forge/plugin/collaboration/message/CollaborationMessageTemplatePolicy.java — 文本、卡片字段、跳转 URL 和长度校验。forge-server/forge-framework/forge-plugin-parent/forge-plugin-collaboration/src/main/java/com/mdframe/forge/plugin/collaboration/controller/CollaborationMessageTestController.java — 仅授权管理员给明确测试用户发送测试消息。java
public ProviderMessageResult send(ProviderMessageRequest request, CollaborationExecutionContext context);
public RecipientResolution resolve(Long tenantId, Long connectionId, Collection<Long> forgeUserIds);
invaliduser 转逐人失败;测试接口不能向全员发送。forge-server/forge-framework/forge-starter-parent/forge-starter-collaboration/src/main/java/com/mdframe/forge/starter/collaboration/todo/CollaborationTodoPublisher.java — Flow 插件依赖的低层 SPI。forge-server/forge-framework/forge-plugin-parent/forge-plugin-collaboration/src/main/java/com/mdframe/forge/plugin/collaboration/todo/CollaborationTodoProjectionService.java — 创建、转派、完成、撤回、退回、终结状态机和版本。forge-server/forge-framework/forge-plugin-parent/forge-plugin-collaboration/src/main/java/com/mdframe/forge/plugin/collaboration/mapper/SocialTodoLinkMapper.java、forge-server/forge-framework/forge-plugin-parent/forge-plugin-collaboration/src/main/resources/mapper/SocialTodoLinkMapper.xml — 期望状态 CAS、领取到期记录和幂等键。forge-server/forge-framework/forge-plugin-parent/forge-plugin-collaboration/src/main/java/com/mdframe/forge/plugin/collaboration/provider/wecom/WeComTodoConnector.java — 创建/更新/关闭企微待办卡片。forge-server/forge-framework/forge-plugin-parent/forge-plugin-flow/src/main/java/com/mdframe/forge/starter/flow/listener/FlowTaskEventListener.java — 调用可选 Publisher,不直接调用企微 API。public TodoProjectionResult project(CollaborationTaskEvent event); public DeliveryClaim claim(Long linkId, long expectedVersion, String workerId);
- **验收**:创建/重复创建幂等;转派关闭旧人并创建新人版本;完成/撤回/终结关闭所有活动投影;外网失败不改变 Forge 任务状态。
## Task 15:待办安全入口、身份交换与受控回调动作(P2)
- **目标**:用户从企微进入或点击卡片动作时,重新验证身份、任务和权限,禁止链接篡改和过期任务执行。
- **涉及文件**:
- `forge-server/forge-framework/forge-plugin-parent/forge-plugin-collaboration/src/main/java/com/mdframe/forge/plugin/collaboration/todo/CollaborationTodoEntryService.java` — 生成/消费短期入口票据,发起企微 OAuth,安全跳转 Forge。
- `forge-server/forge-framework/forge-plugin-parent/forge-plugin-collaboration/src/main/java/com/mdframe/forge/plugin/collaboration/todo/CollaborationTodoActionService.java` — 映射外部身份并调用 Forge 受控流程动作。
- `forge-server/forge-framework/forge-plugin-parent/forge-plugin-collaboration/src/main/java/com/mdframe/forge/plugin/collaboration/service/CollaborationCallbackEventDispatcher.java` — 将卡片事件路由到 OPEN/APPROVE/REJECT/ACK 处理器。
- `forge-server/forge-framework/forge-plugin-parent/forge-plugin-collaboration/src/main/java/com/mdframe/forge/plugin/collaboration/controller/CollaborationTodoEntryController.java` — 入口和 OAuth 回跳。
- `forge-server/forge-framework/forge-plugin-parent/forge-plugin-flow/src/main/java/com/mdframe/forge/starter/flow/integration/FlowCollaborationActionGateway.java` — 实现 `CollaborationFlowActionGateway`,内部复用现有 `FlowTaskActionAuthorization/FlowTaskService`,不向 Collaboration Plugin 暴露 Flow 内部类。
- **关键签名**:
```java
public TodoEntryResult enter(String opaqueTicket, VerifiedSocialIdentity identity);
public FlowActionResult execute(VerifiedSocialIdentity identity, ExternalTodoAction action,
String idempotencyKey);
forge-admin-ui/src/api/collaboration.js — 连接、应用、测试和迁移摘要 API。forge-admin-ui/src/views/system/collaboration/index.vue — 企业协同连接列表和状态总览。forge-admin-ui/src/views/system/collaboration/components/ConnectionEditor.vue — 连接基础信息、权威和身份策略。forge-admin-ui/src/views/system/collaboration/components/ApplicationEditor.vue — LOGIN/DIRECTORY/MESSAGE/TODO 应用与 Secret 空值保留。forge-admin-ui/src/views/system/socialConfig.vue — 兼容跳转或只读提示,不继续回显旧 Secret。component 值实现为 connections.vue(连接列表+详情弹窗+应用/能力绑定编辑,替代 index.vue + ConnectionEditor/ApplicationEditor 拆分),API 层 src/api/collaboration.js 已建;socialConfig.vue 兼容改造与迁移摘要接口延后至 Task 19A 前补充。补齐后端能力绑定/应用删除端点与 V1.0.62__add_collaboration_binding_api_resources.sql(含 4 个新字典类型与 API 资源授权)。forge-admin-ui/src/views/system/collaboration/sync.vue — 同步触发、进度、计数、阶段和日志。forge-admin-ui/src/views/system/collaboration/issues.vue — 问题单绑定/忽略/重试。forge-admin-ui/src/views/system/collaboration/mappings.vue — 部门/用户/岗位/标签映射只读检索。forge-admin-ui/src/views/system/collaboration/deliveries.vue — 消息/待办投递、错误分类和重试。forge-admin-ui/src/views/system/collaboration/callback-events.vue — 回调元数据和处理状态,不展示解密正文。forge-server/forge-framework/forge-plugin-parent/forge-plugin-collaboration/src/main/java/com/mdframe/forge/plugin/collaboration/controller/CollaborationConnectionController.java — 连接、应用、能力测试和逻辑删除。forge-server/forge-framework/forge-plugin-parent/forge-plugin-collaboration/src/main/java/com/mdframe/forge/plugin/collaboration/controller/CollaborationOperationsController.java — 同步、问题单、映射、投递和回调查询/重试。forge-server/forge-framework/forge-plugin-parent/forge-plugin-collaboration/src/main/java/com/mdframe/forge/plugin/collaboration/dto/CollaborationConnectionSaveRequest.java、CollaborationAppSaveRequest.java、CollaborationSyncCommand.java — 同目录下的入参校验和敏感字段边界。forge-server/forge-framework/forge-plugin-parent/forge-plugin-collaboration/src/main/java/com/mdframe/forge/plugin/collaboration/vo/CollaborationConnectionVO.java、CollaborationSyncLogVO.java、CollaborationDeliveryVO.java — 同目录下的脱敏输出。forge-docs/guide/integration/enterprise-collaboration.md — 架构、Provider 扩展、配置、迁移、监控、故障和回退。text
system:collaboration:connection:list|create|update|delete|test
system:collaboration:sync:view|execute|resolve
system:collaboration:delivery:view|retry
system:collaboration:callback:view|retry
system:collaboration:credential:migrate
@ApiDecrypt;Service 和 Mapper 均显式校验租户;操作日志不记录请求 Secret。test-spec.md 形成可复跑证据,使 M1 和 M2 可以分别审查、验收和上线,避免待办资料阻塞一期。forge-server/forge-framework/forge-starter-parent/forge-starter-collaboration/src/test/java/com/mdframe/forge/starter/collaboration/provider/ProviderContractTestKit.java — 公共 Provider 合同。forge-server/forge-framework/forge-starter-parent/forge-starter-social/src/test/java/com/mdframe/forge/starter/social/security/SocialAppCredentialServiceTest.java — 凭据生命周期、认证密文和外部引用测试。forge-server/forge-framework/forge-plugin-parent/forge-plugin-collaboration/src/test/java/com/mdframe/forge/plugin/collaboration/service/CollaborationCredentialMigrationServiceTest.java、service/CollaborationIdentityMigrationServiceTest.java、provider/wecom/WeComAccessTokenProviderTest.java、service/directory/DirectorySyncOrchestratorTest.java、message/CollaborationMessageChannelTest.java、todo/CollaborationTodoProjectionServiceTest.java、todo/CollaborationFlowActionGatewayContractTest.java、service/CollaborationCallbackInboxServiceTest.java、mapper/CollaborationMapperXmlContractTest.java — 同测试源码根下的迁移、编排和合同测试。forge-admin-ui/src/views/system/collaboration/__tests__/ — Secret 表单、状态转换、问题单和投递交互测试。code-copilot/changes/unified-enterprise-collaboration/test-spec.md — 更新执行状态和基线。code-copilot/changes/unified-enterprise-collaboration/execution-log.md — 记录命令、数量、接口/数据库结论、警告、跳过和服务清理。milestone accepted 并独立上线;19B 通过后本变更才标记 done。未验证的能力不得写入对应里程碑完成声明。FeishuProvider、登录/目录/消息/待办/回调 Connector。ProviderContractTestKit 和真实飞书测试企业 UAT。DingTalkProvider、登录/目录/消息/待办/回调 Connector。ProviderContractTestKit 和真实钉钉测试企业 UAT。