Local Development
Local Development
This guide covers setting up and running the Groundtruth Platform locally for development.
Prerequisites
- Node.js 18+ (recommended: 20 LTS)
- Python 3.12+
- PostgreSQL (local instance or a Supabase project)
- npm (included with Node.js)
- Git
Optional:
- Upstash Redis account (caching and rate limiting degrade gracefully without it)
- Stripe CLI (for testing webhooks locally)
Clone and Install
1. Clone the Repository
git clone <repo-url>
cd groundtruth-platform2. Install Web App Dependencies
cd apps/web
npm install3. Install Python Engine Dependencies
cd packages/engine
python -m venv venv
source venv/bin/activate # macOS/Linux
# venv\Scripts\activate # Windows
pip install -r requirements.txtEnvironment Variables
Web App (apps/web/.env.local)
Create this file with the following variables. See docs/operations/environment-variables.md for the full reference.
# Supabase
NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key
SUPABASE_SERVICE_ROLE_KEY=your-service-role-key
# Database (Supabase provides this under Settings > Database)
DATABASE_URL=postgresql://postgres:password@db.your-project.supabase.co:5432/postgres
# Stripe (test mode keys)
STRIPE_SECRET_KEY=sk_test_...
STRIPE_WEBHOOK_SECRET=whsec_...
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_...
# Railway engine URL (local development)
RAILWAY_ENGINE_URL=http://localhost:8000
# Upstash Redis (optional -- falls back to in-memory)
UPSTASH_REDIS_REST_URL=https://your-redis.upstash.io
UPSTASH_REDIS_REST_TOKEN=your-token
# Resend (optional -- emails will log to console if missing)
RESEND_API_KEY=re_...
# Sentry (optional)
NEXT_PUBLIC_SENTRY_DSN=https://...@sentry.io/...
SENTRY_AUTH_TOKEN=sntrys_...Python Engine (packages/engine/.env)
# Database
DATABASE_URL=postgresql://postgres:password@db.your-project.supabase.co:5432/postgres
# LLM API keys
OPENAI_API_KEY=sk-...
XAI_API_KEY=xai-...
ANTHROPIC_API_KEY=sk-ant-...
GOOGLE_API_KEY=AIza...
# Sentry (optional)
SENTRY_DSN=https://...@sentry.io/...
ENVIRONMENT=developmentDatabase Setup
From the apps/web directory:
# Apply all Prisma migrations (creates tables, indexes, RLS policies)
npx prisma migrate dev
# Seed the agent roster (20 agents across 8 departments)
npx prisma db seed
# Open visual database browser (runs at http://localhost:5555)
npx prisma studioThe seed script (prisma/seed.ts) populates the AgentConfig table with the full agent roster. A separate template seeder (prisma/seed-templates.ts) creates the five system engagement templates.
Running Locally
You need two terminals -- one for the Next.js web app and one for the Python engine.
Terminal 1: Next.js Dev Server
cd apps/web
npm run devThe web app runs at http://localhost:3000.
Terminal 2: Python Engine
cd packages/engine
source venv/bin/activate
python api.pyThe engine API runs at http://localhost:8000.
Verify Both Services
# Web app health check
curl http://localhost:3000/api/health
# Engine health check
curl http://localhost:8000/healthBoth should return JSON with a status indicating the service is healthy.
Running Tests
The web app uses Vitest as its test framework. All 281 tests are in apps/web/src/__tests__/.
cd apps/web
# Watch mode (re-runs on file changes)
npm test
# Single run (CI mode)
npm test -- --run
# With coverage report
npm test -- --coverage
# Run a specific test file
npm test -- --run src/__tests__/api-keys/api-key-management.test.ts
# Run tests matching a pattern
npm test -- --run -t "should create engagement"See testing.md for detailed information on test patterns and mocking strategies.
Common Issues
RAILWAY_ENGINE_URL Not Set
If the web app cannot reach the engine, ensure RAILWAY_ENGINE_URL=http://localhost:8000 is set in apps/web/.env.local. Without it, engine-related API calls (starting runs, fetching status) will fail.
Supabase Storage Bucket Missing
File uploads require a storage bucket named engagement-attachments in your Supabase project. Create it via the Supabase dashboard:
- Go to Storage in the Supabase dashboard
- Click New bucket
- Name:
engagement-attachments - Set to Private (not public)
Redis Not Available
Redis (Upstash) is entirely optional for local development. The platform degrades gracefully:
- Caching: Falls back to no-cache (every request hits the database)
- Rate limiting: Falls back to an in-memory token bucket (resets on server restart)
No mock or local Redis instance is needed.
Prisma Client Out of Date
If you see type errors after pulling new migrations, regenerate the Prisma client:
cd apps/web
npx prisma generatePort Conflicts
- Next.js defaults to port 3000. If occupied, it auto-selects the next available port.
- The Python engine defaults to port 8000. If you change it, update
RAILWAY_ENGINE_URLaccordingly.
Stripe Webhooks in Development
To test Stripe webhooks locally, use the Stripe CLI:
stripe listen --forward-to localhost:3000/api/billing/webhookThis provides a temporary whsec_... secret to set as STRIPE_WEBHOOK_SECRET.
Related Documentation
- Environments & Dev Setup -- dev branches, Supabase branching, environment matrix
- Architecture Overview -- system design and data flow
- Testing Guide -- test framework, patterns, and mocking
- Deployment Guide -- deploying to production
- Engine Architecture -- Python engine module breakdown