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__.pyapp/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 migrate downgrade |
Rollback the last migration (use -r -2 for multiple steps, -r base for all) |
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 modelapp/schemas/product.py— Pydantic schemas (Create, Update, Response)app/repositories/product.py— Repository extending BaseRepositoryapp/services/product.py— Service with CRUD methodsapp/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 userget_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_NAMESECRET_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 Uvicorndocker-compose.yml— App + PostgreSQL service- Start DB only:
docker-compose up -d db
Converted and distributed by TomeVault — claim your Tome and manage your conversions.