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 isnode:20-alpineand 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 composefor 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, soPLAYWRIGHT_BASE_URLdefaults tohttp://localhost:9102. - API:
API_PORT=8100, soPLAYWRIGHT_API_URLdefaults tohttp://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 port3000127.0.0.1:8100-> container FastAPI port8000
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.1unless a deployment runbook explicitly says otherwise. - Before opening a PR, check
git diff --statandgit difffor accidental data or secret additions.