Architecture Overview

Core/impl split, KSP code generation, key abstractions, and how the pieces fit together.

Core/Impl Split

Bosca follows a strict core/impl split architecture:

  • core-* modules define contracts: interfaces, models, and annotations. They publish to Maven so any module in any repository can depend on the contract without pulling in the implementation.
  • Implementation modules provide concrete classes: repositories backed by PostgreSQL, services with business logic, and GraphQL controllers.

An implementation module never reaches into another implementation module directly. All cross-module communication goes through core interfaces.

KSP Code Generation

All boilerplate wiring is handled by KSP (Kotlin Symbol Processing) at compile time. There is no runtime reflection.

AnnotationWhat KSP Generates
@RepositoryFull JDBC implementation from the interface's @Query SQL
@ServiceImplementationDI provider registration
@TypeController / @FieldGraphQL resolver wiring
@RouteControllerHTTP route handler registration + DI provider
@JobDefinitionJob executor provider and enqueue helpers
@JobEventdispatch() extension that enqueues jobs and publishes to pub-sub
@Schemas / @SchemaSchema file merging across modules
Generated code goes to build/generated/ksp/ and must never be committed.

Key Abstractions

Bosca uses abstracted infrastructure services. The code works against interfaces, not specific products.

CacheManager

Central registry of named caches providing the distributed (remote) cache tier. The backing store is selected at startup via configuration — implementations exist for Redis and NATS KV. Your code never interacts with the backing store directly; it works through ServiceCache and RequestCache, which delegate to CacheManager.

PubSubService

The publish-subscribe abstraction. Channels are named strings, messages are serialized to JSON. subscribe() returns a Kotlin Flow. Implementations exist for both NATS and Redis pub-sub.

kotlin

JobQueue

Durable job queue abstraction with at-least-once delivery semantics. Implementations exist for NATS JetStream and Redis. Job enqueuing is deferred until after any open database transaction commits.

Server Architecture

The platform runs as two applications:

  • bosca-server — Serves the GraphQL API over Netty (queries, mutations, subscriptions via WebSocket).
  • bosca-runner — Processes background jobs from the job queue.

Both share the same domain libraries. The server is a composition root with minimal domain logic.

Async-First

All I/O uses Kotlin suspend functions throughout the stack. JDBC blocking calls are dispatched to a virtual-thread-per-task executor (DatabaseDispatcher) so they don't block coroutine thread-pool threads.