跳到主要内容
gm-libs packages in the homelab console

gm-libs:每个 Webanion 前端与后端起步所依托的软件包

Webanion brand logoWebanion附加服务6月 15, 20265 个月

一个带版本、与框架无关的软件包家族,Webanion 的每个前端和后端都以它为起点,服务端有一层 NestJS,客户端有 React、Vue 和 Expo 绑定:支持通行密钥和单点登录的身份认证、功能开关、审计日志、多租户数据、加密、文件、文档、消息、实时与离线、webhook、worker 和一套 UI 组件库。每个包都有自己的私有仓库和独立发布,从工作室的私有 npm registry 安装,工作室的控制台会显示哪个消费方在哪个版本上落后。

NestJSTypeScriptNode.jsPostgreSQLOpenFGATemporalDockerSoftware ArchitectureSaaSVerdaccio
Md Moniruzzaman Image

Md Moniruzzaman

完整故事

为什么把鉴权、审计和功能开关一次做好、纳入版本管理并在各处复用,会让一家工作室的客户受益更多。

每个后端都曾从零开始

客户付费开发的每个后端,在做任何客户真正关心的事情之前,都需要同样的基础:登录、会话、权限、配置、文件存储、邮件、PDF、后台任务和审计日志。如果每个项目都重新编写,这些部分要耗费数周时间,每个项目各不相同,还各自带着自己的 bug。

gm-libs 就是答案:把这些底层基础设施从早已验证过它们的项目中提取出来,加固成带有版本、文档和变更日志的包,并在工作室构建的各个前端和后端中复用。

登录与权限,一次解决

鉴权包提供 Argon2id 密码哈希、短时效的访问令牌配合轮换的刷新会话,以及基于 OpenFGA 的关系型权限,因此像“分支机构员工只能看到自己所在的分支机构”这样的规则,是一个声明式的模型,而不是散落在代码各处的检查。它还支持带账号关联的社交登录和 OIDC 登录、无密码登录、多因素认证、通行密钥和单点登录。新后端只需导入一个模块,就能获得全部这些能力。

对客户而言,这意味着安全机制已经在一个金融平台上经过加固和测试,而不是在截止日期的压力下重新发明。

Brand colour backdrop
Sign in and permissions from one module: Argon2id, rotating sessions, OpenFGA relationship checks
The console's consumer drift for the finance platform's backend: every @gm-libs dependency, auth among them, resolves to its latest release

安全地开启功能

功能开关包决定为每个租户、分支机构、角色或个人展示什么、运行什么,而且从不阻塞请求:开关从内存中读取,如果无法连接开关服务器,每个开关都会回退到安全的默认值,除非团队另有选择,否则默认关闭。它与授权配合使用,而不是取代授权,因此只有开关和权限都同意时,功能才会出现。

客户可以先把一个功能发布给一个分支机构或一个人,观察效果,再无需重新部署就扩大范围,Al-Insaf 团队就是这样管理自己的功能的。

Brand colour backdrop
Al-Insaf feature management, where the flags are set per role and per person
Two gates on every request: the feature flag and the permission must both say yes

从不拖慢任何人的审计日志

审计包会在每一次写操作时记录谁在何时、何地做了什么,按类别和严重程度分类,并把每条记录移出请求路径,再分批写入。审计存储变慢或出错时会被记录到日志中,但绝不会阻塞正在使用系统的人,正因如此,才能放心地审计一切重要操作。

Brand colour backdrop
One audited write: the entry is built on the request and stored in batches off it

每个包,只做一件事

除了 auth、flags 和 audit,这个家族还覆盖了前端和后端所需的其余部分,每个包只做一件事,接入方式也完全一致:底层是与框架无关的代码,服务端有一层 NestJS,包延伸到客户端的地方则提供 React、Vue 和 Expo 绑定。

  • 基础与数据:core(错误、请求上下文、会隐去凭据的日志器、缺少密钥时立即报错的类型化配置、金额、分页、限流、幂等、健康检查)和 db(多租户 Postgres,每个租户独立一个数据库,附带迁移和模型)。
  • 身份与访问:auth、flags、audit,以及用于字段和密钥信封加密、密钥可轮换的 crypto。
  • 文件、文档与消息:用于存储和签名上传的 media、pdf,用于流式 CSV 和 XLSX 导出及带校验导入的 tabular,用于邮件、短信、推送和团队聊天的 notifications,以及用于实时对话的 chat。
  • 实时与离线:用于经过认证的按频道事件的 realtime,带有适用于 React、Vue 和 Expo 的自动重连客户端;以及 offline,为每个用户提供缓存和只发送一次的写入队列,可用于浏览器和 Expo 应用。
  • 集成与运行时:按 Standard Webhooks 规范签名的 webhooks,用于 Temporal 的 worker,提供加固的无头浏览器和拒绝内部地址的出站请求的 web,用于流式加密数据库备份的 datavault,以及用于构建 MCP 服务器的 mcp。
  • 界面:ui,从设计令牌到 React、Vue、Next.js 和 Expo 组件。

