Skip to content

Latest commit

 

History

616 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Project Assumptions

Microservices back-end for managing projects and their tasks, built on:

  • Domain-Driven Design.
  • Event-Driven Architecture.
  • Hexagonal Architecture.
  • Choreography and the Saga pattern for distributed transactions.
  • Outbox and inbox patterns for reliable messaging.
  • SOLID.

The front-end is FastDo.

Architecture Graph

Architecture graph

Technology Stack

Back-end:

  • Spring Boot.
  • Kotlin.
  • Gradle Kotlin DSL (a separate build for each service, joined as a composite build).
  • PostgreSQL (a separate database for each service).
  • Apache Kafka (KRaft).
  • Apache Avro with Schema Registry.
  • Redis (API gateway sessions).
  • Garage (S3-compatible storage for files).
  • JUnit.
  • Testcontainers.
  • Spring Security.
  • Spring Data JPA.
  • Spring Cloud Gateway.
  • OpenAPI (Swagger).

Authentication:

  • Identity provider: Keycloak (realm veds) owns every page that touches a credential: sign-up, sign-in, email verification, password reset, two-factor authentication and acceptance of the terms of use. The application never sees a password.
  • Pattern: BFF with Spring Security's OAuth2 client. The API gateway signs users in with the authorization code flow and PKCE and is the only component that holds tokens; the browser holds only the VEDS_SESSION cookie (HttpOnly, SameSite=Strict, Secure in production). No token reaches JavaScript.
  • Session store: Redis (Spring Session, veds:session namespace), every attribute encrypted by the gateway.
  • JWT: on the way to a service the gateway exchanges the person's token at Keycloak (token exchange, RFC 8693) for one whose only audience is that service, and every service is a stateless OAuth2 resource server verifying signature, issuer, expiry and its own audience (veds-<name>-service). A token leaked from one service opens no other.
  • State: every service is stateless: each request is authorized by the JWT alone. The only state is the gateway's session, and it lives in Redis, so gateway instances are interchangeable too.
  • Token lifecycle: access tokens live five minutes; every refresh returns a new refresh token and invalidates the old one, and concurrent requests of one session share a single refresh, across replicas too (a lock in Redis). Signing out revokes the refresh token at Keycloak.
  • Authorization: permissions are granted to roles, never to people; iam-service announces what every role grants through Kafka and each service decides from its local projection.
  • Accounts: iam-service creates the account in PostgreSQL at the first sign-in.

Core back-end:

  • The application has an exception handling mechanism (RFC 9457 problem details with message codes).
  • The application has a logging mechanism.
  • The application has separate environments for local and prod.
  • The application has a dedicated configuration file.
  • The application has RBAC with permissions per role, announced to every service through Kafka.
  • The application has Flyway database migration mechanism.
  • The application has optimistic locking with ETag and If-Match headers.
  • The application has translations (ICU MessageFormat) owned by the service that declares them.
  • And many other features that can be found in the application code.

Other:

  • Docker for development environment.
  • Detekt for static code analysis.
  • ktlint for code formatting.
  • ArchUnit for executable architecture rules.
  • Dokka for code documentation.
  • OpenTofu for Kafka topic provisioning.

Documentation

Start with Development Setup, then Architecture.

Every service and shared module has its own README with the decisions behind it, for example api-gateway, iam-service and shared-messaging-kafka.