Currency ManagementConfiguration

Configuration

This page covers the environment variables, service dependencies, and setup required for the currency management features.

Batch Service Configuration

Environment Variables

VariableDescriptionExample
SUBSCRIPTION_SERVICE_URLBase URL for the subscription service APIhttp://localhost:3007
DB_HOSTPostgreSQL hostdb.example.supabase.co
DB_PORTPostgreSQL port5432
DB_USERNAMEDatabase usernamepostgres
DB_PASSWORDDatabase password—
DB_DATABASEDatabase namepostgres
DB_SCHEMADefault schemapublic

Redis Configuration

BullMQ requires a Redis instance for job queue management. Redis connection settings are defined in batch-service/src/config/redis.config.ts.

OpenExchangeRates API

The API key for OpenExchangeRates is currently configured in the batch processor. To use a different key or provider, update the FetchExchangeRates case in batch-service/src/jobs/daily-batch.processor.ts.

Service Dependencies

The currency management feature spans multiple services:

┌─────────────────┐     ┌──────────────────────┐     ┌──────────────────┐
│  batch-service   │────>│  subscription-service │<────│  reporting-service│
│  (rate sync)     │     │  (currency storage)   │     │  (analytics SQL)  │
└─────────────────┘     └──────────────────────┘     └──────────────────┘
                               │
                        ┌──────▼──────────┐
                        │  user-tenant-    │
                        │  service         │
                        │  (base currency) │
                        └─────────────────┘
ServicePortRole
batch-service—Fetches exchange rates on schedule and persists via subscription-service
subscription-service3007Stores currencies, conversion rates, and exchange rates. Manages account currency.
user-tenant-service—Stores tenant-level base_currency_code
reporting-service—Applies currency conversion CTEs in analytics SQL queries
billhive-facade4001Orchestrates currency sync to tenant, validates currency at order time, enforces currency lock on accounts

Database Schema Setup

Required Tables

subscription.currency — Tenant currency configuration:

ColumnTypeDescription
iduuidPrimary key
tenant_iduuidOwning tenant
currency_codevarchar(5)ISO currency code
base_currency_codevarchar(5)Tenant’s base currency code
conversion_ratenumericUnits of this currency per 1 base currency unit
is_base_currencybooleanWhether this is the tenant’s base currency

subscription.currency_conversions — Exchange rates from external provider:

ColumnTypeDescription
base_currencyvarcharSource currency (typically USD)
target_currencyvarcharTarget currency
exchange_ratenumericConversion rate (4-decimal precision)

user_tenant.tenant — Tenant record (relevant column):

ColumnTypeDescription
base_currency_codevarchar(5)Tenant’s base currency, synced from subscription.currency

Migration

The base_currency_code column on user_tenant.tenant is populated via migration:

-- Add column
ALTER TABLE user_tenant.tenant
  ADD COLUMN base_currency_code VARCHAR(5);
 
-- Backfill from existing currency data
UPDATE user_tenant.tenant t
SET base_currency_code = c.base_currency_code
FROM subscription.currency c
WHERE c.tenant_id = t.id AND c.is_base_currency = true;
 
-- Default for tenants without currency config
UPDATE user_tenant.tenant
SET base_currency_code = 'USD'
WHERE base_currency_code IS NULL;

Currency Enum

The PostgreSQL enum type subscription."Currency" defines the allowed currency values. When joining against varchar columns (e.g., in analytics queries), cast the enum column with ::text:

LEFT JOIN currency_rates cr ON cr.currency_code = t.currency::text

Adding a New Currency

To add support for a new currency:

  1. Add the currency code to the Currency enum in packages/enums/src/currency.enum.ts
  2. Add the corresponding PostgreSQL enum value via migration
  3. Add the currency to the targetCurrencies array in batch-service/src/flows/update-exchange-rates/exchange-rate-flow.ts
  4. Add the currency symbol mapping in the frontend currency_mapper
  5. Create the currency record for each tenant via the currency management UI or API