A full-stack budget tracking application with React frontend, FastAPI backend, and PostgreSQL database.
- Frontend: React 18 + TypeScript + Vite + Material-UI
- Backend: Python 3.12 + FastAPI
- Database: PostgreSQL 16
- Cache/Queue: Redis 7
- Containerization: Docker + Docker Compose
If you're new to Docker or setting up your development environment for the first time, follow these steps:
Download and Install:
- macOS: Download from Docker Desktop for Mac
- Windows: Download from Docker Desktop for Windows
- Linux: Follow instructions at Docker Engine for Linux
After Installation:
- Open Docker Desktop application
- Wait for it to fully start (you'll see a green "running" status)
- Docker Desktop includes Docker Compose, so you'll have everything you need
Open your terminal and run:
docker --version
docker-compose --versionYou should see version numbers for both commands.
git clone git@github.com:Code-Campfire/smores-syntax.git
cd smores-syntax-
Ask Claude Code: If you run into issues during setup, ask Claude (claude.ai/code) to help troubleshoot. Claude can help with Docker installation, configuration, and common errors.
-
Stuck or Running Older Hardware?: If you're completely stuck or running on an older computer that can't handle Docker Desktop, reach out to your team lead or admins for assistance. They can help with alternative setup options or hardware upgrades.
- Docker Desktop installed and running on your system (see "First-Time Setup" above if you haven't installed it yet)
-
Clone the repository (if not already done)
-
Start all services with Docker Compose:
docker-compose up --build
This will start:
- Frontend on http://localhost:5173
- Backend API on http://localhost:8000
- PostgreSQL database on localhost:5432
- Redis on localhost:6379
-
Access the application:
- Frontend: http://localhost:5173
- Backend API docs: http://localhost:8000/docs
- Backend health check: http://localhost:8000/health
docker-compose downTo also remove volumes (database data):
docker-compose down -vpersonal-budget-analyzer/
├── frontend/ # React + TypeScript frontend
│ ├── src/
│ ├── package.json
│ └── vite.config.ts
├── backend/ # FastAPI backend
│ ├── app/
│ ├── requirements.txt
│ └── .env.example
├── docker/ # Docker configuration
│ ├── frontend.Dockerfile
│ └── backend.Dockerfile
└── docker-compose.yml # Docker Compose orchestration
The frontend runs with hot-reload enabled. Any changes to files in frontend/src/ will automatically refresh the browser.
The backend runs with uvicorn's reload feature. Any changes to Python files will automatically restart the server.
To access the PostgreSQL database directly:
docker-compose exec db psql -U postgres -d budget_analyzerView logs for all services:
docker-compose logs -fView logs for a specific service:
docker-compose logs -f backend
docker-compose logs -f frontend
docker-compose logs -f dbOnce the backend is running, visit:
- Swagger UI: http://localhost:8000/docs
- ReDoc: http://localhost:8000/redoc
The backend exposes a simple JWT-based login flow that the frontend (or external clients) can call:
-
Create the initial superuser – required to access admin-only endpoints. After the stack is running execute:
docker-compose run --rm backend python -m app.initial_data
This command reads the
FIRST_SUPERUSER_*variables frombackend/.env(seebackend/.env.example) and creates the account if it does not already exist. -
Register a regular user – submit
POST /api/v1/auth/registerwith the JSON payload:{ "username": "luis", "email": "luis@example.com", "full_name": "Luis Estigarribia", "password": "strong-password" }The endpoint enforces unique
email/usernamecombinations and will always store new accounts as active, non‑superusers. -
Obtain a token – call
POST /api/v1/auth/loginwith form-data (application/x-www-form-urlencoded). Examplecurl:curl -X POST http://localhost:8000/api/v1/auth/login \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "username=luis@example.com&password=strong-password"
The response contains:
{ "access_token": "<JWT>", "token_type": "bearer" } -
Use the token – include
Authorization: Bearer <JWT>in subsequent requests. Useful endpoints:GET /api/v1/users/me– returns the profile tied to the current token.GET /api/v1/usersandPOST /api/v1/users– admin-only operations that require the superuser token.
Forgot password is supported via email verification. The flow uses a password reset token stored in the database and a Celery worker to send emails through Resend SMTP.
Important for local testing: Resend test mode only allows sending to the email address that owns the Resend account. Each teammate must use their own Resend account and API key, and test using their own email address. This is expected for development; production configuration will be handled later.
-
Configure env vars in your local
.env(root of repo):MAIL_FROM=onboarding@resend.dev MAIL_FROM_NAME=Smore Budget MAIL_USERNAME=resend MAIL_PASSWORD=re_XXXXXXXXXXXX # This is the Resend API KEY, you need to copy it from your Resend accountAlso set
FRONTEND_URLandPASSWORD_RESET_PATHif your frontend differs from defaults. -
Start the stack, including the Celery worker:
docker compose up --build
-
Request a reset:
curl -X POST http://localhost:8000/api/v1/auth/forgot-password \ -H "Content-Type: application/json" \ -d "{\"email\":\"your-own-resend-email@example.com\"}"
Example (must be the email tied to your Resend account):
curl -X POST http://localhost:8000/api/v1/auth/forgot-password \ -H "Content-Type: application/json" \ -d "{\"email\":\"you@your-resend-email.com\"}"
The API always returns a success message, even if the email is not registered.
-
Reset password using the token from the email:
curl -X POST http://localhost:8000/api/v1/auth/reset-password \ -H "Content-Type: application/json" \ -d "{\"token\":\"<token-from-email>\",\"new_password\":\"new-strong-password\"}"
See backend/.env.example for all available environment variables.
See frontend/.env.example for all available environment variables.
Once the application is running (see Quick Start above), test the authentication features:
- Navigate to http://localhost:5173/register
- Fill in the form:
- First Name:
John - Last Name:
Doe - Email:
john.doe@example.com - Password:
password123(min 8 chars)
- First Name:
- Click Register
- ✅ You should see a success message and be redirected to the update profile page
- Navigate to http://localhost:5173/login
- Enter credentials:
- Email:
john.doe@example.com - Password:
password123
- Email:
- Click Sign In
- ✅ You should be redirected to the update profile page
- On the profile page (http://localhost:5173/profile)
- Modify any field (e.g., Full Name or Theme)
- Click Save changes
- ✅ Changes should be saved and theme should update immediately
- Change theme to Dark and save
- Logout and login again
- ✅ Dark theme should be automatically applied
This is a basic skeleton setup. To add features:
- Add database models in
backend/app/models/ - Create API endpoints in
backend/app/api/v1/endpoints/ - Build UI components in
frontend/src/components/ - Add pages in
frontend/src/pages/ - Set up Redux store in
frontend/src/store/
Port already in use: If you see port binding errors, make sure ports 5173, 8000, 5432, and 6379 are not being used by other applications.
Database connection errors: Wait a few seconds for the database to fully initialize on first run.
Frontend can't connect to backend: Make sure the VITE_API_URL environment variable is set correctly.