Jon Gerton
Engineering projects
Open source · Hosted CI green

ServiceFlow API

Field-service operations are straightforward—until two dispatchers schedule the same technician at the same time.

I built ServiceFlow as a production-minded Java backend where the business rules remain correct under concurrency, authorization is explicit, and every delivery claim has executable evidence.

  • Java 21
  • Spring Boot 4.1
  • Spring Security
  • PostgreSQL
  • Flyway
  • Testcontainers
  • Docker
  • OpenAPI
  • GitHub Actions
unit & architecture tests
140
PostgreSQL integration tests
88
line coverage
95.5%
fixed high/critical findings
0

The brief

Model the operational truth, not just CRUD screens.

Dispatchers need to manage customers and technicians, qualify work by skill, assign appointments, advance jobs through a controlled lifecycle, and understand current workload. Technicians should see only their own assignments. Invalid state must fail predictably.

The subtle requirement is scheduling integrity. An application-level “check then insert” looks correct in a single request but can fail when two requests race. ServiceFlow treats PostgreSQL as the final authority for that invariant while retaining a useful API response.

Architecture

One deployable application. Deliberate internal boundaries.

A modular monolith keeps operations simple while feature packages own their API, application, domain, and persistence concerns. ArchUnit tests prevent controllers and entities from leaking across those boundaries.

authenticated request path
HTTP / JWT
Controllers
Application services
Repositories
PostgreSQL

auth · customer · technician · workorder · reporting · common

The hard part

Make double-booking impossible, even during a race.

The service first checks for an overlap so normal conflicts can name the existing work order. PostgreSQL independently guards the same rule with a half-open timestamp range, allowing adjacent appointments while rejecting true overlap.

If simultaneous requests both pass the friendly check, the database accepts one and rejects the other. The constraint violation is translated into the same stable HTTP 409 contract.

V5__prevent_technician_schedule_overlaps.sql
EXCLUDE USING gist (
  technician_id WITH =,
  tstzrange(
    scheduled_start,
    scheduled_end,
    '[)'
  ) WITH &&
)
WHERE (
  status <> 'CANCELLED'
  AND scheduled_start IS NOT NULL
  AND scheduled_end IS NOT NULL
);
Stable conflict contractHTTP 409
{
  "status": 409,
  "code": "TECHNICIAN_SCHEDULE_CONFLICT",
  "detail": "The technician is already assigned during the requested time.",
  "conflictingWorkOrderId": "40000000-...-0003"
}

Engineering outcomes

The portfolio value is in the guarantees.

01

Concurrency-safe scheduling

Application checks produce useful conflicts while a PostgreSQL exclusion constraint closes the race between simultaneous requests.

02

Security at two boundaries

JWT roles and technician ownership are enforced at HTTP and application-service boundaries, with active users revalidated from persistence.

03

Schema under source control

Six forward-only Flyway migrations define the production schema. Hibernate validates it; application startup never invents it.

04

Evidence, not assertions

Unit, architecture, HTTP, repository, concurrency, clean-copy, container, vulnerability, and secret-scan checks all run against the release.

Delivery evidence

Reproducible from a clean checkout.

  • Java 21 and Maven verification
  • Real PostgreSQL integration suite
  • Architecture boundary enforcement
  • Production-profile startup and restart
  • Non-root multi-stage container
  • OpenAPI and authenticated smoke test
  • Trivy image vulnerability scan
  • Gitleaks full-history secret scan

Inspect the implementation

Every claim links back to working code.

The repository includes the complete source, database migrations, API contract, architecture decisions, security policy, demo script, and CI workflow.

Explore jgerton/service-flow