← 返回文章列表

DDD 实战(四):协同办公 IM 的领域全景

2026年6月25日架构设计
DDD协同办公IM领域建模

DDD 实战(四):协同办公 IM 的领域全景

推荐 BeWild 代充 Codex ,工作猛猛提效。

前面三篇讲了 DDD 的基本概念。这一篇开始进入完整案例:协同办公 IM 平台。

这里先说明边界:我们不讨论钉钉、飞书/Lark 内部真实架构,因为那不是公开事实。我们能做的是基于它们官网、开放平台文档和可观察产品能力,反推出一个中大型协同办公 IM 平台通常需要覆盖的业务域。

所以本文所有“领域划分”都是架构推导,不是对任何厂商内部实现的断言。

1. 为什么协同办公 IM 适合讲 DDD

协同办公 IM 看起来是聊天工具,但成熟产品早已不是单纯发消息。

从钉钉官网可以看到,它面向企业沟通、组织协作、业务流程、AI 办公和开放生态等场景。钉钉官网

飞书/Lark 也把即时沟通、日历、文档、审批、开放平台和智能协作组合在一起,强调一站式企业协作。飞书官网Lark 官网

开放平台文档进一步暴露了很多业务能力边界。比如飞书开放平台文档中可以看到通讯录、IM 消息、群组、事件订阅、机器人等能力入口。飞书开放平台文档

钉钉开放平台也提供通讯录、身份、消息、机器人、事件订阅、审批等开放能力入口。钉钉开放平台文档

这些公开能力说明,协同办公 IM 至少不是一个“消息表 + 群表 + 用户表”能概括的系统。它更像一个企业协作操作系统,IM 只是最高频入口。

2. 领域地图:先看全景

如果从 DDD 角度建模,一个协同办公 IM 平台可以先拆成这些限界上下文:

限界上下文主要职责核心模型不应该承担
Identity & Access账号、登录、认证、设备、登录会话、安全策略Account、Credential、Device、LoginSession、AuthPolicy不管理企业部门和好友关系
Tenant & Organization企业、部门、成员、组织角色、通讯录可见性Tenant、Department、Member、OrgRole、VisibilityRule不处理登录凭证和群成员治理
Contact & Relationship好友、联系人、外部联系人、黑名单、关系权限ContactRelation、FriendRequest、ExternalContact、BlockRelation不保存组织主数据
Group & Conversation群、群成员、会话、群治理、会话设置Group、GroupMember、Conversation、ConversationSetting不保存消息正文和搜索索引
Messaging消息发送、消息状态、撤回、引用、转发、已读未读Message、MessageReceipt、RecallRecord、MessageCursor不管理组织架构和群治理规则
Notification站内通知、离线推送、提醒、通知偏好Notification、PushSubscription、Reminder、NotifyPreference不作为业务事实源
Workbench & Workflow工作台、应用入口、审批、表单、任务、公告WorkbenchLayout、AppShortcut、ApprovalInstance、Form、Task不承担消息投递主链路
Open Platform应用、机器人、Webhook、事件订阅、API 凭证、配额App、Bot、WebhookSubscription、ApiCredential、ApiQuota不拥有内部业务数据
Search联系人搜索、消息搜索、文档搜索、应用搜索SearchDocument、IndexTask、SearchPermission不反写业务事实
Governance & Security审计、风控、水印、敏感词、合规、数据隔离AuditEvent、RiskRule、DlpPolicy、ComplianceReport不绕过业务域直接修改聚合

这张表不是最终答案,但它能帮助团队先建立讨论基线。

DDD 讨论最怕一开始就陷入“群表应该归哪个服务”“好友表应该放哪里”。更好的起点是先承认:这些概念背后有不同业务语言、不同变化节奏和不同一致性要求。

3. Identity & Access:账号不是组织成员

账号上下文处理的是“谁可以登录系统,以及以什么方式登录”。

它关心的是:

  • 账号 ID。
  • 手机号、邮箱、第三方身份。
  • 密码、验证码、单点登录、OAuth。
  • 设备绑定。
  • 登录会话。
  • 多端登录策略。
  • 风险登录和安全策略。

组织成员上下文处理的是“某个账号在某个企业里是什么身份”。一个账号可以加入多个企业,可以在不同企业有不同部门、岗位、角色和可见性。

因此 Account 和 Member 不应该强行合并。

如果把账号和成员揉成一个 User,短期会很省事,但后面会遇到很多问题:

  • 一个自然人加入多个企业时,字段归属不清。
  • 组织字段变化会污染登录模型。
  • 登录安全策略和组织权限策略互相耦合。
  • 外部联系人、客户、临时协作者难以表达。

更稳妥的模型是:账号上下文拥有 Account,组织上下文拥有 Member。二者通过 account ID 或主体 ID 关联,但各自维护自己的业务规则。

4. Tenant & Organization:企业协作的地基

协同办公 IM 和普通社交 IM 的最大差异之一,是它以组织为中心。

组织上下文通常要管理:

  • 租户和企业。
  • 部门树。
  • 成员。
  • 岗位、角色和职级。
  • 通讯录可见性。
  • 成员生命周期:邀请、入职、转岗、离职、禁用。
  • 组织字段脱敏和权限。

开放平台中的通讯录能力也能说明组织数据的重要性。飞书开放平台和钉钉开放平台都把用户、部门、通讯录作为开放能力的重要部分。飞书开放平台文档钉钉查询用户详情

组织上下文是很多其他上下文的上游,但不应该变成所有模块的超级中心。

例如消息发送需要判断成员是否还有效,文档权限需要判断成员是否属于某部门,开放平台事件需要通知成员变更。但这些不意味着消息、文档、开放平台都直接读写组织表。

