1. Overview
This document provides a technical and functional overview of the Notification System, which is designed to manage consumer events and deliver personalized notifications across multiple channels.
The system is composed of two main services. The Film Notification Service processes consumer lifecycle events (add, modify, delete), enriches them with film availability data, and generates film-consumer-notification events for all active channels. The Notification Service consumes these events, maintains a projection of consumers per channel, manages notification preferences, and ensures delivery through the styles and configurations defined for each channel.
This separation of responsibilities provides scalability, resilience, and a clear workflow from event generation to final notification delivery.
2. Architecture Overview
The architecture of the Notification System is based on an event-driven model that separates the responsibilities of event generation, enrichment, and notification delivery. The system is composed of two core services — Film Notification Service and Notification Service — which communicate asynchronously through events.

At a high level, the workflow follows this pattern:
Film Notification Service consumes consumer lifecycle events (add, modify, delete) and retrieves film availability data.
It generates events that contain consumer and film information.
These events are published into the event bus and consumed by the Notification Service.
The Notification Service maintains channel-based consumer projections, manages notification preferences, and sends notifications using the channel’s defined styles and configurations.
This design ensures scalability, modularity, and resilience by decoupling event enrichment from notification delivery.
3. Film Notification Service
3.1. Overview
This section provides a technical and functional overview of the Usheru Film Notification Service.
The service is responsible for retrieving the list of movies available in cinemas, combining this information with consumer data from active channels, and generating events of type film-consumer-notification. These events contain all the relevant details to notify users about films they might be interested in.
Functionally, the service also processes consumer lifecycle events (add, modify, and delete) to ensure notifications are always aligned with the current state of consumers across channels. By doing this, the Film Notification Service acts as the entry point of the notification system, preparing and delivering enriched events for the Notification Service, which then handles preferences, styles, and the actual delivery to the end user.
3.2. Architecture
The service connects to two databases:
Main Usheru Database – accessed via DAO to read the Outbox table and consumer data and Film Cinema wishlist data.
Local Service Database – maintains projections of channel preferences and implements the Outbox pattern for event delivery.
Key components include:
Film Notification Scheduler: Orchestrates periodic tasks through Quartz. Jobs are created conditionally, based on runtime properties and conditions, providing flexibility per environment. Configured jobs:
CinemaWishlistNotificationJob – generates
FilmCinemaWishlistConsumerNotificationEventin a paced manner.InboxJob – extracts channel preference events (
Add|Modify|Delete) and updates the local projection accordingly.OutboxJob – reads the Outbox table from
usheru_film_notification, collectsFilmCinemaWishlistConsumerNotificationEvententries, and sends them to theconsumer-notification-event-topicin Amazon SNS via the Amazon Publisher.LegacyOutboxJob – reads the Outbox table from
usheru_db, processes (Add|Modify|Delete)ConsumerEvententries, and sends them to theconsumer-event-topicin Amazon SNS via the Amazon Publisher.
Channel Preferences Event Listeners: Listens to (
Add|Modify|Delete)ChannelPreferenceEventmessages and stores them in the inbox table of theusheru_film_notificationdatabase. These projections are later used by the Scheduler to decide which notifications should be created.Amazon Publisher: Publishes all generated events to SNS in an idempotent manner, ensuring reliable delivery and avoiding duplicates.
URL Builder: Constructs image URLs and links that are embedded into notification emails.
3.3. Data Flow
3.3.1. Input
(Add|Modify|Delete)ConsumerEvent from usheru_db's Outbox.
(Add|Modify|Delete)ChannelPreferenceEvent from Notification Service.
Movie availability data from usheru_db.
3.3.2. Processing
Update channel preferences projection.
Match wishlists with currently available movies and channel preferences.
Build enriched event payloads with URLs.
3.3.3. Output
Events published to SNS, consumed later by Notification Service.
3.4. Service Layers
The Film Notification Service is structured in multiple layers, separating responsibilities between scheduling, business logic, and data access:
3.4.1. Service Layer (Jobs)
Defines the scheduled jobs orchestrated by Quartz.
CinemaWishlistNotificationJob – generates film wishlist notifications.
InboxJob – updates channel preference projections.
OutboxJob – publishes film-consumer events to SNS.
LegacyOutboxJob – handles legacy consumer events from the main Usheru database.
3.4.2. Data Access Layer
Provides abstractions for persistence and retrieval of domain entities. The service distinguishes between two domains:
3.4.2.1. Usheru Film Notification Domain (usheru_film_notification)
Uses the Repository pattern to interact with entities such as the Inbox table and the Outbox implementation for wishlist notifications.
This ensures tight integration with Spring Data and transactional consistency.
3.4.2.2. Main Usheru Domain (usheru_db)
Uses the DAO pattern to access entities such as the Outbox table for consumer events.
This keeps access explicit and decoupled, as the main database belongs to another bounded context.
This layered approach provides:
Clear separation of concerns between scheduled jobs, business logic, and data access.
Flexibility, as different persistence strategies are applied per domain (Repository vs. DAO).
Maintainability, by isolating the logic tied to each database into its appropriate layer.
3.5. Development & Build
Build, test, and deployment processes are defined in the repository.
👉 For local setup, testing, and environment configuration, refer to the project’s README.
3.6. Deployment and Operations
CI/CD: Every commit to main triggers CodePipeline, which builds the application (Java + Gradle), creates a new Docker image, and updates ECS tasks automatically.
Scalability: ECS with Fargate supports elastic scaling; more tasks can be added without changing the architecture.
.
4. Notification Service
4.1. Overview
The Notification Service is responsible for managing consumer projections and their notification preferences per channel, as well as generating and delivering notification emails.
Functionally, it:
Receives (
Add|Modify|Delete)ConsumerEventevents to create, update, or delete consumers in its local domain.Maintains and manages channel-based notification preferences, which are derived from default usheru preferences but can be updated per channel.
Exposes REST endpoints that allow updating and modifying preferences.
Periodically consumes
FilmCinemaWishlistConsumerNotificationEventmessages to generate notification emails for consumers who belong to active channels and have the corresponding preferences enabled.Generates (
Add|Modify|Delete)ChannelPreferenceEvent whenever channel preferences are modified, ensuring other services maintain consistent projections.
4.2. Architecture
The Notification Service integrates with multiple components to deliver its functionality:
Event Listeners – consume consumer lifecycle events and
FilmCinemaWishlistConsumerNotificationEvent.Preference Management – stores and applies default and channel-specific notification preferences.
Email Generator – converts FilmCinemaWishlistConsumerNotificationEvent payloads and uses Thymeleaftemplates to generate HTML emails without JavaScript.
Amazon SES Sender – dispatches the generated emails reliably to end users.
REST Endpoints – allow channels to update their preferences dynamically.
Database – maintains projections of consumers and their preferences for notification delivery.
4.3. Data Flow
4.3.1. Input
(
Add|Modify|Delete)ConsumerEvent– updates consumer records in the service.FilmCinemaWishlistConsumerNotificationEvent– provides the data required to generate wishlist notification emails.
4.3.2. Processing
Store consumer lifecycle changes.
Apply or update channel preferences.
Match consumers with wishlist notifications.
Select the appropriate translation based on consumer language.
Render the email content using Thymeleaf templates.
4.3.3. Output
(
Add|Modify|Delete)ChannelPreferenceEvent– published whenever preferences are changed via the API.Emails dispatched to consumers via Amazon SES.
4.4. Service Layer
The service layer orchestrates the business logic:
ConsumerService – manages consumer lifecycle based on incoming events.
ChannelPreferenceService – manages notification preferences at the channel level.
ConsumerChannelPreferenceService – manages notification preferences at the consumer channel level.
EmailNotificationJobService – handles the logic of consuming
FilmCinemaWishlistConsumerNotificationEventand preparing personalized notification emails.EmailSenderService – delegates email dispatch to SmtpEmailSender (Amazon SES).
4.5. Data Access Layer
The data access layer provides persistence and retrieval operations for entities managed by the service:
Repository Pattern – used for consumers and preferences stored in the service’s database.
Inbox Table – all events consumed from SQS are stored here for reliable processing and idempotency.
Outbox Pattern – ensures that (
Add|Modify|Delete)ChannelPreferenceEventmessages are reliably published to SNS whenever preferences are updated.
4.6. Resource Layer
The resource layer exposes REST APIs that allow channel operators to:
Retrieve current notification preferences.
Update or modify preferences at the channel level.
Trigger preference changes that generate (
Add|Modify|Delete)ChannelPreferenceEvent.
3.7. Development & Build
Build, test, and deployment processes are defined in the repository.
👉 For local setup, testing, and environment configuration, refer to the project’s README.
4.8. Deployment and Operations
CI/CD: Every commit to main triggers CodePipeline, which builds the application (Java + Gradle), creates a new Docker image, and updates ECS tasks automatically.
Scalability: ECS with Fargate supports elastic scaling; more tasks can be added without changing the architecture
5. Amazon SNS
The Film Notification Service relies on Amazon SNS (Simple Notification Service) as the central message distribution mechanism. Events generated or read from the Outbox tables are published to dedicated topics using the AmazonSnsPublisher implementation. This publisher ensures:
Idempotent delivery, avoiding duplicate event publication.
Structured routing of events to the correct SNS topics.
Configured topics:
consumer-event-topic – receives (
Add|Modify|Delete)ConsumerEventmessages generated by theLegacyOutboxJob.channel-preference-event-topic – receives (
Add|Modify|Delete)ChannelPreferenceEventmessages, consumed by the film notification service to maintain preference projections from notification service.consumer-notification-event-topic – receives
FilmCinemaWishlistConsumerNotificationEventmessages generated by the CinemaWishlistNotificationJob and OutboxJob.
6. Amazon SQS
Amazon SQS is used to subscribe and process messages published in the SNS topics. The service defines multiple queues linked to each event type, providing clear separation of responsibilities:
Channel Preference Queues (from channel-preference-event-topic)
add-channel-preference-event-to-film-notifications-queue
modify-channel-preference-event-to-film-notifications-queue
delete-channel-preference-event-to-film-notifications-queue
Consumer Queues (from consumer-event-topic)
add-consumer-event-to-notifications-queue
modify-consumer-event-to-notifications-queue
delete-consumer-event-to-notifications-queue
Consumer Notification Queue (from consumer-notification-event-topic)
notify-cinema-wishlist-event-to-notifications-queue
All queues are consumed using @SqsListener-based listeners. These listeners:
Process incoming messages directly from SQS.
Store every event into the inbox table of the service’s local database.
Guarantee resilience with retries and dead-letter queues configured at the SQS level.
This design allows the Notification System to keep a reliable projection of all external events, which can then be used to generate and publish new notification events.
7. Amazon SES
For email delivery, the service integrates with Amazon SES through the SmtpEmailSender implementation. This component:
Sends transactional emails containing notification content.
Uses Thymeleaf templates to generate dynamic HTML emails.
Templates are server-side rendered.
Generated HTML contains no JavaScript, ensuring security and compatibility across email clients.
Embeds image URLs and links created by the URL Builder.
Handles errors gracefully with retries and structured logging.
By leveraging Thymeleaf, the Notification Service guarantees that all notification emails are customizable, secure, and compliant with email client standards, while Amazon SES ensures reliable delivery to end users.
8. Technologies Used
Component | Technology |
Language | Java 21 |
Framework | Spring Boot 3.x |
JSON Processing | Jackson |
HTTP Client | Spring WebClient |
Validation | Bean Validation (Jakarta) |
Logging | Logback / SLF4J |
Build Tool | Gradle |
DB Support | PostgreSQL or BigQuery |
Testing | JUnit 5, Mockito |
Event Bus | Amazon SNS, Amazon SQS |
Spring profiles are used to switch between environments (dev, prod) to allow for flexible deployments and local development.