Skip to main content

Development Workflow

Task Runner (Justfile)

A root-level Justfile provides a single entry point for all workflows. Run just --list to see all available recipes.

Services

just up               # Start all services (db, server, mobile)
just down # Stop all services
just server # Start Django server (with db only)
just mobile # Start Expo / Metro bundler only
just logs [service] # Tail logs (optionally for a specific service)
just build # Rebuild Docker images

Testing

just test             # Run all tests (server + mobile)
just test-server # Server tests (supports args: just test-server -k "test_auth")
just test-mobile # Mobile tests only
just check # Full lint + type-check + tests

Linting

just lint             # ESLint on mobile client
just type-check # TypeScript type-check on mobile client

Database

just migrate          # Run Django migrations (supports args: just migrate users)
just makemigrations # Create Django migrations
just seed # Seed default categories
just db-generate # Generate Drizzle ORM migrations for mobile
just manage <cmd> # Django manage.py passthrough
just reset-db # Drop db volume, re-migrate, re-seed

Shell Access

just shell-server     # Bash shell in server container
just shell-mobile # Shell in mobile container

Documentation

just docs-dev         # Start docs dev server (localhost:3000)
just docs-build # Build docs for production
just docs-serve # Serve production build locally
just docs-gen-api # Generate API reference from OpenAPI schema

Git Workflow

Conventional Commits

Commits are enforced by commitlint via a Husky commit-msg hook:

feat: add budget notifications
fix: correct token refresh race condition
chore: update dependencies
refactor: extract sync encryption module
test: add receipt upload tests
docs: update API reference
perf: memoize transaction list items
style: format with prettier

Rules:

  • Lowercase subject
  • Maximum 100 characters
  • No period at the end

Pre-commit Hooks

Husky runs lint-staged on pre-commit, which checks:

  • ESLint on staged .ts/.tsx files
  • TypeScript type-checking

Development Tips

  • Use just check before pushing to run the full lint + type-check + test suite
  • The mobile client's ESLint config enforces a max of 70 lines per function -- extract sub-components or hooks when functions grow
  • All API calls go through the src/api/ layer with Axios interceptors for JWT handling
  • Database changes require running pnpm db:generate in the mobile client to create Drizzle migrations