feat: consume transactional email notifications
Add contract validation, SMTP delivery results, terminal failure context, neutral development seeding, and local Docker setup. Ref: IT-1033
This commit is contained in:
@@ -1,5 +1,98 @@
|
||||
# hrynco-notification-service
|
||||
|
||||
## Documentation
|
||||
|
||||
- [ItemTracker outbox email consumer](docs/itemtracker-outbox-email-consumer.md)
|
||||
|
||||
## Development environment
|
||||
|
||||
The development Docker Compose stack runs PostgreSQL, RabbitMQ, database migrations,
|
||||
the Notification Service Web and Worker applications, Seq, and Mailpit.
|
||||
|
||||
Prerequisite: install and start Docker Desktop. Then run the installation script from
|
||||
the repository root:
|
||||
|
||||
```powershell
|
||||
.\docker\environments\install-development.cmd
|
||||
```
|
||||
|
||||
The script validates Docker and the Compose configuration, builds the application
|
||||
images, starts the complete stack in the background, and prints container status and
|
||||
the main development URLs. It can also be launched directly from File Explorer or
|
||||
from another working directory.
|
||||
|
||||
To validate the setup without building images or creating containers, run:
|
||||
|
||||
```powershell
|
||||
.\docker\environments\install-development.cmd --validate-only
|
||||
```
|
||||
|
||||
By default, the script uses the tracked `docker/environments/.env.Development` file:
|
||||
|
||||
```dotenv
|
||||
DB_NAME=notification_service
|
||||
DB_USER=postgres
|
||||
DB_PASS=postgres
|
||||
VOLUME_PREFIX=ns-dev
|
||||
RABBITMQ_USER=guest
|
||||
RABBITMQ_PASSWORD=guest
|
||||
RABBITMQ_AMQP_PORT=5672
|
||||
RABBITMQ_MANAGEMENT_PORT=15672
|
||||
WEB_PORT=5200
|
||||
DEVELOPMENT_EMAIL_SERVICE_NAME=TestService
|
||||
```
|
||||
|
||||
To use personal values, copy it to the Git-ignored
|
||||
`docker/environments/.env.local`, adjust the values, and run Docker Compose manually:
|
||||
|
||||
```powershell
|
||||
docker compose --env-file docker/environments/.env.local `
|
||||
-f docker/environments/docker-compose.yml `
|
||||
-f docker/environments/docker-compose.Development.yml `
|
||||
up --build -d
|
||||
```
|
||||
|
||||
After startup, the main development endpoints are:
|
||||
|
||||
- Notification Service admin: `http://localhost:5200/admin/channels`
|
||||
- Notification templates: `http://localhost:5200/admin/templates`
|
||||
- RabbitMQ management: `http://localhost:15672` (`guest` / `guest`)
|
||||
- Mailpit inbox: `http://localhost:8025`
|
||||
- Seq logs: `http://localhost:5342`
|
||||
- PostgreSQL: `localhost:5433`
|
||||
|
||||
During development migrations, the stack idempotently creates an active Mailpit SMTP
|
||||
channel and a neutral English `TestEmail` template for
|
||||
`DEVELOPMENT_EMAIL_SERVICE_NAME`. Existing channels and templates are never
|
||||
overwritten. Change that environment value when the publisher uses another service
|
||||
name.
|
||||
|
||||
Check container status and follow Worker logs:
|
||||
|
||||
```powershell
|
||||
docker compose --env-file docker/environments/.env.local `
|
||||
-f docker/environments/docker-compose.yml `
|
||||
-f docker/environments/docker-compose.Development.yml `
|
||||
ps
|
||||
|
||||
docker compose --env-file docker/environments/.env.local `
|
||||
-f docker/environments/docker-compose.yml `
|
||||
-f docker/environments/docker-compose.Development.yml `
|
||||
logs -f worker
|
||||
```
|
||||
|
||||
Stop the environment without deleting its database and RabbitMQ volumes:
|
||||
|
||||
```powershell
|
||||
docker compose --env-file docker/environments/.env.local `
|
||||
-f docker/environments/docker-compose.yml `
|
||||
-f docker/environments/docker-compose.Development.yml `
|
||||
down
|
||||
```
|
||||
|
||||
See the [ItemTracker consumer guide](docs/itemtracker-outbox-email-consumer.md#local-end-to-end-setup)
|
||||
for the complete end-to-end setup.
|
||||
|
||||
## Notification worker flow
|
||||
|
||||
```mermaid
|
||||
@@ -7,11 +100,15 @@ flowchart TD
|
||||
A[Worker host starts] --> B[Load config and register services]
|
||||
B --> C[Start SendEmailConsumer]
|
||||
C --> D[Receive message from notification.send-email]
|
||||
D --> E[Resolve SendEmailService]
|
||||
E --> F[Pick channel and template]
|
||||
F --> G[Render email content]
|
||||
G --> H[Send via SMTP]
|
||||
H --> I[Update usage counters]
|
||||
I --> J[Optionally publish result to reply queue]
|
||||
H -. failure .-> K[Log and rethrow]
|
||||
D --> E[Validate Notification.SendEmail.v1 metadata and payload]
|
||||
E --> F[Resolve SendEmailService]
|
||||
F --> G[Pick channel and exact-language template]
|
||||
G --> H[Validate variables and render email content]
|
||||
H --> I[Send via SMTP]
|
||||
I --> J[Update usage counters]
|
||||
J --> K[Optionally publish result to reply queue]
|
||||
K --> L[Acknowledge RabbitMQ delivery]
|
||||
I -. failure .-> M[Log and retry]
|
||||
M -->|retries exhausted| N[Publish terminal failure result]
|
||||
N --> O[Nack original delivery without requeue]
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user