Tenelix
All posts
Engineering

Currency lock: why we treat it as a structural invariant

Most billing systems let you change a tenant's currency in settings. Tenelix doesn't — and that's the whole point.

MO
Michael Okonji
Founder & Engineer
February 19, 2026 5 min read

Imagine a clinic that's been operating in NGN for two years. They issue thousands of invoices, collect millions in payments, and one day someone changes the currency setting from NGN to USD. What happens?

In most systems: the previous invoices are silently re-displayed in USD. The numbers look small. Nobody notices for a week. By the time finance catches it, reports across an entire fiscal quarter are corrupted.

This is the kind of bug that a settings page shouldn't be able to cause.

How Tenelix handles it

Tenelix locks the tenant's currency the moment any revenue artifact exists. Specifically:

  • The first time a Service is created in the tenant, currency is locked
  • Or the first time an Invoice is created
  • Or the first time a Payment is recorded

Once locked, the currency setting becomes read-only. The settings page shows a banner explaining why. The only way to "change" currency is via a support-assisted migration, which involves explicit reconciliation — not a dropdown.

The check is enforced at three layers

This is a recurring pattern in Tenelix: any sensitive invariant gets enforced at three layers:

  1. Route ability — the route is gated by an ability check
  2. FormRequest::authorize() — the request validates the operation is allowed
  3. AuthorizationService::authorize() — the controller / action re-checks at the data layer

For currency lock specifically, layer 3 is the structural one. Even if someone bypassed the route and the form request, the data layer refuses. The lock isn't a UI concern; it's a database concern.

Why this matters

Healthcare clinics get audited. Currency drift in financial records is the kind of thing that turns a quarterly review into a forensic investigation. The right design for systems handling money is to make drift structurally impossible, not just unlikely.

Settings pages should never silently corrupt history. We've seen too many billing systems where they do — and we built Tenelix to be the opposite end of that spectrum.

If you've ever spent a weekend manually re-denominating an entire ledger, you know exactly why this matters.

Ready when you are

Want this delivered to your team?

Quarterly engineering letter — architecture decisions, multi-tenancy patterns, and what we're shipping.