后端分层

推荐依赖方向:

controller -> app/service -> domain -> infrastructure/mapper

每层职责:

  • controller:接收参数、权限入口、统一返回

  • app/service:编排用例、写审计、发事件

  • domain:业务规则、状态约束

  • infrastructure:数据库、Redis、外部 API、Outbox、任务

这个分层的重点不是“为了看起来像 DDD”,而是为了把三个最容易失控的东西拆开:

  • 接口层协议处理

  • 业务规则与编排

  • 技术基础设施接入

只要这三件事混在一起,后面权限、审计、异步事件、事务边界就会越来越难维护。

不允许的做法

  • controller 直接操作 mapper

  • 模块 A 直接改模块 B 的表

  • 因为“赶时间”就绕过统一异常、审计、权限上下文

  • 在多个模块里各自复制一套同类规则

system-service 的定位要特别看清

system-service 是平台控制面的核心服务,但它不是“什么都往里放”的大总管。它更像是平台内核,主要维护:

  • 用户和组织主数据

  • 角色、权限、菜单、权限快照

  • 系统配置、字典、审计

  • 平台级 AI 管理、在线会话、监控视图

如果一个能力具备独立数据生命周期、独立高频链路、独立扩容需求,就应该至少保持内部边界清晰,必要时进入独立服务评估,而不是继续无限吸收到 system-service

当前关键模块边界

auth-service

负责:

  • 登录、登出、刷新 token

  • 登录保护、验证码、二次认证

  • Passkey、微信登录

不负责:

  • 菜单树

  • 角色权限分配

  • 业务资源的数据范围判断

它负责证明“你是谁”,但不负责定义“你能做什么”。

system-service

负责平台控制面:

  • IAM、用户、角色、菜单、权限快照

  • 系统配置、字典、审计

  • AI 管理、在线会话、系统监控

不应该无限吸收所有业务能力。

可以把它理解成平台控制面的 owner,而不是所有业务域的默认收容站。

file-service

负责:

  • 上传、下载、预览

  • 图片与文档安全校验

  • 存储空间与 bucket 管理

它是文件 owner,其他模块需要文件对象时应通过它提供的契约接入。

文件一旦成为系统级资源,就很容易被很多地方共用。越是这种能力,越要明确 owner,不能把文件元数据散落在多个模块各管一份。

message-service

负责:

  • 站内信

  • 消息推送

  • 消息 outbox 与实时投递

它的重点不仅是“发消息”,还包括消息状态、投递链路、重放与实时性保障。

plugin-service

负责:

  • 插件包上传、安装、启停

  • 插件运行时隔离

  • 插件网关主流程

localization-service

虽然经常被忽略,但它本质上也是独立 owner 模块,负责:

  • 语言定义

  • 命名空间

  • 词条与翻译内容

  • 发布后的运行时语言包

owner 意识

在这个仓库里,“模块在不在一个进程里”不是重点,“谁是 owner”才是重点。

判断 owner 时优先看:

  • 表是谁维护

  • 生命周期由谁定义

  • 权限由谁解释

  • 异步事件由谁发出

允许的依赖方向到底意味着什么

推荐依赖方向:

controller -> app/service -> domain -> infrastructure/mapper

对应到实际开发时,可以这样理解:

  • controller 只负责入参、出参、权限入口和 HTTP 协议层细节

  • app/service 负责编排用例,比如“保存主对象 -> 写审计 -> 记录事件”

  • domain 负责规则,例如状态流转、字段约束、业务不变量

  • infrastructure 负责把这些规则落到数据库、Redis、外部服务、任务或文件系统上

这条依赖方向一旦被破坏,常见后果是:

  • 控制器里开始堆事务和业务逻辑

  • 规则散落在 mapper、util、定时任务里

  • 事件和审计漏写

  • 权限与数据边界越来越不清楚

新增能力放哪里

新增模块前先问自己三个问题:

  1. 这是平台控制面能力,还是独立业务域能力

  2. 它的数据和生命周期属于谁

  3. 它是否需要独立扩容、独立发布或独立事件链路

如果答案偏向独立业务域,就不要默认往 system-service 里塞。

什么时候应该评估“独立服务化”

满足以下任意两项时,就应该进入独立服务评估,而不是继续当成 system-service 的附属能力:

  • 拥有独立表族和清晰生命周期

  • 有自己的高频读写或异步处理链路

  • 需要独立扩容

  • 需要独立发布窗口

  • 故障不应该拖垮平台控制面主链路

当前最值得持续关注的方向通常包括:

  • AI 相关能力

  • 插件运行时

  • 本地化发布

  • 文件治理与处理链路