# Email Services & Business Logic

# Email Services & Business Logic

<details>
<summary>Relevant source files</summary>

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

- [emailsender/src/services/email-service.ts](emailsender/src/services/email-service.ts)
- [emailsender/src/services/service-registration.ts](emailsender/src/services/service-registration.ts)
- [emailsender/src/services/webhook-service.ts](emailsender/src/services/webhook-service.ts)

</details>



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.

```mermaid
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]]().

```mermaid
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 Field | Code Source / Logic |
| :--- | :--- |
| `code` | `process.env.SERVICE_CODE` [[emailsender/src/services/service-registration.ts:9]]() |
| `base_url` | `process.env.SERVICE_BASE_URL` [[emailsender/src/services/service-registration.ts:10]]() |
| `endpoints` | JSON object containing `/webhook` and `/health` [[emailsender/src/services/service-registration.ts:11-14]]() |
| `updated_at` | Set to `NOW()` during every heartbeat [[emailsender/src/services/service-registration.ts:56]]() |

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

---