此外,devkit 是每个库在发布前都要运行的检查。每个包都有自己的私有仓库和独立的发布版本,因此只有当客户的团队采用新版本时,客户的系统才会改变。

Brand colour backdrop
Drawn map of the gm-libs packages grouped by job: foundation and data, identity and access, files, documents and messages, real time and offline, integration and runtime, and interface, with the devkit as the shared release check
The console's delivery table filtered to the gm-libs organisation: each library repository with what merging it deploys, its concurrency group and whether it may be merged from the board

一次修复,惠及所有系统

由于工作室的前端和后端共享同样的基础,一次安全修复或改进只需提升版本号,就能到达每一个前端和后端,并附有说明改了什么、为什么改的变更日志。各次发布都严格遵守语义化版本,因此不会因为另一个客户需要新功能,就让某个客户的系统出问题,而控制台当天就能显示哪个消费方还没有采用新版本。

对客户来说,结果是更快的交付、更少的意外,以及一个由已在别处经过生产环境检验的组件构建的产品,其中包括Al-Insaf 的故事中那个达到账本级严谨度的金融平台。

每个包,已发布且受到监看

每个包都从工作室的私有 npm registry 安装,工作室的控制台也像消费方一样读取这个 registry。它会 ping registry,读取每个包的每个版本及其发布时间、打包大小和完整性,并读取各消费方默认分支上的清单文件,判断每个依赖是否解析到最新发布。一个库家族的价值,取决于能否证明使用它的每个系统都是最新的,而这份证明就在这里。

在截图当天,也就是 2026 年 9 月 30 日,视图显示 registry 运行正常、每个包都已发布、registry 本身有一份最近的备份,并且除工作室自己的工具之外,每个消费方都在使用最新发布,那些工具仍停留在 core 和 pdf 的较早版本上。

Brand colour backdrop
The console's Packages view of the private npm registry: the registry up, every package published, the age of the registry backup, and the consumer drift table with any dependency that is behind flagged
The Packages table: every @gm-libs package with its latest version, publish age, packed size, published state and version count

从 GitHub Release 到 npm install,经由工作室的 registry

给某个库打上标签,就会在 GitHub 上运行它的发布流程,并在 Release 中附上一个打包文件。集群内的同步任务每五分钟发布一次这个完全相同的文件,因此 Release 和 registry 中保存的是相同的字节,每晚还会再核对一次。读取需要登录,公开域名拒绝一切写入。之所以没有采用 GitHub Packages,是因为这些库和它们的消费方位于不同的组织中。

Brand colour backdrop
Drawn path of a library version: a tag, the GitHub release with one packed file, the sync in the cluster publishing that exact file every five minutes, the nightly check against the release, and npm install from the private registry with a login

你可能也喜欢

fully booked brand logo
Fully Booked Video Editing
附加服务
2 年 3 个月
fully booked brand logo

Fully Booked:推广和教程视频制作

一支推广视频,按照英国小巴运营商最关心的顺序,带他们了解 Fully Booked 的好处,用的是真实应用而不是素材库画面。视频从运营商自己的问题开篇,每项好处都在真实界面上占一个节拍,并剪成多种时长,从社交信息流上几秒钟的开场钩子,到用于落地页和应用商店页面的完整版本。

Md Moniruzzaman Image

Md Moniruzzaman

6月 24, 2025

+1
Dominic Dormer
fully booked brand logo
Fully Booked Photoshop Design
附加服务
2 年 3 个月
fully booked brand logo

Fully Booked:使用 Photoshop 的视觉资产设计

商店截图、宣传图、应用图标和邮件插画,都在 Photoshop 中用真实界面制作,让一个年轻的平台在运营商眼中显得成熟可靠。截图在 Apple 和 Google 要求的每种尺寸下用五次滑动讲完整个卖点,每封邮件都以一幅品牌配色的专属插画开头,图标和启动画面上是两只手相握的标志。

Md Moniruzzaman Image

Md Moniruzzaman

6月 24, 2025

+1
Dominic Dormer
fully booked brand logo
Fully Booked UI UX Design
附加服务
2 年 3 个月
fully booked brand logo

Fully Booked:移动应用和管理面板的 UI/UX 设计

Fully Booked 的每一个界面都始于一张草图,在为任何代码付费之前就由创始人批准,每一个界面都在回答运营商或客户的某个问题。运营商首页变成了一份收入菜单,Get Covered 保留了手绘流程的顺序,报价单和取消信来自创始人自己的措辞,管理后台则从五个线框标签页成长为整个网络的控制室。MVP 的界面由 Webanion 的另一位设计师设计;第 2、3、4 阶段由我本人以这些流程为基础在 Figma 中重新设计。

Md Moniruzzaman Image

Md Moniruzzaman

6月 24, 2025

+1
Dominic Dormer
Read the Md Moniruzzaman blog

博客是来自生产一线的笔记:架构决策、经受住真实用户考验的 AI 系统、能自己挣回成本的基础设施。写于工作之中,而不是隔岸观火。