Shared modules
Libraries, not processes. A service opts in by Gradle dependency. Do not put a use case here.
| Module | Public types | Use it when |
|---|---|---|
shared-database | DataSourceFactory, PostgresConfig, JpaBaseConfig | You need the standard Postgres pool |
shared-redis | IntegrationEventConsumerSupport, RedisStreamConsumerSupport | You consume a stream |
shared-events | IntegrationEventEnvelope, *EventRoutes, *EventStreams, *EventTypes | You name a fact that crosses a process |
shared-outbox | OutboxWriter, JdbcOutboxWriter, OutboxRelayEngine | You publish a fact, or you are the relay |
shared-inbox | InboxMessage, JdbcInboxMessageRepository, InboxMessageWorker | You handle a fact asynchronously |
shared-idempotency | IdempotencyFilter | A retried POST must not double-apply |
shared-communication-ports | EmailSenderPort, SmsSenderPort, OtpSenderPort | You send mail or OTP without importing the provider SDK |
shared-logging | RequestCorrelation, HttpAccessLogFilter, StructuredLog, UseCaseObservationAspect | You log a request or a use case |
shared-security | JwtAuthenticationFilter, JsonAuthenticationEntryPoint, JsonAccessDeniedHandler | The route accepts a user JWT |
shared-web | GlobalExceptionHandler | You map errors to the standard body |
shared-feign | Shared response records (UserProfileResponse, ExpenseResponse, and others) | You share a DTO shape across services |
shared-i18n | I18nMessageService, MessageKeys, SupportedLocale | You return localized copy |
application-shared.yml in shared-logging is on the classpath of every service. Override a key in the service file rather than forking the shared file for one context.
Event route constants are the contract. Adding a type means updating the producer, the consumer, and both service pages. A stringly-typed event name that is not in *EventTypes will be published and then ignored.