Hatchback Project Skill
This project was generated with Hatchback — a production-ready FastAPI boilerplate with SQLAlchemy 2, Alembic migrations, JWT auth, multi-tenancy, and Docker support.
Architecture Overview
The project follows a clean architecture pattern with four distinct layers:
app/ ├── models/ # SQLAlchemy ORM models (DB layer) ├── repositories/ # Data access — wraps queries, extends BaseRepository ├── services/ # Business logic — orchestrates repositories ├── routes/ # HTTP endpoints — thin controllers, delegates to services ├── schemas/ # Pydantic v2 request/response schemas ├── config/ # Database connection, rate limiter, settings ├── dependencies.py # FastAPI dependency injection (auth, services)
Data flow: Route → Service → Repository → Model
Key Conventions
- •Resource naming: always
snake_case(e.g.blog_post). The CLI and templates derivePascalCaseclass names automatically (BlogPost). - •Primary keys: UUID columns via
sqlalchemy.dialects.postgresql.UUID(as_uuid=True). - •Schemas: use Pydantic v2 (
model_dump(), not.dict()). Every resource should haveCreate,Update, andResponseschemas inapp/schemas/<resource>.py. - •Repositories extend
app/repositories/base.py(BaseRepository) which providesget_all,get_by_id,create,update,delete. - •Routes use FastAPI
Depends()for DB sessions and service injection. - •Registering new resources: imports must be added to:
- •
app/models/__init__.py - •
app/routes/__init__.py(add torouterslist) - •
app/services/__init__.py(add to__all__) - •
app/repositories/__init__.py(add to__all__)
- •
Hatchback CLI Commands
Run these from the project root (where requirements.txt lives).
hbk is a shorthand alias — hbk make product is equivalent to hatchback make product.
| Command | Description |
|---|---|
hatchback make <resource> | Scaffold model, schema, repo, service, route, and test for a new resource |
hatchback remove <resource> | Remove a scaffolded resource and clean up all imports |
hatchback migrate create -m "message" | Create a new Alembic migration |
hatchback migrate apply | Apply pending migrations |
hatchback run | Start Uvicorn dev server with hot-reload |
hatchback seed | Seed database with default tenant and admin user |
hatchback test | Run pytest test suite |
hatchback inspect --url <db_url> | Reflect an existing DB and generate SQLAlchemy models |
hatchback upgrade | Sync latest skills and infrastructure files into an existing project |
Scaffolding a new resource
hatchback make product
This creates:
- •
app/models/product.py— SQLAlchemy model - •
app/schemas/product.py— Pydantic schemas (Create, Update, Response) - •
app/repositories/product.py— Repository extending BaseRepository - •
app/services/product.py— Service with CRUD methods - •
app/routes/product.py— Full REST router (GET, POST, PUT, DELETE) - •
tests/test_products.py— Pytest stubs
It also auto-updates the __init__.py files in models, routes, services, and repositories.
Removing a resource
hatchback remove product # asks for confirmation hatchback remove product --force # skips confirmation
This deletes all 6 files created by make and removes the corresponding imports
from all __init__.py files.
Database & Migrations
- •Engine: PostgreSQL via
psycopg2-binary - •ORM: SQLAlchemy 2 with synchronous sessions
- •Config:
app/config/database.pyreads from.env(see.env.example) - •Migrations: Alembic, configured in
alembic.iniandalembic/
After modifying a model, always run:
hatchback migrate create -m "describe change" hatchback migrate apply
Authentication & Multi-tenancy
- •JWT tokens via
python-jose[cryptography] - •Password hashing via
passlib[bcrypt] - •Multi-tenant: every user belongs to a
Tenant; tokens includetenant_id - •Auth dependencies in
app/dependencies.py:- •
get_current_user— validates JWT, returns user - •
get_current_active_user— checks user status is "active" - •
RoleChecker(["admin"])— role-based access control
- •
Testing
- •Framework:
pytestwithhttpx(AsyncClientorTestClient) - •Config:
tests/conftest.pysets up test DB session and fixtures - •Run:
hatchback test
Environment Variables
See .env.example for required vars:
- •
DATABASE_USERNAME,DATABASE_PASSWORD,DATABASE_HOSTNAME,DATABASE_PORT,DATABASE_NAME - •
SECRET_KEY— JWT signing key (auto-generated onhatchback init) - •
MAILERSEND_API_KEY,MAILERSEND_FROM_EMAIL,MAILERSEND_FROM_NAME
Docker
- •
Dockerfile— Python slim image, installs requirements, runs Uvicorn - •
docker-compose.yml— App + PostgreSQL service - •Start DB only:
docker-compose up -d db