Files
aurum/backend/scripts/capitalize_transaction_descriptions.py
ZProger 6cc532378b feat: auto-capitalize the first letter of transaction descriptions
Transactions/recurring templates entered with mixed casing ("траты на
продукты") are now capitalized on create/update via a Pydantic validator,
so the fix applies to every client, not just the web UI. Adds a one-off
backfill script for existing rows.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-24 23:10:22 +03:00

44 lines
1.5 KiB
Python

"""One-off backfill: capitalizes the first letter of every existing
transaction/recurring-template description, so historical rows entered with
mixed casing ("покупка продуктов", "ПОКУПКА хлеба") match the auto-
capitalization now applied on create/update (see app/core/text.py and the
description validators in app/schemas/transaction.py, app/schemas/recurring.py).
Run it once against a running stack with:
docker compose exec backend python -m scripts.capitalize_transaction_descriptions
Safe to re-run — already-capitalized descriptions are left untouched.
"""
import asyncio
from sqlalchemy import select
from app.core.text import capitalize_first_letter
from app.db.session import AsyncSessionLocal
from app.models import RecurringTransaction, Transaction
async def _capitalize_all(session, model) -> int:
result = await session.execute(select(model))
updated = 0
for row in result.scalars().all():
fixed = capitalize_first_letter(row.description)
if fixed != row.description:
row.description = fixed
updated += 1
return updated
async def main() -> None:
async with AsyncSessionLocal() as session:
transactions_updated = await _capitalize_all(session, Transaction)
recurring_updated = await _capitalize_all(session, RecurringTransaction)
await session.commit()
print(f"Transactions updated: {transactions_updated}")
print(f"Recurring templates updated: {recurring_updated}")
if __name__ == "__main__":
asyncio.run(main())