preferences: add currency_code field + shared currency formatting utility #52

Closed
opened 2026-04-20 10:22:02 -07:00 by pyr0ball · 0 comments
Owner

Summary

Add currency_code (ISO 4217) to the preferences module so all menagerie apps can store a per-user currency preference. Also ship a shared format_currency(amount, currency_code, locale=None) utility so each app does not roll its own.

Motivation

Snipe displays eBay listing prices — these come in whatever currency the seller uses. A UK buyer seeing USD on every listing is friction. Kiwi has food item costs. Peregrine has salary ranges. Crossbill is a finance app. All of them need this.

Proposed schema addition (preferences table)

currency_code TEXT DEFAULT 'USD'  -- ISO 4217: USD, GBP, EUR, CAD, AUD, etc.

Proposed utility (MIT, cf-core.preferences or cf-core.formatting)

def format_currency(amount: float, currency_code: str, locale: str = "en_US") -> str:
    """Format amount as a locale-aware currency string. e.g. format_currency(12.5, "GBP") -> "£12.50"""

Priority fallback chain

  1. User preference (currency_code in preferences table)
  2. App-level env var (CURRENCY_DEFAULT)
  3. System default: USD

Consumers

  • Snipe (primary — see snipe#X)
  • Kiwi (food costs, recipe budgets)
  • Peregrine (salary ranges)
  • Crossbill (finance app — whole-app requirement)

Notes

  • Currency conversion (live exchange rates) is out of scope here — that is a separate BSL feature. This issue is display preference only: store what currency the user wants to see, format amounts in that currency.
  • babel or py-moneyed are candidates for the formatting utility — check licenses before picking.
## Summary Add `currency_code` (ISO 4217) to the preferences module so all menagerie apps can store a per-user currency preference. Also ship a shared `format_currency(amount, currency_code, locale=None)` utility so each app does not roll its own. ## Motivation Snipe displays eBay listing prices — these come in whatever currency the seller uses. A UK buyer seeing USD on every listing is friction. Kiwi has food item costs. Peregrine has salary ranges. Crossbill is a finance app. All of them need this. ## Proposed schema addition (preferences table) ```sql currency_code TEXT DEFAULT 'USD' -- ISO 4217: USD, GBP, EUR, CAD, AUD, etc. ``` ## Proposed utility (MIT, cf-core.preferences or cf-core.formatting) ```python def format_currency(amount: float, currency_code: str, locale: str = "en_US") -> str: """Format amount as a locale-aware currency string. e.g. format_currency(12.5, "GBP") -> "£12.50""" ``` ## Priority fallback chain 1. User preference (`currency_code` in preferences table) 2. App-level env var (`CURRENCY_DEFAULT`) 3. System default: `USD` ## Consumers - Snipe (primary — see snipe#X) - Kiwi (food costs, recipe budgets) - Peregrine (salary ranges) - Crossbill (finance app — whole-app requirement) ## Notes - Currency *conversion* (live exchange rates) is out of scope here — that is a separate BSL feature. This issue is display preference only: store what currency the user wants to see, format amounts in that currency. - `babel` or `py-moneyed` are candidates for the formatting utility — check licenses before picking.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: Circuit-Forge/circuitforge-core#52
No description provided.