Elexvx
架构设计

后端模块边界

了解后端模块如何分层、如何划分 owner,以及哪些依赖是被允许的。

后端分层

推荐依赖方向:

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 相关能力
  • 插件运行时
  • 本地化发布
  • 文件治理与处理链路

目录