Currencies API
Manage supported currencies (KES, USD, UGX, TZS, etc.) and exchange rates for frontend conversion. List, get-default, and convert are public (no auth) so customers can view currencies and convert prices. Create, update, and set-default require admin. Base path: <API_BASE_URL>/currencies.
rate_to_base
Each currency has rate_to_base: units of this currency per 1 unit of the base (default) currency. The default currency always has rate_to_base = 1. Example: if USD is base and 1 USD = 130 KES, then KES has rate_to_base = 130. Frontend converts via (amount / from_rate) * to_rate.
Currencies
Query active_only: use 1, true, or yes (default) to filter active only; 0 or false for all.
Create currency. Permission: admin. Body: code (required), name (required), symbol (required), rate_to_base (optional, default 1; use 1 for base/default), is_default (optional, default false). 409 if code exists.
List currencies with rate_to_base. Public (no auth). Response: {"currencies": [{"id", "code", "name", "symbol", "rate_to_base", "is_default", "is_active", "created_at"}, ...]}.
Update currency. Permission: admin. Body: optional name, symbol, rate_to_base, is_default. 404 if not found.
Get default currency. Permission: view_products. 404 if no default set.
Convert amount between currencies. Public (no auth). Query: amount (number), from (currency code, e.g. USD), to (currency code, e.g. KES). Response: {"amount": 130, "from": "USD", "to": "KES"}.
Set currency as default (and rate_to_base = 1). Permission: admin. 404 if currency not found.
Common responses
List, default, and convert require no auth. Write routes (POST, PATCH, PUT default): 401 if missing or invalid token, 403 if not admin. 404 if currency not found. 409 if currency code already exists.