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 | 封装数据库查询,继承泛型基类 | 包含业务逻辑 |
| Model | ORM 表映射,定义表结构和约束 | 包含查询逻辑 |
| Infrastructure | 数据库连接池、Redis、JWT、邮件、限流器 | 被上层直接绕过 |
为什么要这么分?因为混层代码的代价太大了——Router 里直接写 SQL,Service 里直接操作 Session,改一个功能要动三个文件,debug 的时候不知道逻辑在哪一层。五层架构的代价是文件多,但好处是改任何一层都不影响其他层。新增业务模块就像填表——每层写对应的代码,不会串。
开箱即用的能力
| 能力 | 说明 |
|---|---|
| JWT 双 Token | Access 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"就行。
开发日记
-
邮件系统、RBAC权限、定时任务
邮件多通道容灾、RBAC多端权限、定时任务热重载、分布式限流、审计日志、管理后台API。