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.
| Annotation | What KSP Generates |
|---|---|
@Repository | Full JDBC implementation from the interface's @Query SQL |
@ServiceImplementation | DI provider registration |
@TypeController / @Field | GraphQL resolver wiring |
@RouteController | HTTP route handler registration + DI provider |
@JobDefinition | Job executor provider and enqueue helpers |
@JobEvent | dispatch() extension that enqueues jobs and publishes to pub-sub |
@Schemas / @Schema | Schema file merging across modules |
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.
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.