01

先看全景:这不是一个服务,而是一套平台

上一版课程偏重“发一条消息会经过什么”。这一版我们先把镜头拉远:`im-app-server`、`im-admin-server`、AWS 运行层与发布脚本,合起来才是你真正要指挥的 IM 平台。

先认角色,再看细节

你可把它想成一座商场。`im-app-server` 面向普通用户,像前台营业区;`im-admin-server` 面向租户管理员、开放平台和运营动作,像后场管理区;AWS 则是整栋楼的水电、仓储与安保系统。

入口层

🌐
公网入口 / ALB

应用层

💬
im-app-server
🛠️
im-admin-server

基础设施层

☁️
ECS / Fargate + 数据层
🚀
spug/aws 脚本
逐个点卡片。先看平台分层,再回到代码,理解会快得多。
💡
为什么先看全景

若你一开始只盯某个控制器,就容易误把“业务代码问题”当成“架构分工问题”。真正成熟的排障,先问哪一层,再问哪一行。

三个目录,各管一摊

把仓库拆成三块看,会比把几百个文件一把抓更容易。你以后让 AI 干活,也该先点名“去哪块地里挖”。

im-app-server/ 对终端用户开放的主业务后端:登录、消息、群组、上传、会话、消费者。
im-admin-server/ 租户后台与运营后端:管理员登录、租户配置、开放平台、翻译、聊天分享、共享会议。
spug/aws/ 部署与运行脚本:构建镜像、升级 ECS、跑 PG/DDB 迁移、同步配置与 Secret。

真实代码:Admin 服务先放公开接口,再进后台授权区

这段入口代码很能说明 `im-admin-server` 的定位。它不是一个静态后台页面接口,而是一套带公开分享口、开放平台口、再加后台受权区的独立服务。

代码

app.use(bodyParser());
app.use(SetRequest);
app.use(Access);
app.use(apiRoutes.base.router.routes());
app.use(apiRoutes.chatShare.publicRouter.routes());
app.use(apiRoutes.openPlatform.router.routes());
app.use(Authorize);
app.use(apiRoutes.admin.router.routes());
app.use(apiRoutes.tenant.router.routes());
app.use(apiRoutes.referral.router.routes());
app.use(apiRoutes.translation.router.routes());
app.use(apiRoutes.sharedMeeting.router.routes());
app.use(apiRoutes.externalData.router.routes());
app.use(apiRoutes.chatShare.router.routes());
          
白话

先装请求体解析、上下文与基础访问控制,这是所有接口都要走的底层工序。

`base`、公开分享 `chatShare.publicRouter`、开放平台 `openPlatform` 被放在授权中间件之前,说明它们有独立认证方式或公开入口。

`Authorize` 从这里开始像一道闸门,后面的 `admin`、`tenant`、`translation`、`sharedMeeting` 等都属于后台受控区域。

所以 `im-admin-server` 是“多入口的后台服务”,不是单纯的管理页 BFF。

小测:你已经分清平台边界了吗

若需求是“普通用户发送一条群消息并更新未读数”,你首先应把 AI 引到哪块?

为什么这个仓库把 `im-admin-server` 单独拉出来,而不是全塞进 `im-app-server`?

如果你要查“某次上线后为何版本没有切到新镜像”,最该优先看哪里?