PrimeBrickPrimeBrick
  • Docs
  • Contact
  • MIT License
  • Documentation
  • MCP Server
  • API Catalog
  • Services
  • Libraries
PrimeBrickPrimeBrick

© 2026 PrimeBrick. MIT License. v3.11.2

github
Backend
Frontend
Microservices
    Developer Guide
      Microservices OverviewArchitectureConventionsAdding a Service
      Services
        Docs Knowledge BaseProvider Model
powered by Zudoku
Services

Provider Model

Status quo — one adapter

Today the service supports exactly one provider: brevo. The send path in email-service.ts is:

  1. Provider config — dal.find on emailsender.providers WHERE provider = 'brevo'; admins create this row via the FE (POST/PUT /api/v1/entities/provider) with api_key, api_endpoint, from_email, from_name, reply_to. Missing → explicit error ("admin must configure the Brevo provider").
  2. Client — new BrevoClient(api_key, api_endpoint ?? "https://api.brevo.com/v1") constructed inline (injectable for tests).
  3. Template — email_templates row matched on (code, language_iso) from the request; Handlebars renders subject + body with the request's params.
  4. Send — POST {endpoint}/smtp/emails, api-key header.
  5. sender_log — one row per attempt, success and failure; rendered content and template uuid are hoisted outside the try so a failed send still logs the interpolated message for forensics.

Inbound triggers

SubjectDurabilityFlow
emailsender.sendfire-and-forget pub/subsubscribeToEmailSendRequests → sendEmail(request, actorId)
webhook.emailsender.receivedJetStream WEBHOOK streamsubscribeToWebhooks — external provider callbacks routed through the webhook ingress

Request fields on the NATS contract are camelCase (templateCode, languageIso); DB columns stay snake_case — the service maps at the boundary, which is the only legal place for the translation.

Adding a second provider — the real extension point

There is no provider interface today — adding one means:

  1. a new providers/<name>.ts client (same shape as BrevoClient: (apiKey, apiEndpoint) → sendEmail(request));
  2. a provider branch in email-service.sendEmail where brevo is currently hardcoded — resolve the config row by request.provider (or a default) and construct the matching client;
  3. ProviderEntity.provider already carries the discriminator — the config table needs no schema change.

Keep the sender_log contract identical for every provider: log before returning, include rendered content on failure, never log api_key.

Last modified on October 28, 2026
Docs Knowledge Base
On this page
  • Status quo — one adapter
  • Inbound triggers
  • Adding a second provider — the real extension point