更合理的做法是:组织上下文维护事实源,其他上下文通过 API、事件或缓存快照消费组织事实。

5. Contact & Relationship:关系不只是账号字段

很多早期 IM 系统会把好友关系直接放进用户模块。简单产品可以这么做,但协同办公 IM 往往更复杂。

关系上下文可能需要表达:

  • 好友申请。
  • 好友关系。
  • 外部联系人。
  • 客户联系人。
  • 拉黑关系。
  • 联系人备注。
  • 关系可见性。
  • 组织内外的联系策略。

一旦关系有了独立生命周期,就应该从账号或组织上下文里独立出来。

关系上下文不拥有账号,也不拥有组织成员。它只拥有“关系事实”。它可以引用账号 ID、成员 ID、外部联系人 ID,但不能修改账号状态或组织身份。

这样做的收益是关系规则可以独立演进。比如未来新增“客户联系人”“跨企业好友”“临时会话”“合作伙伴联系人”,不会把账号上下文越改越重。

6. Group & Conversation:群、会话和消息不是一回事

协同办公 IM 中,“群聊”是最容易混淆的模型。

至少要区分三个概念:

  • Group:群组本身,关注群资料、群成员、群主、管理员、入群规则、群公告、群治理。
  • Conversation:会话入口,关注用户侧的聊天列表、置顶、免打扰、草稿、会话设置。
  • Message:消息事实,关注发送、投递、撤回、已读、转发、引用、内容类型。

一个群可以对应一个群会话,但群不是会话,会话也不是消息容器。

如果把群、会话、消息都塞进一个 Messaging 模块,早期很快,但后期容易出现问题:

  • 群治理规则和消息投递规则混在一起。
  • 会话列表设置和群成员状态互相污染。
  • 群成员变更频繁影响消息主链路。
  • 大群消息扩散时,群聚合可能被错误放大。

更合理的方式是让群组上下文回答“这个群是什么,谁在里面,规则是什么”,让会话上下文回答“用户如何看到这个聊天入口”,让消息上下文回答“这条消息如何成为事实并被投递”。

7. Messaging:IM 的高频核心域

消息上下文通常是协同办公 IM 的核心域之一。

它关注的是:

  • 消息 ID 和幂等。
  • 消息内容类型。
  • 消息发送状态。
  • 撤回、编辑、引用、回复、转发。
  • 已读未读。
  • 多端同步游标。
  • 离线补拉。
  • 大群扇出。
  • 加密消息和普通消息的差异。

飞书开放平台的 IM 消息 API 暴露了应用发送消息、消息内容、接收方类型等能力,可以作为公开能力观察入口。飞书发送消息 API

但公开 API 只能说明产品开放了哪些能力,不能说明内部如何建模。我们能推导的是:成熟 IM 平台必然要把“消息事实”和“由消息触发的派生动作”区分开。

消息发送主链路应该尽量短:

  1. 鉴权和基础校验。
  2. 会话和群组规则校验。
  3. 消息幂等写入。
  4. 产生 MessageSent 领域事件。
  5. 返回发送结果。

通知、搜索、机器人、审计、AI 摘要不应该阻塞主链路。

8. Workbench、Workflow 与 Open Platform:IM 之外的协作能力

协同办公产品的复杂度,往往从“聊天”扩展到“工作发生在哪里”。

工作台和流程上下文可能包含:

  • 应用入口。
  • 审批。
  • 表单。
  • 公告。
  • 任务。
  • 日程。
  • 低代码应用。

开放平台上下文可能包含:

  • 企业自建应用。
  • 第三方应用。
  • 机器人。
  • Webhook。
  • 事件订阅。
  • API 凭证。
  • 权限范围。
  • 配额和审计。

飞书开放平台和钉钉开放平台都把开放能力作为重要入口,这说明协同办公 IM 不只是用户之间的通信系统,也是企业应用生态的承载层。飞书开放平台文档钉钉开放平台文档

这里的建模重点是:开放平台不应该拥有内部业务事实。它应该通过授权、API、事件订阅和防腐层访问内部上下文。

9. Search、Notification、Governance:跨域支撑能力

搜索、通知、安全治理这些能力经常被误放。

搜索不是业务事实源。消息、联系人、文档、应用才是事实源,搜索只是索引和查询视图。搜索索引可以延迟,可以重建,不能反写消息事实。

通知也不是业务事实源。通知由业务事件触发,比如成员加入、审批通过、消息发送、文档分享。通知上下文负责偏好、渠道、频控、推送状态,不应该决定业务动作是否成立。

治理和安全更特殊。审计、风控、敏感词、水印、合规策略会影响多个域,但它们也不应该绕过业务模型直接改数据。更好的做法是:

  • 风控前置参与决策。
  • 审计通过事件记录事实。
  • DLP 和水印通过策略影响文档、消息和文件上下文。
  • 合规报表消费审计和业务事件。

这类横向能力要特别小心。它们既重要,又容易侵入所有模块。DDD 的边界设计,就是为了让它们通过清晰接口协作,而不是到处打补丁。

10. 第一版领域地图应该如何落地

如果从零设计一个协同办公 IM,不建议一开始就拆十几个微服务。更务实的做法是:

第一阶段,先在代码里建立模块边界:

  • identity
  • organization
  • relationship
  • group
  • messaging
  • notification
  • workflow
  • openplatform
  • search
  • governance

第二阶段,找出高变化、高吞吐、高故障隔离要求的上下文,优先拆部署:

  • messaging
  • group
  • openplatform
  • search
  • notification

第三阶段,再根据团队组织和业务增长拆更多服务。

领域地图不是服务拆分清单,而是讨论业务边界、数据所有权和演进方向的地图。

下一篇我们专门讨论最容易争议的边界:账号、组织、关系、群组和会话。

返回博客列表