Skip to main content

Backend Services

The backend monorepo (os-backend/) manages each service as a git submodule under services/, orchestrated with pnpm workspaces and Docker Compose. The NestJS services share a common library, shared/os-nest-shared (exception filter, logging/response interceptors, validation pipe, Swagger setup).

os-auth-service — Spring Boot / Java 21

The identity and organization service. Besides authentication it co-hosts the user-management capability in v1: users, invitations, roles/permissions, departments and memberships, projects, and badges.

  • Port 8081 · DB os_auth (Flyway migrations V1V13, JPA validates only)
  • Layout: hexagonal — api/ (controllers, DTOs), application/, domain/{model,repository,service}, infrastructure/{persistence,messaging,integration,web} under com.ipf.os.auth.
  • Auth flows: Google Workspace sign-in (hosted-domain restricted; a Google identity alone is not enough — the user must be provisioned and ACTIVE), local email/password only for the fallback/root admin, JWT access tokens + rotating refresh tokens.
  • Messaging: RPC responder on the os.rpc direct exchange — answers auth.department.get-by-id, auth.project.get-by-id, and auth.pmo.get lookups for the tickets service.
  • Seeding: Flyway seeds the RBAC catalog; startup initializers can create a bootstrap admin and Google test identities (toggled by AUTH_BOOTSTRAP_* env vars).
  • No Swagger — its API contract lives only in the hand-written docs/design/api-spec.yml.

os-tickets-service — NestJS

The flagship domain service: tickets, participants, comments, attachments, SLA policies, an append-only action timeline, and relative tickets.

  • Port 8086 · DB os_tickets (TypeORM migrations)
  • Key domain rules (enforced server-side):
    • Statuses are forward-only: OPEN → IN_PROGRESS → CLOSED. There is no reopen — continuation happens through relative tickets (parentId/rootId, parent flagged revised).
    • Priority is derived from the due date, never accepted from the client: ≤ 4h Critical, ≤ 24h High, ≤ 3d Medium, else Normal (no due date → Normal with a 7-day SLA).
    • Ticket numbers follow T-YYYY-WW-#### from an atomic per-ISO-week counter.
    • Assignment resolves most-specific-wins: direct assignee > project (PMO + PM) > department manager; participant roles are ASSIGNEE | MANAGER | PMO | PM | OBSERVER.
  • Messaging: RPC client on os.rpc for department/project/PMO enrichment (3s timeout, degrades gracefully — a ticket still loads with owningDepartment: null); publisher on the os.events topic exchange with routing keys ticket.<eventtype>.
  • Attachments are stored in MinIO and accessed through presigned URLs (max 10 files, size caps, MIME whitelist).

os-integration-service — NestJS

The notification service. Consumes ticket events and persists in-app notifications; serves notification reads. Outbound email and Google adapters are designed but deferred.

  • Port 8087 · DB os_integration
  • Messaging: binds queue integration.notifications to os.events with routing key ticket.*, dead-letter queue included. The event contract is pinned and mirrors the publisher: ASSIGNED, PARTICIPANT_ADDED, COMMENT_ADDED, INTERNAL_NOTE_ADDED, CLOSED_NEEDS_RESPONSE, SLA_BREACHED, RELATIVE_CREATED.

os-meals-service — NestJS

Designed to own the meal library, weekly menus, and selections.

  • Port 8083 · DB os_meals
  • Status: the service is scaffolded (health endpoint, config, database wiring) but the meals domain module, entities, and migrations are not yet implemented in this repo — the data model exists only in docs/design/data-model.md. Verify against the code before relying on meals endpoints.

os-hr-service and os-tasks-service — placeholders

Both are declared submodules with no code. HR (leave, approvals, profiles) is planned at /api/v1/hr. Note the backend README's service table is partly stale — tickets live in os-tickets-service, not os-tasks-service.

Working on a NestJS service

cd os-backend/services/os-tickets-service
pnpm build # prebuild compiles shared/os-nest-shared first
pnpm start:dev # watch mode
pnpm test # jest --runInBand
pnpm typecheck
pnpm migration:generate / migration:run / migration:revert

Each Nest service serves Swagger UI at /api/v1/docs on its own port when SWAGGER_ENABLED=true — but the gateway does not route it, so hit the service port directly.