Skip to content

currency: no exchange-rate / home-currency conversion — dynamic multi-currency amounts cannot be reconciled or aggregated across currencies #8345

Description

@os-zhuang

Status

Maintainer decision (2026-08-13): scheduled for v18.

Context

Surfaced while scoping a solution for an overseas port/terminal customer (2026-08): billing / reconciliation / invoicing must run in multiple currencies, with consolidated reporting in one home currency.

What the platform has today

  • currency field type with currencyConfigcurrencyMode: 'dynamic' (per-record currency) or 'fixed', defaultCurrency, precision (packages/spec/src/data/field.zod.ts).
  • ISO 4217 fraction-digit consistency validation at publish time (packages/spec/src/data/currency-fraction-digits.ts — JPY 0, KWD 3, CLDR 48.0 snapshot).
  • Tenant default currency in Localization settings (packages/services/service-settings/src/manifests/localization.manifest.ts, valueDomain: 'iso_4217_currency').
  • Analytics currency labeling resolution chain (ADR-0053): measure currency → field currencyConfig.defaultCurrencyctx.currency (packages/services/service-analytics/src/analytics-service.ts).

What is missing

  • No exchange-rate table / object, no dated-rate history.
  • No conversion engine: formula / summary roll-ups and analytics aggregations over a dynamic-currency field combine nominal values as if they were one currency — a sum across USD + EUR rows is numerically meaningless.
  • No "record currency + home-currency shadow amount" projection (Salesforce ACM-style) for consolidated reporting.

Grep evidence: exchange rate / fx_rate / currency_conversion have zero implementation hits under packages/. The one prose mention ("Money with exchange rates", content/docs/protocol/objectql/index.mdx) does not match the shipped field.zod.ts behavior and reads as a doc leftover.

Possible scope sketch (for discussion)

  1. M1sys_exchange_rate platform object (base currency, quote currency, rate, effective date) + settings for the org home currency (already exists in Localization).
  2. M2 — CEL stdlib conversion function(s) (e.g. convertCurrency(amount, from, to, date?)) usable in formula fields.
  3. M3 — opt-in converted projection for summary roll-ups and analytics measures over dynamic currency fields (aggregate in home currency; keep per-currency breakdown available).
  4. Guard rails: refuse (or warn on) cross-currency sum/avg over a dynamic currency field when no conversion is configured — today it fails silently into wrong numbers.

Workaround today

App-level customization: model an exchange-rate object, snapshot the rate onto each billing record via hook, and compute home-currency amounts with formula. Works, but every implementation reinvents it and the naive-aggregation foot-gun above remains for anyone who doesn't.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions