Zakariae Jaafari

ProjectsFlagship

ChantiePro

16 Spring Boot 3.3 services on Java 21, 6 shared libraries, 31 Flyway migrations, Kafka, Angular 18.

Overview

A personal engineering project that models a construction firm as thirteen business services plus three platform services. Each service owns a private PostgreSQL schema. Changes that other parts of the system must react to travel as Kafka domain events. An Angular 18 workspace in Nx sits on top; Prometheus, Grafana, Loki and Zipkin sit underneath.

Interface

ChantiePro login screen — construction-site management sign-in
ChantiePro registration form

Problem

A construction site behaves like a small business: materials arrive and are consumed, equipment moves between sites, crews clock in, expenses need approval, and every event has to reconcile against a project budget. Putting that in one monolith couples every change. The goal was to decompose a real domain into independently deployable services and still ship a coherent UI.

Technical solution

Requests enter a Spring Cloud Gateway that validates the JWT once and forwards the authenticated principal. Services discover each other through Eureka and load configuration from a config server. Anything another bounded context must observe — a project changing status, an expense being approved — is published to Kafka instead of being handled with a synchronous call. Data is organisation-scoped via an organizationId in the JWT, applied at the query layer. That is not a hardened multi-tenant isolation model.

Architecture

Request path and backing services
  1. 01

    Angular 18 · Nx

    NgRx Signal Store

  2. 02

    API Gateway :8080

    JWT, routing, CORS

  3. 03

    Eureka + Config

    :8761 · :8888

Business services

  • auth :8081

    Registration, login, roles

  • user :8082

    Profiles and organisations

  • referentiel :8083

    Categories, units

  • project :8084

    Projects, milestones

  • material :8085

    Stock and movements

  • equipment :8086

    Register and assignments

  • hr :8087

    Employees, attendance

  • expense :8088

    Capture and approval

  • finance :8089

    Invoices, budgets

  • notification :8090

    In-app and email

  • document :8091

    PDF, Excel, Word

  • file :8092

    MinIO uploads

  • audit :8093

    Trail and history

Kafka → notification, audit, finance · PostgreSQL 16 · Redis · MinIO · Prometheus / Grafana / Loki / Zipkin

What is in the repository

  • Thirteen business services and three platform services (gateway, Eureka, config server) on Java 21 and Spring Boot 3.3
  • Six shared libraries for DTOs, security, Kafka, audit, exceptions and web filters
  • Schema-per-service PostgreSQL 16 with Flyway migrations
  • Kafka domain events consumed by notification, audit and finance
  • Redis cache, MinIO object storage, springdoc OpenAPI
  • Angular 18 in an Nx monorepo with NgRx Signal Store
  • Prometheus, Grafana, Loki and Zipkin
  • CI: Maven tests on JDK 21 including Testcontainers/Flyway integration tests, Nx production build, Compose validation

Technical decisions

Schema per service, not a shared database
Each service owns its tables. There are no cross-service joins. That keeps deployability real; it also forces every collaboration between services to be an explicit API or an event.
Events for reactions, REST for commands
Synchronous REST stays inside a use case the caller is waiting on. Audit and notification never need to be on that path, so they subscribe.
Shared libraries instead of copy-paste
JWT filters, event envelopes and error shapes live in Maven modules. A new service inherits the platform’s conventions by declaring a dependency.