Architecture
The Unsexy Stack is a two-service application: an async FastAPI backend and a Next.js 15 frontend, backed by PostgreSQL 16, with Clerk for authentication and Stripe for billing. It is single-tenant by default, with clean patterns to extend for B2B multi-tenancy.
The shape of the backend
Section titled “The shape of the backend”backend/ app/ api/v1/ # routers: health, users, billing, webhooks core/ # config, auth (JWKS), deps (DB + current user), security models/ # SQLAlchemy 2.0 async models (user, webhook_event) schemas/ # Pydantic v2 request/response models services/ # Stripe + business logic main.py # FastAPI app factory alembic/ # async migrations tests/ # 145 backend testsThe frontend is a standard Next.js 15 App Router project that talks to the backend over the documented API (see the API Reference).
Design choices that matter
Section titled “Design choices that matter”- Async everywhere. SQLAlchemy 2.0 async sessions,
httpx.AsyncClient, async FastAPI routes. Python on a persistent server, not a serverless function fighting cold-starts and connection-pool churn. - Dependency injection at the boundaries. Auth, the DB session, and the current user are
FastAPI
Depends. Swapping a provider (for example, your own JWT verification instead of Clerk) is a change behind one boundary, not a rewrite of your routes. - The contract is the OpenAPI spec. Every endpoint is typed with Pydantic v2, so the
openapi.jsonthat generates the API Reference is the real, enforced contract.
The hard parts (documented from the real code)
Section titled “The hard parts (documented from the real code)”- Auth — JWKS-cached Clerk verification with a thundering-herd guard.
- Billing + webhooks — idempotent, signature-verified Stripe webhooks.
- Testing — 200 tests with a real-Postgres integration lane.
- Security — a 22-item checklist mapped to OWASP ASVS L1.
- Deployment — systemd + nginx + certbot for any VPS.