FastSoyAdmin
April 30, 2026 · View on GitHub
Overview
A batteries-included full-stack admin template — usable as an internal-tools scaffold and as a reference for modern full-stack development.
- Backend — FastAPI · Pydantic v2 · Tortoise ORM · Redis
- Frontend — Vue3 · Vite7 · TypeScript · Naive UI · UnoCSS · Pinia · Alova · Elegant Router
- Infra — Docker Compose (Nginx + FastAPI + Redis), multi-worker startup lock, fastapi-guard, built-in Radar dashboard
- Code generator —
cli-initto scaffold, writemodels.py,cli-gen-allto emit backend + frontend CRUD
Highlights
AI-native
- AI-coding friendly — ships with CLAUDE.md + llms.txt / llms-full.md feeding Claude Code / Cursor / Copilot the full architecture, layering rules, API conventions, response codes and PR checklist; agents produce code that matches project conventions out of the box
- Generator as the AI workbench —
cli-gen-allcollapses "add a table" into one command; the agent only ownsmodels.pyand override diffs, the rest is emitted by the CLI
Engineering velocity
- End-to-end CLI codegen — one command turns a Tortoise model into full backend (schemas / controllers / api) + frontend (views / service / typings / i18n) CRUD
- CRUDRouter +
@crud.override— the factory emits 6 standard routes; only override diffs. "No aggregate roots" boundary is explicit to prevent abstraction bloat
Extensible architecture
- Autodiscovered modules — drop a package into
app/business/<name>/and routes, models, and init data register themselves; modules are decoupled, cross-module talk goes via the event bus (emit/on) - Multi-database friendly — modules can declare their own
DB_URLand get a dedicatedconn_<biz>; transactions always go throughin_transaction(get_db_conn(Model)) - Multi-worker startup coordination — a Redis leader lock serializes
init_menus → refresh_api_list → init_data → refresh_cache, so K8s replicas don't double-reconcile
Security & permissions
- Three-tier RBAC + row-level
data_scope— menu / API / button checks plusall / department / self / customdata scope; button checks live in services, not just in UI - Menu / role IaC reconciliation —
ensure_menu/reconcile_menu_subtree/refresh_api_listgive three explicit semantics so you know which subtrees are code-owned and which are user-editable - Sqid public IDs — auto-increment IDs never leak; enumeration-safe
Contracts & typing
- Unified responses —
{code, msg, data}with HTTP 200 + snake_case ↔ camelCase;BizErrorpropagates business failures with unique codes - End-to-end type safety — basedpyright (standard) on the backend, vue-tsc on the frontend, both gated in CI
- Statically checked i18n — generator output merges via
import.meta.glob;App.I18n.GeneratedPagesletsvue-tscvalidate every$tkey
Observability & resilience
- Built-in Radar dashboard —
/manage/radar/*for real-time request / SQL / exception / permission-deny logs - fastapi-guard — rate limiting + IP banning; blocks brute-force and scanner traffic automatically
- Redis cache + graceful fallback — role permissions, constant routes and
token_versionare cached; queries fall back to the DB if Redis is down - State machine / event bus — first-class primitives for workflows like tickets, approvals, orders
Deployment
- One-command Docker — Nginx + FastAPI + Redis pre-wired;
docker compose up -dand you're live
Links
Branches
| Branch | Purpose |
|---|---|
main | Default; includes the HR example (app/business/hr/ — employees / departments / tags) |
slim | Clean skeleton with no business examples (in preparation) |
Want a clean start now? Delete
app/business/hr/before launching — autodiscover will skip it.
Getting Started
Requirements
| Tool | Version |
|---|---|
| Python | >= 3.12 |
| Node.js | >= 20 |
| uv · pnpm · make | latest |
Docker (recommended)
git clone https://github.com/sleep1223/fast-soy-admin.git
cd fast-soy-admin
make up # docker compose up -d
docker compose exec app uv run python -m app.cli initdb # first-run: create tables + seed
docker compose restart app
Open http://localhost:1880.
Migrations do not run automatically; the container's SQLite is not volume-mounted by default. For production, switch to an external DB or mount a volume for
app_system.sqlite3. See the deployment guide.
Local development
git clone https://github.com/sleep1223/fast-soy-admin.git
cd fast-soy-admin
make install-all # uv sync + pnpm install
cp .env.example .env # copy env template; update SECRET_KEY / DB_URL / REDIS_URL as needed
make initdb # first-time: create tables + seed
make dev # backend (:9999) + frontend (:9527) in parallel, Ctrl+C stops both
Common Commands
All commands are wrapped in Makefile. Run make help for the full list.
| Command | Purpose |
|---|---|
make dev | Run backend + frontend dev servers together |
make check-all | Run all backend + frontend quality gates (pre-commit) |
make mm | makemigrations + migrate |
make cli-init MOD=xxx | Scaffold a new business module |
make cli-gen MOD=xxx | Generate backend code from models.py |
make cli-gen-web MOD=xxx CN=name | Generate frontend code from models.py |
make cli-gen-all MOD=xxx CN=name | Generate both at once |
make up / make down / make logs | Docker lifecycle |
See the commands reference for the complete list.
Adding a new business module
make cli-init MOD=inventory # 1. scaffold the module
$EDITOR app/business/inventory/models.py # 2. define Tortoise models
make cli-gen-all MOD=inventory CN=Inventory # 3. generate backend + frontend CRUD (i18n auto-merged)
make mm # 4. run migrations
make dev # 5. verify
make check-all # 6. pre-commit
Walkthrough and field type mappings: Development guide.
Architecture
app/
├── core/ # Framework infra (CRUDBase / CRUDRouter / Schema / auth / cache / events / Sqids)
├── system/ # System modules (auth / user / role / menu / api / dictionary / radar)
├── business/ # Business modules (autodiscovered)
│ └── hr/ # Reference module
├── cli/ # Code generator
└── utils/ # Unified re-export surface for business modules
web/src/
├── views/ # Pages (Elegant Router source)
├── service/api/ # Alova HTTP wrappers
├── typings/api/ # TS types
├── store/modules/ # Pinia
├── router/ # Elegant Router + guards
└── locales/ # vue-i18n
Layers: api/ → services/ → controllers/ → models + schemas. Business modules must not reverse-import app.system.* (except a few explicitly exposed services) and must not import sibling modules — cross-module talk uses the event bus. See architecture.
Switching databases
Change DB_URL in .env and run make initdb. PostgreSQL / SQLite / MySQL / SQL Server supported.
PostgreSQL (tortoise-orm[asyncpg]) and SQLite (aiosqlite, ships with tortoise-orm) are bundled by default; install extras for other engines:
uv sync --extra mysql # MySQL (asyncmy)
uv sync --extra mssql # SQL Server (asyncodbc)
uv sync --extra oracle # Oracle (asyncodbc)
A module can declare its own DB_URL in config.py; autodiscover registers it as conn_<biz>. For cross-model transactions, use get_db_conn(Model) to pick the connection. See switch database.
Response Codes
All endpoints return {"code": "xxxx", "msg": "...", "data": ...} with HTTP status always 200.
| Range | Meaning | Typical frontend behavior |
|---|---|---|
0000 | Success | Normal processing |
1xxx | Internal / serialization error | Auto-toasted by the framework |
21xx | Auth failure (token / session) | Logout / modal / auto token refresh |
22xx | Authorization failure (RBAC / button) | Show error toast |
23xx | Resource conflict (unique constraint) | Show error toast |
24xx | Generic business failure | Show error toast |
25xx | Rate-limit / security | Show error toast |
26xx | Schema required-field fallback | Show error toast |
4000–9999 | User-defined (modules start at 4000) | Handled by callers |
See response codes.
Frontend sync
web/ is maintained in a separate repo, fast-soy-admin-frontend, with no common ancestor. Upstream sync is a manual git subtree workflow — see commits prefixed chore(web): sync with fast-soy-admin-frontend@....
Screenshots

TODO
- Redis caching
- One-command Docker deploy
- CLI code generator (backend + frontend)
- Built-in Radar dashboard (requests / SQL / exceptions / audit)
-
slimclean branch - End-to-end tests
Contributing
Pull requests and issues welcome.