PayChecker
Setup & Configuration

PayChecker Setup & Configuration

This guide covers the complete setup process for PayChecker, from local development to production deployment.

Prerequisites

Before setting up PayChecker, ensure you have the following installed:

  • Python 3.12 (specifically required)
  • Node.js 18+ (for frontend)
  • uv (Python package manager) - Install: curl -LsSf https://astral.sh/uv/install.sh | sh
  • Supabase CLI - Install: brew install supabase/tap/supabase (macOS)
  • Git 2.5+ (for worktree support)

Quick Start

1. Clone and Navigate to Repository

# Clone the repository
git clone https://bitbucket.org/natca_itc/pay_checker.git
cd pay_checker
 
# Navigate to your feature worktree (e.g., 012)
cd 012

2. Start Supabase (Local Docker Instance)

# Start local Supabase instance
supabase start
 
# This will output important connection details:
# - API URL: http://127.0.0.1:54321
# - Database URL: postgresql://postgres:postgres@127.0.0.1:54322/postgres
# - Studio URL: http://127.0.0.1:54323
# - service_role key: <key>
# - anon key: <key>

Note: Copy the service_role key - you'll need it for the .env file.

3. Run Development Setup Script

# Automated setup (installs backend and frontend dependencies)
uv run dev-setup

This script will:

  • Install Python dependencies via uv
  • Install Node.js dependencies via npm
  • Set up pre-commit hooks
  • Verify database connection

4. Configure Environment Variables

Create a .env file in the project root:

# Application Configuration
ENVIRONMENT=development
PORT=8000
LOG_LEVEL=INFO
 
# CORS Origins (comma-separated)
CORS_ORIGINS=http://localhost:5173,http://localhost:3000
 
# Supabase Configuration (Local)
SUPABASE_URL=http://127.0.0.1:54321
SUPABASE_KEY=<service_role_key_from_supabase_start>
 
# Development Only (for pull-dev-members.sh script)
# Get these from production Supabase dashboard
SUPABASE_PRODUCTION_PROJECT_REF=<your-project-ref>
SUPABASE_PRODUCTION_SERVICE_ROLE_KEY=<your-service-role-key>

Create frontend/.env.local:

# Frontend Configuration
VITE_API_URL=http://localhost:8000

5. Pull Development Data (Optional)

Load 10 real members from production for testing:

cd supabase/scripts
./pull-dev-members.sh

This creates consistent test data across all developer environments.

6. Start Backend Server

# Terminal 1: Start FastAPI server
cd pay_checker
uv run api-server
 
# Server will start at: http://localhost:8000
# Swagger docs at: http://localhost:8000/docs

7. Start Frontend Server

# Terminal 2: Start Vite dev server
cd frontend
npm run dev
 
# Frontend will start at: http://localhost:5173

8. Access the Application

Environment Configuration

Backend Environment Variables

VariableRequiredDefaultDescription
ENVIRONMENTYes-development or production
PORTNo8000Port for FastAPI server
LOG_LEVELNoINFOLogging level (DEBUG, INFO, WARNING, ERROR)
CORS_ORIGINSYes-Allowed CORS origins (comma-separated)
SUPABASE_URLYes-Supabase API URL
SUPABASE_KEYYes-Supabase service role key (admin access)
SUPABASE_PRODUCTION_PROJECT_REFNo-Production project ref (dev only)
SUPABASE_PRODUCTION_SERVICE_ROLE_KEYNo-Production service key (dev only)

Frontend Environment Variables

VariableRequiredDefaultDescription
VITE_API_URLYes-Backend API base URL

Database Setup

Local Development Database

Connection Details:

Database Migrations

Apply all migrations:

# Reset database and apply all migrations
supabase db reset
 
# Or apply migrations only (no reset)
supabase db push

Create a new migration:

# Generate migration from schema changes
supabase db diff -f <migration_name>
 
# Or create blank migration
supabase migration new <migration_name>

