Basic_Web:10 分钟搭好生产级 SaaS 底座

FastAPI + Vue 3 · 登录、权限、部署、限流全搞定 · 不用再花一周搭基建

为什么做这个

每个 SaaS 都要写登录注册、角色权限、邮件发送、审计日志——这些代码跟业务半毛钱关系都没有,但你不写项目就跑不起来。我知道这件事,所以一开始就先把脚手架做了。

Basic_Web 就是这个脚手架。有了它,搭 Promo_Web 只花了2个小时——改个项目名和数据库配置,认证、权限、邮件、审计日志全有了,直接开始写业务逻辑。后来 FinBuddy_Web 也从它继承,基础设施写一次,到处复用。

设计理念

三个原则,贯穿整个项目:

1. 不是产品,是起点

Basic_Web 不解决任何具体业务问题。它解决的是"每个 SaaS 都要做但没人想重复写"的问题。用户认证、权限控制、邮件发送、审计日志、定时任务、健康检查——这些东西每个项目都要,但每次从零写起都是浪费时间。

所以 Basic_Web 的目标是:改个项目名,配个数据库,就能开始写业务代码。不需要先花一周搭基础设施。

2. 约定大于配置

新增一个业务模块只需要7步:Model → Repository → Service → Schema → Router → 注册路由 → 注册模型。每一步都有基类和模板,不需要从空白文件开始写。Repository 层有泛型基类,CRUD + 分页一行都不用写,子类只需设置 self.model

所有 API 返回统一格式 {code, message, data},分页有 PagedData 泛型。前端不用适配各种奇奇怪怪的响应格式。

3. AI 友好

项目里有11个规则文件,覆盖编码规范、分层架构、API设计、安全、日志、数据库、错误处理。配合 AI 编程工具,新增代码能始终符合项目规范。AI 不需要"理解"整个项目,只需要按规则文件填表。这也是我在 Vibe Coding 里反复强调的——规则越明确,AI 产出越稳定。

五层架构

整个后端严格分成五层,单向依赖,禁止反向调用:

职责禁止
Router接收请求,参数校验,调用 Service,返回响应直接操作数据库、包含业务逻辑
Service编排业务流程,跨 Repository 协调直接写 SQL、在 Service 内 commit
Repository封装数据库查询,继承泛型基类包含业务逻辑
ModelORM 表映射,定义表结构和约束包含查询逻辑
Infrastructure数据库连接池、Redis、JWT、邮件、限流器被上层直接绕过

为什么要这么分?因为混层代码的代价太大了——Router 里直接写 SQL,Service 里直接操作 Session,改一个功能要动三个文件,debug 的时候不知道逻辑在哪一层。五层架构的代价是文件多,但好处是改任何一层都不影响其他层。新增业务模块就像填表——每层写对应的代码,不会串。

开箱即用的能力

能力说明
JWT 双 TokenAccess 30分钟 + Refresh 7天,改密码自动失效旧 Token,前端自动刷新
RBAC 多端权限同一个用户在 Web/App/小程序三个端看到的权限不同,角色跟着人走,权限跟着端走
审计日志管理员操作自动记录,操作人、操作类型、目标资源、来源 IP 全有
邮件系统多通道容灾(主通道挂了自动切备用),数据库模板管理,发送记录追踪
定时任务数据库配置驱动,运行时热重载,多实例部署只有一个执行
分布式限流登录5次/5分钟,注册10次/小时,防暴力破解
分布式信号量跨实例并发控制,比 Python 内置的 threading.Semaphore 适合多进程部署
健康检查存活检查 + 就绪检查(验证 DB 和 Redis 连通性)
数据库迁移Alembic + 种子数据,alembic upgrade head 一步到位
前端脚手架Vue 3 + Element Plus + 路由守卫 + Token 自动刷新 + 自动导入

几个我觉得值得说的设计

邮件容灾

邮件系统做了三层架构:EmailProvider 抽象基类 → EmailRouter 通道路由器 → InfraEmailService 门面。主通道挂了自动切备用通道,备用也挂了还有兜底。模板存在数据库里,管理员在后台就能改,不用改代码重新部署。每封邮件的发送结果都记录在 email_logs 表里,出问题能追溯。

定时任务热重载

任务定义存在 scheduler_configs 表里,后台线程每分钟检查 updated_at 字段,变了就自动重载。不需要重启服务。用 Redis JobStore 确保多实例部署时只有一个实例执行任务。还有个 @task 装饰器,新任务注册就像加个注解一样简单。

RBAC 多端权限

FinBuddy 有桌面端和 Web 端,同一个管理员在两个端能做的事不一样。普通 RBAC 做不到这一点——它只管"这个角色能做什么",不管"在哪个端能做"。所以 Basic_Web 从一开始就设计了 PlatformPermission 表:同一个角色在不同端有不同的权限集合。

改密码自动失效旧 Token

用户改密码后,token_version 递增,所有已签发的 JWT 自动失效。不需要维护 Token 黑名单,不需要 Redis 存废弃 Token。前端 Axios 拦截器检测到 401 自动用 Refresh Token 换新的 Access Token,用户无感知。

一键启动

开发环境一个命令启动前后端:

python dev.py          # 同时启动后端(uvicorn + reload)和前端(Vite dev server)
python dev.py --back   # 只启动后端
python dev.py --front  # 只启动前端

文件变更自动重载,彩色输出区分前后端日志。不需要开两个终端。

集群部署

Basic_Web 从一开始就考虑了多实例部署:

  • INSTANCE_COUNT 配置项:连接池大小按实例数等比缩减,3个实例每个开1/3的连接
  • Redis JobStore:定时任务只在一个实例上执行
  • 分布式限流器/信号量:跨实例的并发控制,基于 Redis INCR + EXPIRE
  • 三环境配置(Dev/Staging/Prod):通过 ENV 环境变量切换

继承它的项目

Basic_Web 的核心代码已经跑在两个项目里了:

  • FinBuddy_Web — AI Agent 平台后端,在 Basic_Web 基础上加了 LLM 代理、积分系统、WebSocket
  • Promo_Web — 营销网站生成器,在 Basic_Web 基础上加了模板引擎、域名管理

两个项目的认证、权限、邮件、审计日志代码完全一样,区别只在业务层。这就是脚手架的价值——基础设施写一次,到处复用。

想用?

Basic_Web 目前还没开源,但如果你在做 SaaS 项目、需要一套生产级的基础设施,可以加我微信聊聊。我可以分享项目结构、设计思路,或者帮你基于 Basic_Web 搭建你的项目。

加微信

扫描 关于页 的二维码,备注"Basic_Web"就行。

开发日记

  1. 邮件系统、RBAC权限、定时任务

    邮件多通道容灾、RBAC多端权限、定时任务热重载、分布式限流、审计日志、管理后台API。

404 Not Found

404 Not Found


nginx