FastAPI + PostgreSQL API for tracking expenses with email-based authentication and JWT access/refresh tokens.
- Email signup, verification codes, login, refresh tokens
- Password reset and change password with token versioning
- Expense tracking with categories and filters
- Cursor pagination and summary endpoints
- CORS-ready for frontend integration
- FastAPI
- PostgreSQL
- SQLAlchemy + Alembic
- JWT (python-jose)
src/app.py: FastAPI applicationsrc/auth: auth routes, services, schemas, utilssrc/user: user models and servicessrc/categories: category modelssrc/expenses: expense modelssrc/db: database session and Alembictests: test suite
Create a .env file in the project root:
JWT_SECRET_KEY=change-me
DATABASE_URL=postgresql+psycopg2://user:password@localhost:5432/expense_tracker
BACKEND_CORS_ORIGINS=["http://localhost:3000"]
FRONTEND_HOST=http://localhost:3000
Notes:
DATABASE_URLis used for both sync and async engines.BACKEND_CORS_ORIGINSshould be a JSON list string.
Install dependencies (using uv):
uv sync
Run the app:
uvicorn src.app:app --reload
Create migrations:
alembic revision --autogenerate -m "init"
Run migrations:
alembic upgrade head
Auth:
POST /auth/signupPOST /auth/verify-emailPOST /auth/resend-verification-codePOST /auth/loginPOST /auth/refreshPOST /auth/request-password-resetPOST /auth/reset-passwordPOST /auth/change-password
Categories (auth required):
GET /categoriesPOST /categoriesPATCH /categories/{id}DELETE /categories/{id}
Expenses (auth required):
POST /expensesGET /expensesGET /expenses/{id}PATCH /expenses/{id}DELETE /expenses/{id}GET /expenses/summary
Health:
GET /health
pytest