A microservices-based architecture following principles:
- Domain-Driven Design.
- Event-Driven Architecture.
- Hexagonal Architecture.
- Separation of Concerns.
- Choreography pattern for service coordination.
- Saga pattern for distributed transactions.
- Outbox pattern for reliable event publishing.
- SOLID.
- Back-end: Spring Boot, Kotlin, Gradle Kotlin DSL (a separate build for each service).
- Database: PostgreSQL (a separate instance for each service).
- Message Broker: Apache Kafka KRaft (Zookeeper-less).
- Identity Provider: Keycloak (OAuth2 / OpenID Connect).
- API Documentation: OpenAPI (Swagger).
- Containerization: Docker / Podman.
- Authentication: Keycloak JWT + refresh tokens (HttpOnly secure cookie via BFF pattern).
- Testing: JUnit, Testcontainers.
- Static Analysis: ktlint, Detekt.
- Documentation: Dokka for code docs.
- Infrastructure as Code: Terraform for Kafka topic provisioning.
- Build and Dependency Management: Gradle with composite builds for modularization.
- Schema Management: Apache Avro with Schema Registry for versioning and compatibility.
New here? Read in this order: Development Setup to get it running, Architecture for the shape of the system, then Hexagonal Layering and Shared Modules — between them, they explain nearly every "why is this in a separate module?" question the code raises.
Getting it running
- Development Setup — running the whole system locally, from a fresh clone.
- Testing — the two test tiers and the architecture check.
How the code is organized
- Architecture — components and design principles.
- Hexagonal Layering — the dependency rule, how it is enforced, and what it cost.
- Shared Modules — the six shared libraries, what each is responsible for, and the two rules that decide when a new one is justified.
- Service Dependencies — what each service needs to build and to run.
- CQRS — where command/query separation is applied, where it is not, and why.
How services talk to each other
- Eventual Consistency — outbox, inbox and sagas: how services agree on state without a distributed transaction.
- Event Catalogue — every topic, its owner and its consumers.
- Concurrency Control — optimistic locking, ETags, saga and outbox concurrency.
Cross-cutting features
- Keycloak Configuration — realm setup, authentication flow, role management.
- Files — pre-signed uploads, a private bucket, and the two sweeps.
- Translations — key ownership, ICU, and why a missing key renders as the key.
Each service documents its own decisions — what it owns, what it deliberately does not, and the reasoning behind the parts that look surprising.
| Module | |
|---|---|
| api-gateway | Token Handler, session encryption, filter ordering |
| iam-service | users, roles, permissions, registration saga |
| mail-service | delivery, and why failure is an event |
| project-service | projects, membership, the access policy |
| task-service | tasks, the board query, local projections |
| notification-service | delivery rules, STOMP transport |
| translation-service | key ownership, ICU, the two-column rule |
| file-service | pre-signed uploads, the two sweeps |
| template-service | the reference service, and what to strip after cloning |
| shared-saga-api | saga vocabulary, framework-free |
| shared-translation | the key DSL and the ICU renderer |
| shared-web | Keycloak converters, ETag and optimistic locking |
| shared-messaging-kafka | outbox, idempotent consumption, Avro |
| shared-saga-engine | saga orchestration, compensation, watchdog |
| shared-translation-client | start-up registration of translation keys |
| shared-archunit | executable architecture rules, applied by every service |
Infrastructure directories document themselves too: contracts, infra/kafka, infra/garage.
