# NATS Messaging Layer

# NATS Messaging Layer

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

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

- [emailsender/src/nats/client.ts](emailsender/src/nats/client.ts)
- [emailsender/src/nats/handlers.ts](emailsender/src/nats/handlers.ts)
- [emailsender/src/nats/types.ts](emailsender/src/nats/types.ts)

</details>



The **NATS Messaging Layer** serves as the primary communication backbone for the `EmailSender` microservice. It facilitates an asynchronous request/response pattern for dispatching emails and provides the infrastructure for JetStream-based persistence. The implementation leverages the `nats` library to handle high-performance messaging between microservices.

## Messaging Architecture

The `EmailSender` service operates as a consumer of messages published to specific subjects. It follows a decoupled architecture where the requester does not wait for a synchronous HTTP response but instead listens for a correlated response on a dedicated subject.

### Request/Response Flow

1.  **Subscription**: The service subscribes to `emailsender.send` [emailsender/src/nats/handlers.ts:5-12]().
2.  **Request**: An external service publishes a `SendEmailRequest` to that subject.
3.  **Processing**: The `subscribeToEmailSendRequests` function iterates over the message stream, decodes the payload, and invokes the business logic handler [emailsender/src/nats/handlers.ts:16-21]().
4.  **Response**: After processing, the service publishes a `SendEmailResponse` to a specific response subject: `emailsender.response.{requestId}` [emailsender/src/nats/handlers.ts:24-27]().

### Data Flow Diagram

The following diagram illustrates the interaction between the NATS Server, the `handlers.ts` logic, and the core `EmailService`.

**NATS Message Flow**
```mermaid
sequenceDiagram
    participant Requester as "External Service"
    participant NATS as "NATS Server"
    participant Handlers as "nats/handlers.ts"
    participant EmailService as "EmailService (Logic)"

    Handlers->>NATS: subscribe("emailsender.send")
    Requester->>NATS: publish("emailsender.send", SendEmailRequest)
    NATS->>Handlers: Delivery (Msg)
    Handlers->>EmailService: handleSendEmail(request)
    EmailService-->>Handlers: SendEmailResponse
    Handlers->>NATS: publish("emailsender.response." + requestId, SendEmailResponse)
    NATS-->>Requester: Response Delivery
```
Sources: [emailsender/src/nats/handlers.ts:5-27](), [emailsender/src/nats/types.ts:1-20]()

## Client Initialization & JetStream

The connection management is centralized in `client.ts`. It maintains singleton instances of the NATS connection and the JetStream client to ensure resource efficiency.

### Connection Management
The `getNatsConnection()` function initializes the connection using the `NATS_URL` environment variable (defaulting to `nats://127.0.0.1:4222`) [emailsender/src/nats/client.ts:9-10](). Once connected, it initializes the JetStream client via `nc.jetstream()` [emailsender/src/nats/client.ts:11]().

### Key Entities in `client.ts`
| Entity | Type | Description |
| :--- | :--- | :--- |
| `nc` | `NatsConnection` | Singleton NATS connection instance [emailsender/src/nats/client.ts:3](). |
| `js` | `JetStreamClient` | Singleton JetStream client for persistent messaging [emailsender/src/nats/client.ts:4](). |
| `getNatsConnection` | `Function` | Asynchronous getter that connects if no instance exists [emailsender/src/nats/client.ts:6-15](). |
| `getJetStream` | `Function` | Returns the JetStream client; throws if NATS is not yet connected [emailsender/src/nats/client.ts:17-22](). |

**NATS Client Initialization**
```mermaid
graph TD
    subgraph "client.ts"
        A["getNatsConnection()"] --> B{"nc exists?"}
        B -- "No" --> C["connect(process.env.NATS_URL)"]
        C --> D["nc.jetstream()"]
        D --> E["Store nc & js"]
        B -- "Yes" --> F["Return nc"]
    end
    
    subgraph "handlers.ts"
        G["subscribeToEmailSendRequests()"] --> A
    end
```
Sources: [emailsender/src/nats/client.ts:1-31](), [emailsender/src/nats/handlers.ts:8-9]()

## Message Types

The messaging layer uses strictly typed interfaces to ensure contract safety between services.

### SendEmailRequest
The input payload required to trigger an email dispatch.
*   **Path**: [emailsender/src/nats/types.ts:1-12]()
*   **Fields**:
    *   `requestId`: Unique identifier for correlation.
    *   `templateCode`: Handlebars template identifier.
    *   `languageIso`: Language code (e.g., 'en', 'it').
    *   `to`, `cc`, `bcc`: Recipient arrays.
    *   `variables`: Key-value pairs for template injection.
    *   `entityTable`/`entityId`/`entityUuid`: Optional metadata for linking the email to database records.

### SendEmailResponse
The output payload returned after processing.
*   **Path**: [emailsender/src/nats/types.ts:14-20]()
*   **Fields**:
    *   `requestId`: Correlated ID from the request.
    *   `success`: Boolean indicating if the provider accepted the request.
    *   `providerMessageId`: The ID returned by the external provider (e.g., Brevo).
    *   `error`: Error message if `success` is false.
    *   `logId`: The ID of the communication log entry in the database.

Sources: [emailsender/src/nats/types.ts:1-20]()

## Error Handling

The subscription loop in `handlers.ts` is wrapped in a `try...catch` block to prevent the subscriber from crashing on malformed messages.
1.  **Parsing Errors**: If `JSON.parse` fails, the error is logged, and the loop continues to the next message [emailsender/src/nats/handlers.ts:30-31]().
2.  **Graceful Degradation**: If an error occurs during processing, the service attempts to parse the `requestId` from the raw message data to send a failure response back to the requester [emailsender/src/nats/handlers.ts:41-50]().
3.  **Unknown Requests**: If the `requestId` cannot be determined, no response is published to the response subject [emailsender/src/nats/handlers.ts:48-50]().

Sources: [emailsender/src/nats/handlers.ts:17-52]()

---
