mirror of
https://github.com/escalante29/WealthySmart.git
synced 2026-07-17 11:08:47 +02:00
Migrate all 29 money columns from float to NUMERIC/Decimal (BE-02)
Models use Money = Annotated[Decimal, PlainSerializer(float)] so storage is exact NUMERIC(15,2) (rates 15,6) while JSON keeps emitting plain numbers — the frontend contract is unchanged, pinned by test_models_serialization.py. Service layers coerce to float at their boundaries (projection math, rate multipliers, agent tool output, the savings constants become Decimal) so no naive Decimal/float mixing can raise. Migration 7f567c8bafdb applied to dev: per-row values and the table sum byte-identical before/after; endpoints verified live on the new schema. 59/59 tests green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -66,9 +66,9 @@ def get_accounts() -> list[dict]:
|
||||
"bank": a.bank.value,
|
||||
"label": a.label,
|
||||
"currency": a.currency.value,
|
||||
"balance": a.balance,
|
||||
"balance": float(a.balance),
|
||||
"account_type": a.account_type.value,
|
||||
"next_payment": a.next_payment,
|
||||
"next_payment": float(a.next_payment) if a.next_payment is not None else None,
|
||||
}
|
||||
for a in rows
|
||||
]
|
||||
@@ -79,15 +79,15 @@ def get_net_worth() -> dict:
|
||||
USD/EUR balances are converted at the latest exchange rate."""
|
||||
accounts = _s().exec(select(Account)).all()
|
||||
rate = get_current_rate(_s())
|
||||
sell = rate.sell_rate if rate else 600.0
|
||||
sell = float(rate.sell_rate) if rate else 600.0
|
||||
assets_crc = 0.0
|
||||
liabilities_crc = 0.0
|
||||
for a in accounts:
|
||||
amt = a.balance
|
||||
amt = float(a.balance)
|
||||
if a.currency.value == "USD":
|
||||
amt = a.balance * sell
|
||||
amt = float(a.balance) * sell
|
||||
elif a.currency.value == "EUR":
|
||||
amt = a.balance * sell * 1.08 # rough; real conversion is endpoint-side
|
||||
amt = float(a.balance) * sell * 1.08 # rough; real conversion is endpoint-side
|
||||
if a.account_type.value == "LIABILITY":
|
||||
liabilities_crc += amt
|
||||
else:
|
||||
@@ -139,7 +139,7 @@ def get_recent_transactions(
|
||||
"id": t.id,
|
||||
"date": t.date.isoformat(),
|
||||
"merchant": t.merchant,
|
||||
"amount": t.amount,
|
||||
"amount": float(t.amount),
|
||||
"currency": t.currency.value,
|
||||
"source": t.source.value,
|
||||
"transaction_type": t.transaction_type.value,
|
||||
@@ -243,7 +243,7 @@ def list_recurring_items() -> list[dict]:
|
||||
{
|
||||
"id": r.id,
|
||||
"name": r.name,
|
||||
"amount": r.amount,
|
||||
"amount": float(r.amount),
|
||||
"currency": r.currency.value,
|
||||
"item_type": r.item_type.value,
|
||||
"frequency": r.frequency.value,
|
||||
@@ -281,12 +281,12 @@ def get_pension_snapshots(
|
||||
"fund": r.fund.value,
|
||||
"period_start": r.period_start.isoformat(),
|
||||
"period_end": r.period_end.isoformat(),
|
||||
"saldo_anterior": r.saldo_anterior,
|
||||
"aportes": r.aportes,
|
||||
"rendimientos": r.rendimientos,
|
||||
"retiros": r.retiros,
|
||||
"comision": r.comision,
|
||||
"saldo_final": r.saldo_final,
|
||||
"saldo_anterior": float(r.saldo_anterior),
|
||||
"aportes": float(r.aportes),
|
||||
"rendimientos": float(r.rendimientos),
|
||||
"retiros": float(r.retiros),
|
||||
"comision": float(r.comision),
|
||||
"saldo_final": float(r.saldo_final),
|
||||
}
|
||||
for r in rows
|
||||
]
|
||||
@@ -334,11 +334,11 @@ def get_municipal_receipts(
|
||||
"period": r.period,
|
||||
"account": r.account,
|
||||
"finca": r.finca,
|
||||
"subtotal": r.subtotal,
|
||||
"interests": r.interests,
|
||||
"iva": r.iva,
|
||||
"total": r.total,
|
||||
"water_consumption_m3": sum(w.consumption_m3 for w in readings),
|
||||
"subtotal": float(r.subtotal),
|
||||
"interests": float(r.interests),
|
||||
"iva": float(r.iva),
|
||||
"total": float(r.total),
|
||||
"water_consumption_m3": float(sum(w.consumption_m3 for w in readings)),
|
||||
}
|
||||
)
|
||||
return out
|
||||
@@ -436,8 +436,8 @@ def get_exchange_rate() -> dict:
|
||||
if not rate:
|
||||
return {"buy_rate": None, "sell_rate": None, "date": None}
|
||||
return {
|
||||
"buy_rate": rate.buy_rate,
|
||||
"sell_rate": rate.sell_rate,
|
||||
"buy_rate": float(rate.buy_rate),
|
||||
"sell_rate": float(rate.sell_rate),
|
||||
"date": rate.date.isoformat(),
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user