PES is a monorepo for process engineering workflows: hydraulic network editing, PSV workflows, and a shared backend API.
Core rule: engineering calculations live in Python (see AGENTS.md).
Apps (TypeScript / Next.js):
apps/webdashboard (port 3000)apps/docsdocs site (port 3001, when enabled)apps/network-editor(port 3002)apps/psvPSV workflow (port 3003)apps/design-agents(port 3004, when enabled)
Backend (Python / FastAPI):
apps/apiAPI (port 8000, OpenAPI at/docs)
This starts Postgres + API + all web apps via infra/docker-compose.yml.
- Set Postgres password (compose expects it):
cd infra
cat > .env <<'EOF'
POSTGRES_PASSWORD=change-me
EOF- Start the stack:
cd infra
docker compose up -d --build- Open:
- Dashboard: http://localhost:3000
- Network Editor: http://localhost:3002
- PSV: http://localhost:3003
- API docs: http://localhost:8000/docs
Notes:
- The API runs Alembic migrations (
alembic upgrade head) automatically on startup. - The dev compose file seeds the database from
apps/api/mock_data.jsonon first boot (only if the DB is empty).
Prereqs:
- Node.js 18+ (for Bun)
- Bun
Install + run all apps:
bun install
bun run devCommon commands:
bun run build
bun run lint
bun run check-types
bun run formatRun API + Postgres in Docker, run the frontends locally.
- Backend:
cd infra
docker compose up -d --build postgres api
docker compose logs -f api- Frontend:
bun install
bun run devThe API can run in two modes:
- Database (Postgres): normal mode
- Mock (JSON file): fallback when DB is unavailable, or forced via env
Environment variables:
DATABASE_URL: async SQLAlchemy URL (example:postgresql+asyncpg://postgres:password@localhost:5432/engsuite)USE_MOCK_DATA=true: force mock mode even if DB is availableSEED_FROM_MOCK=true: seed the DB fromapps/api/mock_data.jsonon startup (only if DB is empty)
Check what the API is using:
curl http://localhost:8000/admin/data-sourceIn Docker, migrations run on API startup. To run them manually:
cd infra
docker compose exec -w /app/apps/api api alembic upgrade headCreate a new migration:
cd infra
docker compose exec -w /app/apps/api api alembic revision --autogenerate -m "your_message"Seed the database from apps/api/mock_data.json:
curl -X POST http://localhost:8000/admin/seed-from-mockExport the current database contents back to apps/api/mock_data.json:
curl "http://localhost:8000/admin/export-mock-data?write_to_file=true"Or from inside Docker:
docker compose -f infra/docker-compose.yml exec api python /app/apps/api/scripts/export_db_to_mock.py- UI: PSV Dashboard ->
Systemtab (admin-only) - API:
GET /admin/backupreturns a.sqldump in DB mode (or a JSON export in mock mode)POST /admin/restorerestores from an uploaded.sql(DB mode) or.json(mock mode)
The root Dockerfile builds a single image that runs apps, API, and PostgreSQL via supervisord.
Build:
docker build -t process-engineering-suite .Run (Postgres included in the container):
docker run \
-p 3000:3000 \
-p 3001:3001 \
-p 3002:3002 \
-p 3003:3003 \
-p 3004:3004 \
-p 8000:8000 \
-e POSTGRES_PASSWORD="change-me" \
-e POSTGRES_USER="postgres" \
-e POSTGRES_DB="engsuite" \
-v postgres_data:/var/lib/postgresql/data \
process-engineering-suiteIf DATABASE_URL is not provided, the API derives it from POSTGRES_PASSWORD, POSTGRES_USER, and POSTGRES_DB.
- Check mode:
curl http://localhost:8000/admin/data-source - If DB mode and empty, seed:
curl -X POST http://localhost:8000/admin/seed-from-mock - If mock mode, verify
apps/api/mock_data.jsoncontains data (the API reads it on startup)
This happens when Alembic runs from the wrong working directory. In Docker, the API should run with working_dir=/app/apps/api.
apps/ # Next.js apps + FastAPI API
packages/ # Shared TypeScript packages
services/ # Python calculation engine(s)
infra/ # Docker compose + deployment helpers
docs/ # Architecture / standards documentation