Skip to content

EPPA Developer Setup

EPPA is the LABIS posturography tool for clinical/research workflows. This front contains a Next.js frontend, a FastAPI calculation/auth API, Docker deployment assets, Python tests, and Playwright end-to-end tests.

Work from this directory unless a command says otherwise:

cd fronts/eppa

Do not commit real patient data, clinical payloads, secrets, production tokens, database dumps, Vaultwarden exports, PANs, CVVs, PIN blocks, or track data.

Prerequisites

  • Node.js 20.x. There is no .nvmrc; use Node 20 because the Docker image is node:20-alpine and local dependencies are tested against modern Node.
  • npm 10.x, included with current Node 20 releases.
  • Python 3.11 or newer. Python 3.12 also works for the current API/test stack.
  • Docker Engine with the Compose plugin (docker compose ...).
  • Playwright browsers, installed after npm ci.
  • Optional: PostgreSQL and MinIO via docker compose for auth/clinical-data work. The calculation API and most Playwright coverage do not require real clinical records.

Fresh Checkout Setup

cd fronts/eppa
npm ci
npx playwright install --with-deps chromium

python3 -m venv venv
source venv/bin/activate
pip install -r python/requirements.txt

For local infrastructure used by the auth and clinical-data backend:

docker compose up -d postgres minio
docker compose ps
DATABASE_URL='postgresql+psycopg://eppa:eppa_dev_pw_CHANGE_ME@127.0.0.1:5432/eppa' \
  PYTHONPATH=python python3 -m alembic -c python/alembic.ini upgrade head

The default Postgres and MinIO credentials in docker-compose.yml are development-only placeholders. Replace them for any shared or production host.

Local Development

Run the API and frontend in separate terminals.

Terminal 1, FastAPI on host port 8100:

source venv/bin/activate
API_PORT=8100 \
CORS_ALLOW_ORIGINS=http://localhost:9002 \
PYTHONPATH=python \
python3 python/api.py

Terminal 2, Next.js on host port 9002:

NEXT_PUBLIC_API_URL=http://127.0.0.1:8100 npm run dev

Open:

  • Frontend: http://localhost:9002
  • API health: http://localhost:8100/health
  • API docs: http://localhost:8100/docs
  • MinIO console, when running: http://localhost:9001

./start-api.sh is still available for the legacy default API port 8000, but new local setup should prefer the explicit API_PORT=8100 command above so it matches Docker and Playwright.

Playwright

The default Playwright config starts its own API and production Next.js server:

npx playwright test

Defaults:

  • Frontend: WEB_PORT=9102, so PLAYWRIGHT_BASE_URL defaults to http://localhost:9102.
  • API: API_PORT=8100, so PLAYWRIGHT_API_URL defaults to http://localhost:8100.
  • Python executable: PYTHON=python3.

To test against already-running local servers instead of letting Playwright start them:

PLAYWRIGHT_BASE_URL=http://localhost:9002 \
PLAYWRIGHT_API_URL=http://127.0.0.1:8100 \
npx playwright test

Useful variants:

npm run test:e2e:playwright -- playwright/e2e/login.spec.ts
npm run test:e2e:playwright:ui
npm run test:e2e:playwright:report

Other Verification

npm run typecheck
npm run test:py:coverage
PYTHONPATH=python pytest tests python/tests/auth
PYTHONPATH=python pytest tests/test_integration.py -v
node tests/js/testAnalysis.js
node tests/js/testMissingDataSemantics.js
python3 scripts/validate_matlab_fixtures.py

npm run test also runs Python tests, JavaScript analysis tests, and an Octave MATLAB-equivalence test. Use it only when Octave is installed.

npm run test:py:coverage generates coverage.xml and prints missing Python lines in the terminal. It excludes only tests that depend on real, private, or binary MATLAB validation fixtures (Base completa- CORREGIDA.xlsx and real .mat files), so CI remains reproducible without committing private data. There is currently no enforced minimum coverage threshold.

Environment Variables

Use a local .env file only for backend settings that python/auth/config.py loads, or export values in the shell before starting processes. Do not commit a populated .env.

