- Backend: validate display.currency against 10 supported ISO 4217 codes
(USD, GBP, EUR, CAD, AUD, JPY, CHF, MXN, BRL, INR); return 400 on
unsupported code with a clear message listing accepted values
- Frontend: useCurrency composable fetches rates from open.er-api.com
with 1-hour module-level cache and in-flight deduplication; falls back
to USD display on network failure
- Preferences store: adds display.currency with localStorage fallback for
anonymous users and localStorage-to-DB migration for newly logged-in users
- ListingCard: price and market price now convert from USD using live rates,
showing USD synchronously while rates load then updating reactively
- Settings UI: currency selector dropdown in Appearance section using
theme-aware CSS classes; available to all users (anon via localStorage,
logged-in via DB preference)
- Tests: 6 Python tests for the PATCH /api/preferences currency endpoint
(including ordering-safe fixture using patch.object on _LOCAL_SNIPE_DB);
14 Vitest tests for convertFromUSD, formatPrice, and formatPriceUSD