mirror of
https://github.com/escalante29/WealthySmart.git
synced 2026-07-17 13:08:46 +02:00
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>
264 lines
13 KiB
Python
264 lines
13 KiB
Python
"""money columns to numeric
|
|
|
|
Revision ID: 7f567c8bafdb
|
|
Revises: c3da001a0eb3
|
|
Create Date: 2026-06-10 13:37:26.281634
|
|
|
|
"""
|
|
from typing import Sequence, Union
|
|
|
|
from alembic import op
|
|
import sqlalchemy as sa
|
|
import sqlmodel
|
|
|
|
|
|
# revision identifiers, used by Alembic.
|
|
revision: str = '7f567c8bafdb'
|
|
down_revision: Union[str, Sequence[str], None] = 'c3da001a0eb3'
|
|
branch_labels: Union[str, Sequence[str], None] = None
|
|
depends_on: Union[str, Sequence[str], None] = None
|
|
|
|
|
|
def upgrade() -> None:
|
|
"""Upgrade schema."""
|
|
# ### commands auto generated by Alembic - please adjust! ###
|
|
op.alter_column('account', 'balance',
|
|
existing_type=sa.DOUBLE_PRECISION(precision=53),
|
|
type_=sa.Numeric(precision=15, scale=2),
|
|
existing_nullable=False)
|
|
op.alter_column('account', 'next_payment',
|
|
existing_type=sa.DOUBLE_PRECISION(precision=53),
|
|
type_=sa.Numeric(precision=15, scale=2),
|
|
existing_nullable=True)
|
|
op.alter_column('balanceoverride', 'override_balance',
|
|
existing_type=sa.DOUBLE_PRECISION(precision=53),
|
|
type_=sa.Numeric(precision=15, scale=2),
|
|
existing_nullable=False)
|
|
op.alter_column('exchangerate', 'buy_rate',
|
|
existing_type=sa.DOUBLE_PRECISION(precision=53),
|
|
type_=sa.Numeric(precision=15, scale=6),
|
|
existing_nullable=False)
|
|
op.alter_column('exchangerate', 'sell_rate',
|
|
existing_type=sa.DOUBLE_PRECISION(precision=53),
|
|
type_=sa.Numeric(precision=15, scale=6),
|
|
existing_nullable=False)
|
|
op.alter_column('municipalreceipt', 'subtotal',
|
|
existing_type=sa.DOUBLE_PRECISION(precision=53),
|
|
type_=sa.Numeric(precision=15, scale=2),
|
|
existing_nullable=False)
|
|
op.alter_column('municipalreceipt', 'interests',
|
|
existing_type=sa.DOUBLE_PRECISION(precision=53),
|
|
type_=sa.Numeric(precision=15, scale=2),
|
|
existing_nullable=False)
|
|
op.alter_column('municipalreceipt', 'iva',
|
|
existing_type=sa.DOUBLE_PRECISION(precision=53),
|
|
type_=sa.Numeric(precision=15, scale=2),
|
|
existing_nullable=False)
|
|
op.alter_column('municipalreceipt', 'total',
|
|
existing_type=sa.DOUBLE_PRECISION(precision=53),
|
|
type_=sa.Numeric(precision=15, scale=2),
|
|
existing_nullable=False)
|
|
op.alter_column('pensionsnapshot', 'saldo_anterior',
|
|
existing_type=sa.DOUBLE_PRECISION(precision=53),
|
|
type_=sa.Numeric(precision=15, scale=2),
|
|
existing_nullable=False)
|
|
op.alter_column('pensionsnapshot', 'aportes',
|
|
existing_type=sa.DOUBLE_PRECISION(precision=53),
|
|
type_=sa.Numeric(precision=15, scale=2),
|
|
existing_nullable=False)
|
|
op.alter_column('pensionsnapshot', 'rendimientos',
|
|
existing_type=sa.DOUBLE_PRECISION(precision=53),
|
|
type_=sa.Numeric(precision=15, scale=2),
|
|
existing_nullable=False)
|
|
op.alter_column('pensionsnapshot', 'retiros',
|
|
existing_type=sa.DOUBLE_PRECISION(precision=53),
|
|
type_=sa.Numeric(precision=15, scale=2),
|
|
existing_nullable=False)
|
|
op.alter_column('pensionsnapshot', 'traslados',
|
|
existing_type=sa.DOUBLE_PRECISION(precision=53),
|
|
type_=sa.Numeric(precision=15, scale=2),
|
|
existing_nullable=False)
|
|
op.alter_column('pensionsnapshot', 'comision',
|
|
existing_type=sa.DOUBLE_PRECISION(precision=53),
|
|
type_=sa.Numeric(precision=15, scale=2),
|
|
existing_nullable=False)
|
|
op.alter_column('pensionsnapshot', 'correccion',
|
|
existing_type=sa.DOUBLE_PRECISION(precision=53),
|
|
type_=sa.Numeric(precision=15, scale=2),
|
|
existing_nullable=False)
|
|
op.alter_column('pensionsnapshot', 'bonificacion',
|
|
existing_type=sa.DOUBLE_PRECISION(precision=53),
|
|
type_=sa.Numeric(precision=15, scale=2),
|
|
existing_nullable=False)
|
|
op.alter_column('pensionsnapshot', 'saldo_final',
|
|
existing_type=sa.DOUBLE_PRECISION(precision=53),
|
|
type_=sa.Numeric(precision=15, scale=2),
|
|
existing_nullable=False)
|
|
op.alter_column('recurringitem', 'amount',
|
|
existing_type=sa.DOUBLE_PRECISION(precision=53),
|
|
type_=sa.Numeric(precision=15, scale=2),
|
|
existing_nullable=False)
|
|
op.alter_column('savingsaccrual', 'memp_amount',
|
|
existing_type=sa.DOUBLE_PRECISION(precision=53),
|
|
type_=sa.Numeric(precision=15, scale=2),
|
|
existing_nullable=False)
|
|
op.alter_column('savingsaccrual', 'mpat_amount',
|
|
existing_type=sa.DOUBLE_PRECISION(precision=53),
|
|
type_=sa.Numeric(precision=15, scale=2),
|
|
existing_nullable=False)
|
|
op.alter_column('transaction', 'amount',
|
|
existing_type=sa.DOUBLE_PRECISION(precision=53),
|
|
type_=sa.Numeric(precision=15, scale=2),
|
|
existing_nullable=False)
|
|
op.alter_column('watermeterreading', 'reading_previous',
|
|
existing_type=sa.DOUBLE_PRECISION(precision=53),
|
|
type_=sa.Numeric(precision=15, scale=2),
|
|
existing_nullable=False)
|
|
op.alter_column('watermeterreading', 'reading_current',
|
|
existing_type=sa.DOUBLE_PRECISION(precision=53),
|
|
type_=sa.Numeric(precision=15, scale=2),
|
|
existing_nullable=False)
|
|
op.alter_column('watermeterreading', 'consumption_m3',
|
|
existing_type=sa.DOUBLE_PRECISION(precision=53),
|
|
type_=sa.Numeric(precision=15, scale=2),
|
|
existing_nullable=False)
|
|
op.alter_column('watermeterreading', 'agua_potable',
|
|
existing_type=sa.DOUBLE_PRECISION(precision=53),
|
|
type_=sa.Numeric(precision=15, scale=2),
|
|
existing_nullable=False)
|
|
op.alter_column('watermeterreading', 'serv_ambientales',
|
|
existing_type=sa.DOUBLE_PRECISION(precision=53),
|
|
type_=sa.Numeric(precision=15, scale=2),
|
|
existing_nullable=False)
|
|
op.alter_column('watermeterreading', 'alcant_sanitario',
|
|
existing_type=sa.DOUBLE_PRECISION(precision=53),
|
|
type_=sa.Numeric(precision=15, scale=2),
|
|
existing_nullable=False)
|
|
op.alter_column('watermeterreading', 'iva',
|
|
existing_type=sa.DOUBLE_PRECISION(precision=53),
|
|
type_=sa.Numeric(precision=15, scale=2),
|
|
existing_nullable=False)
|
|
# ### end Alembic commands ###
|
|
|
|
|
|
def downgrade() -> None:
|
|
"""Downgrade schema."""
|
|
# ### commands auto generated by Alembic - please adjust! ###
|
|
op.alter_column('watermeterreading', 'iva',
|
|
existing_type=sa.Numeric(precision=15, scale=2),
|
|
type_=sa.DOUBLE_PRECISION(precision=53),
|
|
existing_nullable=False)
|
|
op.alter_column('watermeterreading', 'alcant_sanitario',
|
|
existing_type=sa.Numeric(precision=15, scale=2),
|
|
type_=sa.DOUBLE_PRECISION(precision=53),
|
|
existing_nullable=False)
|
|
op.alter_column('watermeterreading', 'serv_ambientales',
|
|
existing_type=sa.Numeric(precision=15, scale=2),
|
|
type_=sa.DOUBLE_PRECISION(precision=53),
|
|
existing_nullable=False)
|
|
op.alter_column('watermeterreading', 'agua_potable',
|
|
existing_type=sa.Numeric(precision=15, scale=2),
|
|
type_=sa.DOUBLE_PRECISION(precision=53),
|
|
existing_nullable=False)
|
|
op.alter_column('watermeterreading', 'consumption_m3',
|
|
existing_type=sa.Numeric(precision=15, scale=2),
|
|
type_=sa.DOUBLE_PRECISION(precision=53),
|
|
existing_nullable=False)
|
|
op.alter_column('watermeterreading', 'reading_current',
|
|
existing_type=sa.Numeric(precision=15, scale=2),
|
|
type_=sa.DOUBLE_PRECISION(precision=53),
|
|
existing_nullable=False)
|
|
op.alter_column('watermeterreading', 'reading_previous',
|
|
existing_type=sa.Numeric(precision=15, scale=2),
|
|
type_=sa.DOUBLE_PRECISION(precision=53),
|
|
existing_nullable=False)
|
|
op.alter_column('transaction', 'amount',
|
|
existing_type=sa.Numeric(precision=15, scale=2),
|
|
type_=sa.DOUBLE_PRECISION(precision=53),
|
|
existing_nullable=False)
|
|
op.alter_column('savingsaccrual', 'mpat_amount',
|
|
existing_type=sa.Numeric(precision=15, scale=2),
|
|
type_=sa.DOUBLE_PRECISION(precision=53),
|
|
existing_nullable=False)
|
|
op.alter_column('savingsaccrual', 'memp_amount',
|
|
existing_type=sa.Numeric(precision=15, scale=2),
|
|
type_=sa.DOUBLE_PRECISION(precision=53),
|
|
existing_nullable=False)
|
|
op.alter_column('recurringitem', 'amount',
|
|
existing_type=sa.Numeric(precision=15, scale=2),
|
|
type_=sa.DOUBLE_PRECISION(precision=53),
|
|
existing_nullable=False)
|
|
op.alter_column('pensionsnapshot', 'saldo_final',
|
|
existing_type=sa.Numeric(precision=15, scale=2),
|
|
type_=sa.DOUBLE_PRECISION(precision=53),
|
|
existing_nullable=False)
|
|
op.alter_column('pensionsnapshot', 'bonificacion',
|
|
existing_type=sa.Numeric(precision=15, scale=2),
|
|
type_=sa.DOUBLE_PRECISION(precision=53),
|
|
existing_nullable=False)
|
|
op.alter_column('pensionsnapshot', 'correccion',
|
|
existing_type=sa.Numeric(precision=15, scale=2),
|
|
type_=sa.DOUBLE_PRECISION(precision=53),
|
|
existing_nullable=False)
|
|
op.alter_column('pensionsnapshot', 'comision',
|
|
existing_type=sa.Numeric(precision=15, scale=2),
|
|
type_=sa.DOUBLE_PRECISION(precision=53),
|
|
existing_nullable=False)
|
|
op.alter_column('pensionsnapshot', 'traslados',
|
|
existing_type=sa.Numeric(precision=15, scale=2),
|
|
type_=sa.DOUBLE_PRECISION(precision=53),
|
|
existing_nullable=False)
|
|
op.alter_column('pensionsnapshot', 'retiros',
|
|
existing_type=sa.Numeric(precision=15, scale=2),
|
|
type_=sa.DOUBLE_PRECISION(precision=53),
|
|
existing_nullable=False)
|
|
op.alter_column('pensionsnapshot', 'rendimientos',
|
|
existing_type=sa.Numeric(precision=15, scale=2),
|
|
type_=sa.DOUBLE_PRECISION(precision=53),
|
|
existing_nullable=False)
|
|
op.alter_column('pensionsnapshot', 'aportes',
|
|
existing_type=sa.Numeric(precision=15, scale=2),
|
|
type_=sa.DOUBLE_PRECISION(precision=53),
|
|
existing_nullable=False)
|
|
op.alter_column('pensionsnapshot', 'saldo_anterior',
|
|
existing_type=sa.Numeric(precision=15, scale=2),
|
|
type_=sa.DOUBLE_PRECISION(precision=53),
|
|
existing_nullable=False)
|
|
op.alter_column('municipalreceipt', 'total',
|
|
existing_type=sa.Numeric(precision=15, scale=2),
|
|
type_=sa.DOUBLE_PRECISION(precision=53),
|
|
existing_nullable=False)
|
|
op.alter_column('municipalreceipt', 'iva',
|
|
existing_type=sa.Numeric(precision=15, scale=2),
|
|
type_=sa.DOUBLE_PRECISION(precision=53),
|
|
existing_nullable=False)
|
|
op.alter_column('municipalreceipt', 'interests',
|
|
existing_type=sa.Numeric(precision=15, scale=2),
|
|
type_=sa.DOUBLE_PRECISION(precision=53),
|
|
existing_nullable=False)
|
|
op.alter_column('municipalreceipt', 'subtotal',
|
|
existing_type=sa.Numeric(precision=15, scale=2),
|
|
type_=sa.DOUBLE_PRECISION(precision=53),
|
|
existing_nullable=False)
|
|
op.alter_column('exchangerate', 'sell_rate',
|
|
existing_type=sa.Numeric(precision=15, scale=6),
|
|
type_=sa.DOUBLE_PRECISION(precision=53),
|
|
existing_nullable=False)
|
|
op.alter_column('exchangerate', 'buy_rate',
|
|
existing_type=sa.Numeric(precision=15, scale=6),
|
|
type_=sa.DOUBLE_PRECISION(precision=53),
|
|
existing_nullable=False)
|
|
op.alter_column('balanceoverride', 'override_balance',
|
|
existing_type=sa.Numeric(precision=15, scale=2),
|
|
type_=sa.DOUBLE_PRECISION(precision=53),
|
|
existing_nullable=False)
|
|
op.alter_column('account', 'next_payment',
|
|
existing_type=sa.Numeric(precision=15, scale=2),
|
|
type_=sa.DOUBLE_PRECISION(precision=53),
|
|
existing_nullable=True)
|
|
op.alter_column('account', 'balance',
|
|
existing_type=sa.Numeric(precision=15, scale=2),
|
|
type_=sa.DOUBLE_PRECISION(precision=53),
|
|
existing_nullable=False)
|
|
# ### end Alembic commands ###
|