PrimebrickPrimebrick
  • Primebrick.dev
  • GitHub
  • Documentation
  • Services
  • Libraries
  • API Catalog
Resources
  • Landing Page
  • API Catalog
  • GitHub
PrimebrickPrimebrick

© 2026 Primebrick. MIT License.

github
Backend
Frontend
Microservices
    Agent Skills & Execution PermissionsAI Agent GovernanceBrevo Email ProviderCode Guardrails & File Operation RulesData Layer & Database ToolingDeployment & DockerEmail Services & Business LogicEmailSender MicroserviceEntity Model & DecoratorsGetting Started & Local DevelopmentGitFlow Branching StrategyGlossaryHTTP Server & Webhook EndpointNATS Messaging LayerOverviewRelease Lifecycle & Pre-commit HooksRepository Structure & Tech StackSchema Snapshot & Migration PipelineVersion Control & Release ProcessWorkflow & Planning Rules (Tic-Toc)
powered by Zudoku
Microservices

Email Services & Business Logic

Email Services & Business Logic

Relevant source files

The following files were used as context for generating this wiki page:

  • emailsender/src/services/email-service.ts
  • emailsender/src/services/service-registration.ts
  • emailsender/src/services/webhook-service.ts

The EmailSender microservice relies on three core service classes to handle the lifecycle of an email, from template rendering and provider dispatch to delivery tracking and service discovery. These services encapsulate the business logic required to transform raw NATS requests into formatted communications and maintain an audit trail in the PostgreSQL database.

EmailService: Rendering & Dispatch

The EmailService is the primary orchestrator for outgoing communications. It performs a multi-step process: fetching configuration, retrieving and interpolating templates, dispatching to the external provider, and logging the transaction.

Implementation Details

  1. Configuration Lookup: It queries emailsender.email_config to retrieve the from_email, from_name, and reply_to settings for the Brevo provider [emailsender/src/services/email-service.ts:25-33].
  2. Template Retrieval: It fetches the specific template from emailsender.email_templates based on the templateCode and languageIso provided in the request [emailsender/src/services/email-service.ts:36-45].
  3. Handlebars Rendering: The service uses handlebars to compile and execute the subject, body_html, and body_text fields using the variables object passed in the request [emailsender/src/services/email-service.ts:48-54].
  4. Provider Dispatch: It transforms the internal SendEmailRequest into a BrevoEmailRequest and invokes the BrevoClient [emailsender/src/services/email-service.ts:57-69].
  5. Audit Logging: Every attempt (success or failure) is recorded in emailsender.email_templates_communication_log with the interpolated message content and provider message IDs [emailsender/src/services/email-service.ts:72-117].

Data Flow: Send Email Request

This diagram bridges the SendEmailRequest type to the EmailService.sendEmail implementation.

Code
graph TD subgraph "NATS Space" A["SendEmailRequest"] end subgraph "EmailService Space" B["EmailService.sendEmail()"] C["Handlebars.compile()"] D["BrevoClient.sendEmail()"] end subgraph "Database Space" E[("emailsender.email_templates")] F[("emailsender.email_templates_communication_log")] end A --> B B --> E E -- "subject/body_html" --> C C -- "Interpolated Content" --> D D -- "messageId" --> F B -- "status: sent/failed" --> F

Sources: [emailsender/src/services/email-service.ts:20-128], [emailsender/src/nats/types.ts:1-20]


WebhookService: Delivery Tracking

The WebhookService handles asynchronous updates from email providers regarding the delivery status of sent messages (e.g., delivered, opened, bounced).

Delivery Status Flow

When a webhook hits the HTTP server, the WebhookService performs the following:

  1. Provider Validation: Ensures the provider is supported (currently limited to brevo) [emailsender/src/services/webhook-service.ts:19-21].
  2. Payload Extraction: Extracts the message-id and event from the provider's JSON payload [emailsender/src/services/webhook-service.ts:23-39].
  3. Status Mapping: Uses BrevoClient.mapStatus() to convert provider-specific event strings into internal system statuses [emailsender/src/services/webhook-service.ts:42].
  4. Log Update: Updates the emailsender.email_templates_communication_log table where the provider_message_id matches, updating the status and status_changed_at timestamp [emailsender/src/services/webhook-service.ts:48-53].
Code
sequenceDiagram participant B as "Brevo Webhook" participant W as "WebhookService.handleWebhook()" participant C as "BrevoClient.mapStatus()" participant DB as "PostgreSQL: email_templates_communication_log" B->>W: POST /webhook { "message-id": "...", "event": "delivered" } W->>C: mapStatus("delivered") C-->>W: "delivered" W->>DB: UPDATE ... SET status = 'delivered' WHERE provider_message_id = '...'

Sources: [emailsender/src/services/webhook-service.ts:18-57], [emailsender/src/providers/brevo.ts:60-75]


ServiceRegistration: Heartbeat & Discovery

The ServiceRegistration class ensures that the EmailSender service is visible to the rest of the microservices ecosystem by managing its entry in the central service registry.

Registration Logic

  • Upsert Pattern: On startup, register() checks public.service_registry. If the SERVICE_CODE (default: EMAILSENDER) exists, it updates the base_url and endpoints (webhook and health). Otherwise, it inserts a new record [emailsender/src/services/service-registration.ts:17-44].
  • Heartbeat Mechanism: The startHeartbeat() method initializes a setInterval (defaulting to 60 seconds) that calls updateHeartbeat(). This updates the updated_at timestamp in the registry to signal that the service is alive [emailsender/src/services/service-registration.ts:51-70].

Service Registry Schema Mapping

Registry FieldCode Source / Logic
codeprocess.env.SERVICE_CODE [emailsender/src/services/service-registration.ts:9]
base_urlprocess.env.SERVICE_BASE_URL [emailsender/src/services/service-registration.ts:10]
endpointsJSON object containing /webhook and /health [emailsender/src/services/service-registration.ts:11-14]
updated_atSet to NOW() during every heartbeat [emailsender/src/services/service-registration.ts:56]

Sources: [emailsender/src/services/service-registration.ts:1-71]


Last modified on July 13, 2026
Deployment & DockerEmailSender Microservice
On this page
  • EmailService: Rendering & Dispatch
    • Implementation Details
    • Data Flow: Send Email Request
  • WebhookService: Delivery Tracking
    • Delivery Status Flow
  • ServiceRegistration: Heartbeat & Discovery
    • Registration Logic
    • Service Registry Schema Mapping