View migration status:

# List all migrations and their status
supabase migration list

Database Schema Structure

PayChecker uses a two-schema architecture:

public schema (Platform - READ-ONLY):

-- Managed by platform team
public.members
public.facilities
public.positions
public.regions
public.grants

pay schema (PayChecker - READ-WRITE):

-- Managed by PayChecker team
pay.pay_periods
pay.les_pay_periods
pay.les_earnings
pay.les_deductions
pay.les_paid_by_govt
pay.les_leave_balances
pay.les_remarks
pay.shifts
pay.cic_time
pay.ojti_time
pay.tos_tnw

Seed Data

Load seed data (regions, facilities):

psql postgresql://postgres:postgres@127.0.0.1:54322/postgres < supabase/seed.sql

Development Workflow

Git Worktree Setup

PayChecker uses git worktrees for parallel feature development:

# List all worktrees
git worktree list
 
# Create a new worktree for feature 013
git worktree add ../013 -b feature/013
 
# Navigate to new worktree
cd ../013
 
# Remove worktree when done
git worktree remove ../013

Benefits:

  • Work on multiple features simultaneously
  • No branch switching required
  • Independent working directories

Pre-commit Hooks

Pre-commit hooks automatically run on every commit:

Installed hooks:

  • Ruff Format (auto-format Python code)
  • Ruff Lint (code quality checks)
  • MyPy (type checking)
  • Branch Protection (blocks commits to main)

Manual pre-commit run:

# Run on all files
uv run pre-commit run --all-files
 
# Run on specific files
uv run pre-commit run --files pay_checker/api/main.py

Skip hooks (use sparingly):

git commit --no-verify -m "message"

Development Scripts

Available scripts (defined in pyproject.toml):

ScriptCommandDescription
parse-lesuv run parse-lesCLI for parsing LES PDFs
debug-vieweruv run debug-viewerDebug viewer for parsed data
api-serveruv run api-serverStart FastAPI server
frontend-serveruv run frontend-serverStart frontend dev server
dev-setupuv run dev-setupAutomated development setup

Testing

Run backend tests:

# Run all tests with coverage
uv run pytest
 
# Run specific test file
uv run pytest tests/api/test_shifts.py
 
# Run with verbose output
uv run pytest -v
 
# Run with coverage report
uv run pytest --cov=pay_checker --cov-report=html

Coverage requirements:

  • Minimum 90% code coverage required
  • 100% coverage for pay calculation functions
  • Coverage enforced by CI and pre-commit hooks

Run frontend tests:

cd frontend
 
# Run Vitest unit tests
npm run test
 
# Run Playwright e2e tests
npm run test:e2e
 
# Run Playwright with UI
npm run test:e2e:ui

Development Mode Authentication

In development mode, authentication is bypassed using a header:

# Test API with development auth
curl -H "X-Dev-Member-Number: 35973" http://localhost:8000/api/v1/shifts

Test user:

Production Deployment

Prerequisites

  • Railway account (for backend)
  • Vercel account (for frontend)
  • Supabase Cloud project (for database)
  • Auth0 tenant (for authentication)

Backend Deployment (Railway)

1. Create Railway project:

# Install Railway CLI
npm i -g @railway/cli
 
# Login to Railway
railway login
 
# Link project
railway link

2. Configure environment variables in Railway dashboard:

ENVIRONMENT=production
PORT=8000
LOG_LEVEL=INFO
CORS_ORIGINS=https://your-frontend-domain.vercel.app
SUPABASE_URL=https://your-project.supabase.co
SUPABASE_KEY=<service_role_key>

3. Deploy:

# Commit changes
git add .
git commit -m "Deploy to production"
git push origin main
 
# Railway auto-deploys on push

4. Verify deployment:

Frontend Deployment (Vercel)

1. Connect to Vercel:

# Install Vercel CLI
npm i -g vercel
 
# Login to Vercel
vercel login
 
