Skip to main content

Notifications

Overview (C4 Component)

Black-box description of components

ComponentResponsibility (why does it exist?)Provided interface(s)Consumed interface(s)
AsyncConfigDeclares the notificationExecutor bean (fixed-size ThreadPoolTaskExecutor) used for non-blocking Web-Socket pushes.Spring @Configuration
notificationExecutorExecutes long-running or blocking tasks (WS broadcasts, e-mail) outside HTTP threads.Executor bean— (created by AsyncConfig)
MailConfigCreates and wires JavaMailSender, SpringTemplateEngine and a ClassLoaderTemplateResolver for HTML templates under templates/email/.Spring @ConfigurationSMTP host/port/credentials in spring.mail.* properties
JavaMailSenderLow–level SMTP client that actually sends the MIME messages.JavaMailSenderSMTP server
SpringTemplateEngineRenders Thymeleaf email templates with dynamic context.SpringTemplateEngine
WebSocketConfigRegisters STOMP endpoints (/ws, SockJS fallback) and the in-memory SimpleBroker (/topic/**).Spring WebSocketMessageBrokerConfigurerWebSocketSecurityConfig
Spring SimpleBrokerIn-memory message broker that multicasts frames published to /topic/** to connected clients.STOMP broker
WebSocketSecurityConfigAdds the JWT handshake interceptor, security context propagation and an (optional) authorization manager for WS frames.WebSocketMessageBrokerConfigurer beans (ChannelInterceptor, AuthorizationChannelInterceptor)JwtAuthentificationService, Spring Security context
DomainEventPublisherUtility wrapper around Spring ApplicationEventPublisher used by all bounded-contexts to emit domain events.publish(Object)Spring event bus
NotificationServiceImplCentral domain-event listener. Decides template, recipients & content, then delegates to in-app push + e-mail.@EventListener methodsInAppNotificationService, MailService
InAppNotificationServicePersistence + delivery of notifications: saves the entity, converts to DTO, and schedules Web-Socket broadcast.pushToUser, pushToProviderNotificationRepository, NotificationMapper, NotificationMessagePublisher
NotificationRepositoryCRUD access to Notification table with convenience finders (top 20, unread-only, provider/user scope).Spring-Data JPAMySQL (via Hibernate)
NotificationMapperMapStruct mapper between Notification entity and NotificationResponse DTO.toDto (single & list)
NotificationMessagePublisherSends a DTO to /topic/users/{id} or /topic/providers/{opsCode} asynchronously via SimpMessagingTemplate.sendUserNotification, sendProviderNotification (annotated @Async)notificationExecutor, Spring SimpleBroker
MailService (MailSenderServiceImpl)Composes an HTML e-mail (Thymeleaf) and delivers it through JavaMailSender.sendHtmlMail(to, subject, template, ctx)JavaMailSender, SpringTemplateEngine
NotificationControllerREST façade: lists the last 20 notifications and marks one as read/unread.GET /v1/notifications, PATCH /v1/notifications/{id}NotificationService, CurrentUserService
NotificationServiceAuthorisation + orchestration layer for REST: filters by AuthInfo, calls repository and mapper.list(AuthInfo, unreadOnly), markRead(AuthInfo,id,flag)NotificationRepository, NotificationMapper
CurrentUserServiceSupplies AuthInfo (userId, providerOpsCode, roles) to the REST layer.authInfo()Spring Security context

Important internal interfaces

NameSignature / ProtocolNotes
Domain event contractPOJOs such as QuoteCreatedEvent, RequestForQuotationStatusChangedEvent, … published via DomainEventPublisher.publish(event)Decouples bounded-contexts. Only the event type & minimal IDs travel across modules.
NotificationServiceImpl listeners@EventListener public void on(QuoteCreatedEvent e) (same for each event)Translates a domain event into a title, message, targetUrl and NotificationContext map for e-mail.
In-app push (provider)pushToProvider(String opsCode, String title, String msg, String url)Persists a provider-scoped notification, then broadcasts over WS.
In-app push (user)pushToUser(Long userId, …)Same as above but user-scoped.
WS broadcastNotificationMessagePublisher.sendProviderNotification(opsCode, dto)convertAndSend("/topic/providers/{opsCode}", dto)Executed on notificationExecutor; each browser already subscribed receives a STOMP MESSAGE.
E-mail deliveryMailService.sendHtmlMail(to, subject, template, ctx)Renders templates/email/{template}.html with the supplied context.
REST – list`GET /v1/notifications?unreadOnly=true or false`Returns up to 20 NotificationResponse, newest first; scope (user vs provider) inferred from JWT.
REST – mark readPATCH /v1/notifications/{id} body \{ "read": true or false \}\Toggles the read flag after ownership check; returns 204 No Content.
STOMP subscription (browser)SUBSCRIBE /topic/users/{userId} or /topic/providers/{opsCode} (after /ws CONNECT)Delivers real-time JSON payloads (NotificationResponse) that the SPA shows as toasts.
JWT handshakeBrowser CONNECT frame with header Authorization: Bearer <jwt>Accepted/rejected by JwtChannelInterceptor; establishes Principal for subsequent SUBSCRIBE frames.