Layman manual
This manual covers day-to-day operation of the PDHC Contract Manager: starting, stopping, backing up, testing, and recovering from common failures.
The following must be installed on the host machine:
pytest, endpoint test script)localhostThe api container reads these from the Docker Compose environment block. Override via a .env file in ./app/ or by exporting before running start.sh.
JWT_SECRET_KEY — signing key for JWT tokens. Change from default before any real use.BOOTSTRAP_ADMIN_USERNAME — initial admin username (default: admin)BOOTSTRAP_ADMIN_PASSWORD — initial admin password (default: change-me)READ_RATE_LIMIT — public read rate limit (default: 100 per hour)CORS_ORIGINS — allowed CORS origins (default: *)DB_WAIT_TIMEOUT_S — seconds the API waits for PostgreSQL readiness (default: 30)From the repository root:
./start.sh
This script will:
docker compose up --build inside ./app/db — PostgreSQL on localhost:9020api — Flask API on localhost:9021web — nginx SPA on localhost:9022Ctrl+C in the terminal running start.shcd app && docker compose downcd app && docker compose down -vUse -v only when you need a clean database (e.g., after changing POSTGRES_HOST_AUTH_METHOD or the DB schema fundamentally).
With the stack running:
docker exec -t $(docker compose -f app/docker-compose.yml ps -q db) \
pg_dump -U contracts -d contracts > backup_$(date +%Y%m%d_%H%M%S).sql
cat backup_YYYYMMDD_HHMMSS.sql | docker exec -i \
$(docker compose -f app/docker-compose.yml ps -q db) \
psql -U contracts -d contracts
For a clean restore, run docker compose down -v first to drop the existing volume, then start the stack and pipe in the backup.
If start.sh fails with "address already in use":
lsof -i :9020-9022
Kill the conflicting process, or let start.sh handle it (it attempts to free ports 9020–9030 automatically).
If the API container exits with "Database not ready after waiting":
DB_WAIT_TIMEOUT_S (e.g., 60)docker compose -f app/docker-compose.yml logs dbIf the admin user is not created on startup:
BOOTSTRAP_ADMIN_USERNAME and BOOTSTRAP_ADMIN_PASSWORD are set and non-emptydocker compose down -v for a fresh startIf the DB container fails with "no pg_hba.conf entry":
POSTGRES_HOST_AUTH_METHOD: trust for local devcd app && docker compose down -v && docker compose up --buildWith the stack running:
source app/.venv/bin/activate
python app/scripts/test_endpoints.py
The script tests all 11 API endpoints (health, auth, FHIR Contract CRUD, user management) and prints pass/fail results. Output is written to ./results/<timestamp>_results/endpoint-test.json.
cd app/backend
source ../. venv/bin/activate
python -m pytest tests/ -v
Runs unit/integration tests against an in-memory SQLite database (no Docker required).
All test outputs follow the convention:
./results/<ISO-8601-UTC>_results/
For example: ./results/2026-03-23T14-30-00Z_results/endpoint-test.json