diff --git a/migrations/versions/011_consolidate_finance_templates.py b/migrations/versions/011_consolidate_finance_templates.py new file mode 100644 index 0000000..0877e9f --- /dev/null +++ b/migrations/versions/011_consolidate_finance_templates.py @@ -0,0 +1,132 @@ +"""Consolidate 3 finance templates into 1 Finance & Accounting Manager + +Revision ID: 011 +Revises: 010 +Create Date: 2026-03-26 + +SMBs don't need separate Financial Manager, Controller, and Accountant +templates. Consolidates into a single versatile Finance & Accounting +Manager that covers invoicing, budgets, reporting, and compliance. +""" + +from __future__ import annotations + +import json +from typing import Sequence, Union + +from alembic import op + +revision: str = "011" +down_revision: Union[str, None] = "010" +branch_labels: Union[str, Sequence[str], None] = None +depends_on: Union[str, Sequence[str], None] = None + + +NEW_NAME = "Finance & Accounting Manager" +NEW_ROLE = "Finance & Accounting Manager" +NEW_DESCRIPTION = ( + "A versatile finance professional that handles invoicing, accounts payable/receivable, " + "expense tracking, budget monitoring, financial reporting, and cash flow analysis. " + "Keeps the books accurate, flags budget overruns early, and provides clear financial " + "summaries for business owners. Escalates unusual transactions, large expenses, and " + "compliance questions to leadership." +) +NEW_PERSONA = ( + "You are meticulous, trustworthy, and proactive about financial health. You handle " + "the full spectrum of SMB finance — from processing invoices and reconciling expenses " + "to preparing monthly reports and monitoring cash flow. You communicate financial " + "information in plain language that non-finance stakeholders can understand. You flag " + "anomalies and budget risks early rather than waiting for month-end surprises. You " + "escalate decisions involving significant expenditures, tax matters, or regulatory " + "compliance to the business owner." +) +NEW_TOOLS = json.dumps(["knowledge_base_search"]) +NEW_ESCALATION = json.dumps([ + {"condition": "transaction_amount > 5000", "action": "handoff_human"}, + {"condition": "tax_or_compliance_question", "action": "handoff_human"}, + {"condition": "budget_overrun AND percentage > 15", "action": "handoff_human"}, +]) +NEW_TRANSLATIONS = json.dumps({ + "es": { + "name": "Gerente de Finanzas y Contabilidad", + "description": ( + "Un profesional financiero versátil que gestiona facturación, cuentas por pagar y " + "cobrar, seguimiento de gastos, monitoreo de presupuesto, informes financieros y " + "análisis de flujo de caja. Mantiene los libros precisos, señala desviaciones " + "presupuestarias tempranamente y proporciona resúmenes financieros claros para los " + "propietarios del negocio. Escala transacciones inusuales, gastos importantes y " + "consultas de cumplimiento al liderazgo." + ), + "persona": ( + "Eres meticuloso, confiable y proactivo con la salud financiera. Manejas todo el " + "espectro de finanzas para PyMEs — desde procesar facturas y conciliar gastos hasta " + "preparar informes mensuales y monitorear el flujo de caja. Comunicas la información " + "financiera en un lenguaje claro que los interesados no financieros pueden entender. " + "Señalas anomalías y riesgos presupuestarios tempranamente en lugar de esperar a las " + "sorpresas de fin de mes. Escalas decisiones que involucran gastos significativos, " + "asuntos fiscales o cumplimiento regulatorio al propietario del negocio." + ), + }, + "pt": { + "name": "Gerente de Finanças e Contabilidade", + "description": ( + "Um profissional financeiro versátil que gerencia faturamento, contas a pagar e " + "receber, acompanhamento de despesas, monitoramento de orçamento, relatórios " + "financeiros e análise de fluxo de caixa. Mantém os registros precisos, sinaliza " + "desvios orçamentários precocemente e fornece resumos financeiros claros para os " + "proprietários do negócio. Escala transações incomuns, despesas significativas e " + "questões de conformidade para a liderança." + ), + "persona": ( + "Você é meticuloso, confiável e proativo com a saúde financeira. Você lida com " + "todo o espectro de finanças para PMEs — desde processar faturas e conciliar " + "despesas até preparar relatórios mensais e monitorar o fluxo de caixa. Você " + "comunica informações financeiras em linguagem clara que stakeholders não " + "financeiros conseguem entender. Você sinaliza anomalias e riscos orçamentários " + "precocemente em vez de esperar surpresas no fechamento do mês. Você escala " + "decisões que envolvem gastos significativos, questões fiscais ou conformidade " + "regulatória para o proprietário do negócio." + ), + }, +}) + + +def upgrade() -> None: + # Update the Financial Manager template to become the consolidated one + op.execute(f""" + UPDATE agent_templates + SET name = '{NEW_NAME}', + role = '{NEW_ROLE}', + description = '{NEW_DESCRIPTION.replace("'", "''")}', + persona = '{NEW_PERSONA.replace("'", "''")}', + tool_assignments = '{NEW_TOOLS}'::jsonb, + escalation_rules = '{NEW_ESCALATION}'::jsonb, + sort_order = 50, + translations = '{NEW_TRANSLATIONS}'::jsonb + WHERE name = 'Financial Manager' + """) + + # Remove Controller and Accountant + op.execute("DELETE FROM agent_templates WHERE name = 'Controller'") + op.execute("DELETE FROM agent_templates WHERE name = 'Accountant'") + + +def downgrade() -> None: + # Restore the original Financial Manager + op.execute(""" + UPDATE agent_templates + SET name = 'Financial Manager', + role = 'Financial Planning and Analysis Manager', + sort_order = 50 + WHERE name = 'Finance & Accounting Manager' + """) + + # Re-insert Controller and Accountant (minimal — full restore would need original data) + op.execute(""" + INSERT INTO agent_templates (id, name, role, description, category, persona, system_prompt, model_preference, tool_assignments, escalation_rules, is_active, sort_order, translations) + VALUES (gen_random_uuid(), 'Controller', 'Financial Controller', 'Financial controller template', 'finance', '', '', 'balanced', '[]'::jsonb, '[]'::jsonb, true, 60, '{}'::jsonb) + """) + op.execute(""" + INSERT INTO agent_templates (id, name, role, description, category, persona, system_prompt, model_preference, tool_assignments, escalation_rules, is_active, sort_order, translations) + VALUES (gen_random_uuid(), 'Accountant', 'Staff Accountant', 'Staff accountant template', 'finance', '', '', 'balanced', '[]'::jsonb, '[]'::jsonb, true, 70, '{}'::jsonb) + """)