4.4 KiB

Backend Services

Shared services provide cross-cutting functionality across the Changemaker Lite platform. These services handle external integrations, background processing, and common operations.

Service Architecture

Services are singleton instances that provide:

  • External API integrations (email, geocoding, newsletters)
  • Background job processing (email queues, geocoding queues)
  • Caching and data management
  • Infrastructure operations (Docker, tunneling)

Core Services

Email Services

Email Service (email.service.ts)

  • Nodemailer SMTP wrapper
  • Template processing with variable substitution
  • Test mode support (MailHog integration)
  • HTML email generation
  • Attachment handling

Email Queue Service (email-queue.service.ts)

  • BullMQ queue management
  • Worker process for async email sending
  • Job retry logic with exponential backoff
  • Queue monitoring and statistics
  • Batch email processing

Geocoding Services

Geocoding Service (geocoding.service.ts)

  • Multi-provider geocoding (6 providers)
    • Nominatim (OpenStreetMap)
    • ArcGIS
    • Photon
    • Mapbox
    • Google Geocoding API
    • Pelias
  • Provider fallback chain
  • Rate limiting per provider
  • Result caching
  • Batch geocoding support

Geocode Queue Service (geocode-queue.service.ts)

  • BullMQ queue for async geocoding
  • Worker process with provider rotation
  • Progress tracking
  • Error handling and retry logic
  • Batch processing optimization

Integration Services

Listmonk Client (listmonk.client.ts)

  • Typed HTTP client for Listmonk REST API
  • Basic auth integration
  • List management operations
  • Subscriber CRUD
  • Campaign operations

Listmonk Sync Service (listmonk-sync.service.ts)

  • Opt-in sync (controlled by LISTMONK_SYNC_ENABLED)
  • Participant → subscriber sync
  • Location → list management
  • User role → list assignment
  • Automated sync on campaign actions

Pangolin Client (pangolin.client.ts)

  • Typed HTTP client for Pangolin Integration API
  • API key authentication
  • Tunnel management
  • Site configuration
  • Resource operations

Infrastructure Services

Docker Service (docker.service.ts)

  • Container lifecycle management
  • Health check monitoring
  • Service status queries
  • Container operations (start, stop, restart)
  • Resource monitoring

Service List

Service Purpose Dependencies
Email Service SMTP email delivery Nodemailer
Email Queue Async email processing BullMQ, Redis
Geocoding Address → coordinates Multiple providers
Geocode Queue Async geocoding BullMQ, Redis
Listmonk Client Newsletter API Native fetch
Listmonk Sync Automated list sync Listmonk Client
Pangolin Client Tunnel API Native fetch
Docker Service Container ops Docker API

Configuration

Services are configured via environment variables in api/src/config/env.ts:

// Email
EMAIL_TEST_MODE=true          // Use MailHog instead of SMTP
SMTP_HOST=smtp.example.com
SMTP_PORT=587

// Geocoding
MAPBOX_ACCESS_TOKEN=pk_...
GOOGLE_GEOCODE_API_KEY=...

// Listmonk
LISTMONK_SYNC_ENABLED=true
LISTMONK_API_URL=http://listmonk:9000
LISTMONK_API_USER=api_user
LISTMONK_API_TOKEN=secret

// Pangolin
PANGOLIN_API_URL=https://api.bnkserve.org/v1
PANGOLIN_API_KEY=...

Usage Patterns

Email Service

import { emailService } from '../services/email.service';

await emailService.sendEmail({
  to: 'user@example.com',
  subject: 'Welcome',
  html: '<p>Welcome to our platform</p>',
});

Email Queue

import { emailQueueService } from '../services/email-queue.service';

await emailQueueService.addEmailJob({
  to: 'user@example.com',
  subject: 'Campaign Update',
  template: 'campaign-email',
  variables: { campaignName: 'Save the Parks' },
});

Geocoding Service

import { geocodingService } from '../services/geocoding.service';

const result = await geocodingService.geocode({
  address: '123 Main St, Toronto, ON',
  provider: 'nominatim',
});

if (result.success) {
  console.log(result.coordinates); // { lat: 43.65, lng: -79.38 }
}