# Link project
vercel link

2. Configure environment variables in Vercel dashboard:

VITE_API_URL=https://your-backend.railway.app

3. Deploy:

# Commit changes
git add .
git commit -m "Deploy frontend"
git push origin main
 
# Vercel auto-deploys on push

4. Verify deployment:

Database Migration (Production)

Apply migrations to production:

# Link to production Supabase project
supabase link --project-ref <production-project-ref>
 
# Push migrations
supabase db push

⚠️ Warning: Always test migrations locally before pushing to production.

Post-Deployment Verification

Backend checklist:

  • Health check endpoint returns 200
  • API documentation loads
  • Database connection successful
  • CORS configured correctly
  • Environment variables set

Frontend checklist:

  • Application loads without errors
  • API requests successful
  • Authentication working
  • Assets loading from CDN
  • No console errors

Troubleshooting

Common Issues

Issue: Supabase won't start

# Check Docker is running
docker ps
 
# Stop and remove containers
supabase stop --no-backup
 
# Restart Supabase
supabase start

Issue: Database connection refused

# Verify Supabase is running
supabase status
 
# Check connection string
echo $SUPABASE_URL
 
# Test connection
psql postgresql://postgres:postgres@127.0.0.1:54322/postgres

Issue: Frontend can't connect to backend

# Check CORS configuration in backend .env
CORS_ORIGINS=http://localhost:5173
 
# Verify backend is running
curl http://localhost:8000/health
 
# Check frontend .env.local
cat frontend/.env.local

Issue: Pre-commit hooks failing

# Run manually to see errors
uv run pre-commit run --all-files
 
# Update hooks
uv run pre-commit autoupdate
 
# Clear cache
uv run pre-commit clean

Issue: Tests failing

# Clear pytest cache
rm -rf .pytest_cache
 
# Reinstall dependencies
uv sync --all-extras
 
# Run tests with verbose output
uv run pytest -v

Issue: Migration failed

# View migration history
supabase migration list
 
# Reset database (⚠️ destroys all data)
supabase db reset
 
# Or rollback specific migration
supabase migration repair <timestamp>

Configuration Files Reference

pyproject.toml

Defines Python dependencies and project metadata:

[project]
name = "pay_checker"
version = "0.2.0"
requires-python = ">=3.12"
 
[project.dependencies]
fastapi = ">=0.115"
pydantic = ">=2.0"
pdfplumber = ">=0.11"
supabase = ">=2.0"
# ... more dependencies
 
[tool.ruff]
line-length = 120
target-version = "py312"
 
[tool.mypy]
strict = true

railway.toml

Defines Railway deployment configuration:

[build]
builder = "RAILPACK"
 
[deploy]
startCommand = "uvicorn pay_checker.api.main:app --host 0.0.0.0 --port $PORT"
healthcheckPath = "/health"
healthcheckTimeout = 30
restartPolicyType = "ON_FAILURE"
restartPolicyMaxRetries = 10

vercel.json

Defines Vercel deployment configuration:

{
  "rewrites": [
    { "source": "/(.*)", "destination": "/index.html" }
  ],
  "headers": [
    {
      "source": "/assets/(.*)",
      "headers": [
        {
          "key": "Cache-Control",
          "value": "public, max-age=31536000, immutable"
        }
      ]
    }
  ]
}

.pre-commit-config.yaml

Defines pre-commit hook configuration:

repos:
  - repo: local
    hooks:
      - id: ruff-format
        name: Ruff Format
        entry: uv run ruff format
        language: system
        types: [python]
 
      - id: ruff-lint
        name: Ruff Lint
        entry: uv run ruff check --fix
        language: system
        types: [python]
 
      - id: mypy
        name: MyPy Type Check
        entry: uv run mypy
        language: system
        types: [python]

Related Documentation


For production deployment support, contact Luke Garner at luke.garner@natca.net. For local development issues, check the troubleshooting section above.