Skip to content

Development Guide

This guide covers setting up your development environment and working with the Metricis codebase.

Prerequisites

  • Node.js 18+ (for client, portal, patient-portal)
  • Python 3.11+ (for server)
  • PostgreSQL 15+ (for database)
  • Redis 5.0+ (for session storage and Celery)
  • Git (for version control)

Initial Setup

1. Clone the Repository

git clone https://github.com/lricher7329/metricis.git
cd metricis

2. Install Dependencies

Frontend Dependencies

npm install

Backend Dependencies

cd server
python -m venv .venv
source .venv/bin/activate  # On Windows: .venv\Scripts\activate
pip install -r requirements.txt

3. Database Setup

Create a PostgreSQL database:

createdb metricis

Set up environment variables in server/.env:

DATABASE_URL=postgresql+asyncpg://user:pass@localhost:5432/metricis
JWT_SECRET_KEY=$(python -c "import secrets; print(secrets.token_urlsafe(32))")
SESSION_SECRET_KEY=$(python -c "import secrets; print(secrets.token_urlsafe(32))")

Run migrations:

cd server
source .venv/bin/activate
alembic upgrade head

4. Redis Setup

Install and start Redis:

# macOS
brew install redis
brew services start redis

# Linux
sudo apt-get install redis-server
sudo systemctl start redis

Configure Redis in server/.env:

SESSION_STORAGE_BACKEND=redis
REDIS_URL=redis://localhost:6379/0

Development Servers

Start All Services

npm run dev:all

This starts: - Client: http://localhost:5173 (jsPsych assessment interface) - Portal: http://localhost:3000 (researcher admin portal) - Patient Portal: http://localhost:3001 (patient/caregiver interface) - Server: http://localhost:8000 (FastAPI backend)

Start Services Individually

# Client only
npm run dev:client

# Portal only
npm run dev:portal

# Patient Portal only
npm run dev:patient-portal

# Server only
npm run dev:server

# Client + Server (original dev command)
npm run dev

Background Workers

For reminder notifications and background tasks:

# In a separate terminal
cd server
source .venv/bin/activate

# Start Celery worker
celery -A app.celery_app worker -Q reminders -l info

# Start Celery beat (periodic tasks)
celery -A app.celery_app beat -l info

Project Structure

metricis/
├── client/          # jsPsych assessment frontend (TypeScript + Vite)
├── portal/          # Researcher admin portal (React 18)
├── patient-portal/  # Patient/caregiver portal (React 18)
├── server/          # FastAPI backend (Python 3.11+)
├── docs/            # Documentation (MkDocs)
├── e2e/             # Playwright E2E tests
└── scripts/         # Utility scripts (screenshot capture, etc.)

Common Development Tasks

Database Migrations

Create a new migration:

cd server
source .venv/bin/activate
alembic revision --autogenerate -m "description of changes"

Apply migrations:

alembic upgrade head

Rollback one migration:

alembic downgrade -1

Running Tests

# Server tests (pytest)
cd server
source .venv/bin/activate
pytest tests/ -v

# Portal tests (Vitest)
cd portal
npm run test

# Patient Portal tests (Vitest)
cd patient-portal
npm run test

# E2E tests (Playwright - requires dev servers running)
npm run test:e2e
npm run test:e2e:ui      # With Playwright UI
npm run test:e2e:headed  # With browser visible

Linting

# Client
cd client && npm run lint

# Portal
cd portal && npm run lint

# Server
cd server && ruff check app/

Building for Production

# Client
npm run build

# Portal
npm run build:portal

# Patient Portal
npm run build:patient-portal

Code Style and Conventions

Naming Conventions

Context Convention Examples
TypeScript files kebab-case simple-rt.ts, digit-span.ts
TypeScript variables/functions camelCase sessionId, createTimeline()
TypeScript interfaces/types PascalCase SessionConfig, SimpleRTSummary
TypeScript constants UPPER_SNAKE_CASE API_BASE_URL, TASK_CONFIG
Python files snake_case session_store.py
Python variables/functions snake_case session_id, get_session()
Python classes PascalCase SessionStore, REDCapService
API paths kebab-case /api/session/start
API request/response fields snake_case session_id, task_summaries

Git Workflow

  1. Create a feature branch:

    git checkout -b feature/your-feature-name
    

  2. Make your changes and commit:

    git add .
    git commit -m "feat: add new feature"
    

  3. Push and create a pull request:

    git push origin feature/your-feature-name
    

Commit Message Format

Use conventional commits:

  • feat: - New feature
  • fix: - Bug fix
  • docs: - Documentation changes
  • refactor: - Code refactoring
  • test: - Test additions or changes
  • chore: - Build process or tooling changes

Environment Variables

Required for Development

Server (.env)

# Database
DATABASE_URL=postgresql+asyncpg://localhost:5432/metricis

# Security (generate with: python -c "import secrets; print(secrets.token_urlsafe(32))")
JWT_SECRET_KEY=your-secret-key
SESSION_SECRET_KEY=your-session-secret

# Redis
SESSION_STORAGE_BACKEND=redis
REDIS_URL=redis://localhost:6379/0

# CORS
ALLOWED_ORIGINS=http://localhost:5173,http://localhost:3000,http://localhost:3001

# Rate Limiting
RATE_LIMIT_PER_MINUTE=60
AUTH_RATE_LIMIT_PER_MINUTE=10

Client (.env.local)

# API URL
VITE_API_URL=http://localhost:8000/api

# For mobile development (use your Mac's IP)
VITE_NATIVE_API_URL=http://192.168.1.xxx:8000/api

Troubleshooting

Port Already in Use

If you get "port already in use" errors:

# Find process using port 5173 (or 3000, 3001, 8000)
lsof -ti:5173

# Kill the process
kill -9 $(lsof -ti:5173)

Database Connection Issues

  1. Verify PostgreSQL is running:

    pg_isready
    

  2. Check database exists:

    psql -l | grep metricis
    

  3. Verify connection string in server/.env

Redis Connection Issues

  1. Verify Redis is running:

    redis-cli ping
    # Should return: PONG
    

  2. Check Redis URL in server/.env

Import Errors in Python

Make sure you're in the virtual environment:

cd server
source .venv/bin/activate
which python  # Should point to .venv/bin/python

Next Steps