Trakr is a full-stack job application tracker. This repository is a monorepo with a React frontend, a Rails API, and deployment config for Vercel + Fly.io.
Live app: trakr-lemon.vercel.app
flowchart LR
browser[Browser]
vercel[Vercel - apps/web]
fly[Fly.io - apps/api]
pg[(Fly Postgres)]
browser --> vercel
vercel -->|"/api/* rewrite"| fly
fly --> pg
In production, the Vite app is served from Vercel. Browser requests to /api/* are rewritten to the Rails API on Fly.io, so the frontend stays same-origin. Locally, Vite proxies /api to Rails on port 3000.
apps/web— React 18, Vite 6, TypeScript, MUI 6, Redux Toolkitapps/api— Ruby on Rails 7.2 API, served by Fly.io in productiondocker-compose.yml— Local PostgreSQL for development
- Node.js 22 (see
apps/web/.nvmrc) - npm
- Ruby 3.3.11
- Bundler
- Docker Desktop
- Fly CLI (production API deploys)
No OpenSSL legacy provider or CRA workarounds are required.
Install frontend dependencies:
cd apps/web
npm installInstall backend dependencies:
cd apps/api
bundle installStart PostgreSQL and load the schema/demo data:
npm run db:setupRun both apps from the repository root:
npm run devThe frontend opens at http://localhost:8080. Vite proxies /api requests to the Rails API at http://localhost:3000 (see apps/web/vite.config.ts). Root npm scripts use scripts/with-ruby.sh to prefer Homebrew ruby@3.3 when available (Apple Silicon or Intel), or your existing PATH via rbenv/asdf. Override with TRAKR_RUBY_BIN=/path/to/ruby/bin if needed.
Procfile.dev is available if you prefer Foreman or Overmind; npm run dev uses concurrently by default.
npm run dev # Start React and Rails together
npm run dev:web # Start only the React app
npm run dev:api # Start only the Rails API
npm run db:up # Start local PostgreSQL
npm run db:setup # Start DB, load schema, and seed demo data
npm run lint:web # ESLint in apps/web
npm run typecheck:web # TypeScript check in apps/web
npm run test:web # Vitest in apps/web
npm run test:api # Rails test suite (requires Postgres)
npm run build:web # Production build of the React appGitHub Actions runs on every push and pull request to main / master:
| Job | What it runs |
|---|---|
| API tests | Rails test suite against Postgres 14 |
| Web CI | npm ci → lint → typecheck → test → build in apps/web |
Run the web checks locally:
npm run lint:web
npm run typecheck:web
npm run test:web
npm run build:webRun API tests locally (Docker Postgres on port 55432; CI uses 5432):
npm run db:up
npm run test:api:prepare
npm run test:apiUse .env.example as the source of truth.
| Variable | Purpose |
|---|---|
VITE_DEMO_MODE |
true enables demo mode (auto-login with sample data) |
VITE_GOOGLE_API_KEY |
Google Places API key for location autocomplete |
| Variable | Default (Docker) |
|---|---|
DB_HOST |
127.0.0.1 |
DB_USERNAME |
postgres |
DB_PASSWORD |
postgres |
DB_PORT |
55432 |
DEMO_MODE |
true |
DEMO_USER_EMAIL |
beetman@shrutefarms.com |
| Variable | Purpose |
|---|---|
DATABASE_URL |
Created by fly postgres attach |
RAILS_MASTER_KEY |
Rails credentials key |
SECRET_KEY_BASE |
Session signing secret |
DEMO_MODE |
true for portfolio demo |
DEMO_USER_EMAIL |
Demo user email |
Frontend (Vercel)
- Create project with Root Directory
apps/web - Framework: Vite; Build Command:
npm run build; Output Directory:dist - Set
VITE_DEMO_MODEandVITE_GOOGLE_API_KEY - Deploy —
apps/web/vercel.jsonrewrites/api/*to Fly
API (Fly.io)
- From
apps/api:fly deploy - Ensure Postgres is attached and secrets are set
- Run
fly ssh console -C "bin/rails db:seed"if seed data is needed - Confirm health check hits
/api/logged_in
Smoke test
- Open the Vercel URL — demo banner should appear when
VITE_DEMO_MODE=true - Dashboard loads sample jobs
- API calls succeed via same-origin
/apiproxy
From apps/api:
fly launch --no-deploy
fly postgres create --name trakr-db
fly postgres attach trakr-db
fly secrets set RAILS_MASTER_KEY=... SECRET_KEY_BASE=... DEMO_MODE=true DEMO_USER_EMAIL=beetman@shrutefarms.com
fly deploy
fly ssh console -C "bin/rails db:seed"The included apps/api/fly.toml assumes an app named trakr-api in the sea region. If fly launch creates a different app name, update apps/api/fly.toml and the Vercel rewrite destination in apps/web/vercel.json.
Create a Vercel project from this repository with:
- Root Directory:
apps/web - Build Command:
npm run build - Output Directory:
dist - Framework: Vite
Set Vercel environment variables for the frontend, then deploy. Vercel rewrites /api/* to the Fly API via apps/web/vercel.json, so browser requests stay same-origin.