Variable Example value Used by Notes
NEXT_PUBLIC_API_URL http://127.0.0.1:8100 Next.js build/runtime Public API base URL baked into frontend builds. Use https://eppa.firemandeveloper.com or https://eppa2.firemandeveloper.com for server builds.
NEXT_PUBLIC_AUTH_GATE_ENABLED 1 Next.js middleware/UI Enables protected-route redirects. Leave empty for legacy/dev/Playwright analysis runs.
API_PORT 8100 FastAPI, Playwright, Docker entrypoint FastAPI listens on this port inside the process. Docker maps container port 8000 to host 8100 for the legacy eppa service.
CORS_ALLOW_ORIGINS http://localhost:9002 FastAPI Comma-separated browser origins allowed to call the API.
PYTHONPATH python Python commands Required when running the API/tests from fronts/eppa.
PYTHON python3 npm scripts, Playwright Override when the interpreter is named differently.
WEB_PORT 9102 Playwright Port for the Playwright-managed Next.js server.
PLAYWRIGHT_BASE_URL http://localhost:9002 Playwright When set, Playwright assumes the frontend server already exists and skips its webServer startup.
PLAYWRIGHT_API_URL http://127.0.0.1:8100 Playwright tests API URL used by tests and health checks.
DATABASE_URL postgresql+psycopg://eppa:eppa_dev_pw_CHANGE_ME@127.0.0.1:5432/eppa FastAPI auth/data backend, Alembic Use dev placeholders locally only. Use server secrets in production.
JWT_ALGO HS256 FastAPI auth HS256 for local/dev. RS256 is supported with key paths.
JWT_SECRET dev-only-change-me-32-plus-chars FastAPI auth Required in production for stable HS256 tokens. Never commit a real value.
JWT_PRIVATE_KEY_PATH /etc/eppa/jwt-private.pem FastAPI auth Required only when JWT_ALGO=RS256.
JWT_PUBLIC_KEY_PATH /etc/eppa/jwt-public.pem FastAPI auth Required only when JWT_ALGO=RS256.
JWT_ISSUER eppa-api FastAPI auth Token issuer claim.
ACCESS_TOKEN_TTL_SECONDS 900 FastAPI auth Access-token lifetime.
REFRESH_TOKEN_TTL_SECONDS 1209600 FastAPI auth Refresh-token lifetime.
COOKIE_SECURE false locally, true in production FastAPI auth Set true behind HTTPS.
COOKIE_SAMESITE lax FastAPI auth lax, strict, or none.
COOKIE_DOMAIN .firemandeveloper.com FastAPI auth Optional. Leave unset for localhost.
LOGIN_RATE_LIMIT 10/minute FastAPI auth SlowAPI limit for login.
FORGOT_PASSWORD_RATE_LIMIT 5/hour FastAPI auth SlowAPI limit for forgot-password.
RESET_PASSWORD_RATE_LIMIT 10/hour FastAPI auth SlowAPI limit for reset-password.
PASSWORD_RESET_TTL_SECONDS 3600 FastAPI auth Password reset token lifetime.
PASSWORD_MIN_LENGTH 10 FastAPI auth Minimum practitioner password length.
FRONTEND_BASE_URL http://localhost:9002 FastAPI auth email links Public frontend URL used in reset links.
EPPA_SMTP_HOST smtp.example.test FastAPI email Optional. If unset, password-reset email content is logged by the stub backend.
EPPA_SMTP_PORT 587 FastAPI email SMTP port.
EPPA_SMTP_USER eppa-dev@example.test FastAPI email Optional SMTP username.
EPPA_SMTP_PASSWORD dev-only-change-me FastAPI email Optional SMTP password. Never commit real credentials.
EPPA_SMTP_FROM no-reply@labis.uca FastAPI email Sender address for reset emails.
EPPA_ENV dev FastAPI auth dev, test, or prod.
MINIO_ROOT_USER eppa_minio_admin Docker MinIO Dev-only value from Compose.
MINIO_ROOT_PASSWORD eppa_minio_dev_pw_CHANGE_ME Docker MinIO Dev-only value from Compose.
POSTGRES_USER eppa Docker Postgres Dev-only value from Compose.
POSTGRES_PASSWORD eppa_dev_pw_CHANGE_ME Docker Postgres Dev-only value from Compose.
POSTGRES_DB eppa Docker Postgres Dev-only value from Compose.
CYPRESS_apiUrl http://localhost:8000 legacy Cypress script Only needed for npm run test:e2e, which wraps Cypress.

JWT_SECRET_FILE appears in the eppa2 Compose service as a production placeholder. The current Python settings load JWT_SECRET, not JWT_SECRET_FILE; mount/export a real JWT_SECRET or switch to RS256 before exposing auth beyond localhost.

Docker

Build the legacy production image:

docker compose build eppa

Run it locally:

docker compose up -d eppa
docker compose ps
curl -fsS http://127.0.0.1:8100/health

Host port mapping for the legacy eppa service:

  • 127.0.0.1:9002 -> container Next.js port 3000
  • 127.0.0.1:8100 -> container FastAPI port 8000

Build-time API URL example without Compose:

docker build \
  --build-arg NEXT_PUBLIC_API_URL=https://eppa.firemandeveloper.com \
  -t eppa:local .

The container starts both processes through entrypoint.sh: FastAPI first, then next start -H 0.0.0.0 -p 3000.

Production Deployment

Production deployment is Docker + Nginx on the server. Run these commands on the server checkout, not on a developer laptop:

cd /home/luis/personal/github-repos/labis-eppa-software/fronts/eppa
git pull --ff-only

docker compose build eppa
docker compose up -d eppa
docker compose ps

curl -fsS http://127.0.0.1:8100/health
curl -sI http://127.0.0.1:9002/ | head -3

For the parallel v2 deployment:

docker compose up -d postgres minio
docker compose build eppa2
docker compose up -d eppa2
docker compose exec eppa2 sh -c 'cd /app && DATABASE_URL=$DATABASE_URL python3 -m alembic upgrade head'
curl -fsS http://127.0.0.1:8101/health

Nginx serves public HTTPS and proxies to loopback ports. The prepared v2 config lives at deploy/nginx/eppa2.firemandeveloper.com.conf; the full v2 rollout, TLS, smoke-test, and rollback sequence is in deploy/RUNBOOK-eppa2.md.

Basic-auth credentials for the public Nginx preview must be retrieved from Vaultwarden. Do not print those credentials in this README, PRs, issues, logs, or screenshots.

Project Layout

fronts/eppa/
  src/                  Next.js app, UI components, API client
  python/               FastAPI app, calculation engine, auth/data backend
  python/migrations/    Alembic migrations
  playwright/e2e/       Playwright end-to-end tests
  tests/                Python integration and fixture tests
  scripts/              Validation and test helpers
  deploy/               Deployment runbooks and Nginx config
  datos/                Example/research data used by the project
  docs/                 Product, validation, API, and testing docs

Clinical Data Safety

  • Use synthetic or explicitly approved fixture data for local tests.
  • Do not add new real patient images, clinical records, secrets, or production exports to the repository.
  • Keep local databases and MinIO buckets on 127.0.0.1 unless a deployment runbook explicitly says otherwise.
  • Before opening a PR, check git diff --stat and git diff for accidental data or secret additions.