Getting Started
IPFOS is IPF's internal operations platform. It is developed as a workspace of two repositories:
| Repo | What it is | Stack |
|---|---|---|
os-backend/ | Microservices monorepo (pnpm workspaces + git submodules) | NestJS 11 / TypeScript, Spring Boot 3 / Java 21, PostgreSQL 16, RabbitMQ, Traefik, MinIO |
ipfos-web/ | The web application | TanStack Start, React 19, Tailwind CSS v4 |
Prerequisites
- Docker with Docker Compose
- Node.js 22 and pnpm 10 (
corepack enablegives you the right pnpm) - Java 21 and Maven — only if you work on the auth service outside Docker
:::caution Java version matters The auth service tests fail on newer JDKs (e.g. Homebrew JDK 26) due to a ByteBuddy incompatibility. Use JDK 21 for local Maven builds and tests. :::
1. Clone
The backend uses git submodules for its services:
git clone --recurse-submodules <os-backend-repo-url>
git clone <ipfos-web-repo-url>
Note: os-hr-service and os-tasks-service are declared but empty submodules — they are planned services with no code yet. Don't be surprised by empty directories.
2. Start the backend
cd os-backend
make up # starts infra (Postgres, RabbitMQ, MinIO) + all services + Traefik
make ps # check status
make logs SERVICE=tickets-service # tail a service's logs
make down # stop everything
The root .env sets COMPOSE_FILE=compose.infra.yml:compose.yml, so plain docker compose up also works.
Once up:
| URL | What |
|---|---|
http://localhost:8080 | API gateway (Traefik) — all API traffic goes through here |
http://localhost:8080/docs | Scalar API reference served from the OpenAPI spec |
http://localhost:15672 | RabbitMQ management UI |
http://localhost:9001 | MinIO console |
Databases are seeded automatically: Flyway migrations seed roles/permissions and a bootstrap admin for the auth service (controlled by AUTH_BOOTSTRAP_ADMIN_ENABLED); a TypeORM migration seeds ticket SLA policies.
:::danger Rotate committed secrets
The repo's root .env contains real-looking Google OAuth credentials, a JWT secret, and an admin password. Treat these as compromised defaults: never reuse them outside local development, and rotate anything that reached a shared environment.
:::
3. Start the frontend
cd ipfos-web
pnpm install
cp .env.example .env
# set VITE_API_BASE_URL=http://localhost:8080 (the local gateway)
# set BETTER_AUTH_SECRET (generate: npx @better-auth/cli secret)
pnpm dev # http://localhost:3000
Sign in with the bootstrap admin credentials (from os-backend/.env) via the admin login, or with a seeded Google test identity.
4. Ports at a glance
Only Traefik publishes an API port to the host; service ports are internal to the compose network.
| Service | Internal port | Public route (via :8080) |
|---|---|---|
| os-auth-service (Spring Boot) | 8081 | /api/v1/auth, /api/v1/users, /api/v1/departments, /api/v1/projects, /api/v1/badges |
| os-meals-service (NestJS) | 8083 | /api/v1/meals |
| os-tickets-service (NestJS) | 8086 | /api/v1/tickets |
| os-integration-service (NestJS) | 8087 | /api/v1/notifications |
| Web app (dev) | 3000 | — (talks to the gateway via its own proxy layer) |
5. Which workflow do I follow?
The two repos have different, non-interchangeable development workflows — this is the most important convention in the workspace:
- Work in
os-backend/follows the Workflow Contract — start atos-backend/CLAUDE.mdandos-backend/ai/workflow-contract/spec/. Planning artifacts live underos-backend/docs/. - Work in
ipfos-web/follows the Spec-Driven Workflow — start atipfos-web/spec-driven/workflow.md. - Cross-cutting features go backend first: the backend phase produces the API contract in
os-backend/docs/design/, and the frontend spec references it. When shapes disagree,os-backend/docs/design/wins.