Venezuela’s dual-currency economy requires every financial transaction to be recorded in both US Dollars (USD) and Venezuelan Bolívares Soberanos (BsS) simultaneously. SCO Autolavados treats multi-currency support as a first-class concern: exchange rates are fetched automatically from an official source, stored on the centralDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/Luisangelebp/SCO_Autolavados/llms.txt
Use this file to discover all available pages before exploring further.
AutoLavado entity, stamped immutably on each sale at the moment of transaction, and used to maintain separate running balances for each currency. This ensures that historical invoices and reports always reflect the rate that was actually in effect — not a retroactively recalculated value.
How Rates Are Stored
Exchange rates live on theAutoLavado database model — the single global record that represents the car wash business. This model is the authoritative source of truth for the current rate.
| Field | Type | Description |
|---|---|---|
currentTasaBs | Float | Current USD → BsS exchange rate (e.g., 36.21) |
currentTasaEurBs | Float | Current EUR → BsS exchange rate |
lastTasaUpdate | DateTime | Timestamp of the last successful rate fetch |
balanceUsd | Float | Cumulative USD balance (incremented by approved payments, decremented by expenses) |
balanceBs | Float | Cumulative BsS balance (same logic) |
0 in the Prisma schema and are populated on first server startup before any requests are handled.
Automatic Rate Fetching
Rate updates are handled byExchangeRateService.ts (backend/src/services/ExchangeRateService.ts), which fetches both the USD and EUR official rates in parallel from the dolarapi.com BCV (Banco Central de Venezuela) data source:
- USD endpoint:
https://ve.dolarapi.com/v1/dolares/oficial - EUR endpoint:
https://ve.dolarapi.com/v1/euros/oficial
promedio, venta, or price field from each response (whichever is present), then writes both rates and a new lastTasaUpdate timestamp to the AutoLavado record via Prisma.
Daily Cron Job
A cron job defined insrc/index.ts triggers updateExchangeRate() every day at 6:00 AM VET (Venezuela Time, America/Caracas):
dayjs library with the utc and timezone plugins is used throughout the backend to correctly handle the America/Caracas timezone (UTC−4, no DST).
Current Rate Endpoint
The current rate is exposed via a dedicated REST endpoint:On every server startup,
initializeApp() in src/index.ts calls updateExchangeRate() immediately — before the HTTP server begins accepting requests. This guarantees that a fresh rate is always available even after a container restart, regardless of the time of day.Using Rates in Sales
When a sale is created viaPOST /api/sales, the caller must supply the tazaUsd field containing the exchange rate at the moment of transaction:
tazaUsd value is stored immutably on the Sales record. This means:
- Historical invoices always show the exact rate at which the transaction occurred.
- Reporting and reconciliation are accurate even as the official rate fluctuates day to day.
- No retroactive recalculation is needed when the rate changes after the sale is recorded.
Sales Prisma model reflects this design:
Payment Recording
Payments are submitted viaPOST /api/payments and support both currency amounts on the same record:
Currency Rules by Payment Method
| Payment Method | method value | mountUSD | mountBS | Notes |
|---|---|---|---|---|
| Cash USD / Zelle | "cash" / "Zelle" | > 0 | 0 | USD-only methods |
| Cash BsS / Pago Móvil | "Efectivo" / "Pago Movil" | 0 | > 0 | BsS-only methods |
| Binance / USDT | "binance" | > 0 | must be 0 | Dollar-only; no BsS component |
| Bank transfer | "transferencia" | 0 | > 0 | Typically BsS |
For Binance payments,
mountBS must be 0. The backend checks method === 'binance' (case-sensitive, lowercase) and throws an error if mountBS > 0, preventing double-counting when reconciling USD and BsS balances.Balance Tracking
When aPayment record is approved (approved: true), both amounts are added to the corresponding balance fields on the AutoLavado entity:
balanceUsd— incremented bymountUSDof each approved payment; decremented when USD expenses are recorded.balanceBs— incremented bymountBSof each approved payment; decremented when BsS expenses are recorded.
Expense model mirrors this dual-currency pattern:
Payments & Sales API
Full API reference for the payments and sales endpoints.
AutoLavado API
Endpoints for reading and updating the AutoLavado entity, including exchange rate data.