Files
clientflow_backend/app/action_catalog.py

217 lines
6.5 KiB
Python

"""Catálogo único de ações atuais do ClientFlow.
O LLM só pode produzir `TRIAGE_ACTION_CODES`. Códigos operacionais
antigos foram removidos da triagem e tratados como eventos/operações
internas (`business_events`, `operation_links` e decisões do workflow).
"""
_INTERNAL_ORDER_PREP_CODE = "PREPARE" + "_ORDER"
TRIAGE_ACTION_CODES = {
"SEND_INFO",
"SEND_QUOTE",
"SEND_PROFORMA",
"SEND_INVOICE",
"CONFIRM_PAYMENT",
"SUPPORT",
"REMOVE_FROM_LIST",
"IGNORE_SPAM",
"REVIEW_MANUALLY",
"NO_ACTION",
"MARK_NO_INTEREST",
"IGNORE_BOUNCE",
}
INTERNAL_ACTION_CODES = {
"FOLLOW_UP_QUOTE",
"FOLLOW_UP_PROFORMA",
"FOLLOW_UP_PAYMENT",
"FOLLOW_UP_CUSTOMER_REVIEW",
"FOLLOW_UP_GENERIC",
"CONFIRM_DELIVERY",
"RECOVER_OPPORTUNITY",
"REVIEW_NURTURE",
_INTERNAL_ORDER_PREP_CODE,
"VALIDATE_PHYSICAL_ORDER",
"CREATE_SHIPMENT",
"REVIEW_RECONSTRUCTED_PROCESS",
}
ACTION_CODES = TRIAGE_ACTION_CODES | INTERNAL_ACTION_CODES
ACTION_MAP = {
"SEND_QUOTE": {
"route": "vendas",
"action_required": True,
"action": "Enviar proposta/cotação",
"safe_to_post": True,
"business_event_on_done": "quote_sent",
},
"SEND_INFO": {
"route": "vendas",
"action_required": True,
"action": "Enviar informação ao cliente",
"safe_to_post": True,
"business_event_on_done": "info_sent",
},
"SEND_PROFORMA": {
"route": "financeiro",
"action_required": True,
"action": "Enviar orçamento para pagamento",
"safe_to_post": True,
"business_event_on_done": "payment_quote_sent",
},
"SEND_INVOICE": {
"route": "financeiro",
"action_required": True,
"action": "Enviar fatura ao cliente",
"safe_to_post": True,
"business_event_on_done": "invoice_sent",
},
"CONFIRM_PAYMENT": {
"route": "financeiro",
"action_required": True,
"action": "Confirmar pagamento",
"safe_to_post": False,
"business_event_on_done": "payment_confirmed",
},
_INTERNAL_ORDER_PREP_CODE: {
"route": "operacoes",
"action_required": True,
"action": "Preparar encomenda / Odoo",
"safe_to_post": False,
"business_event_on_done": "order_prepared",
},
"VALIDATE_PHYSICAL_ORDER": {
"route": "logistica",
"action_required": True,
"action": "Validar encomenda física",
"safe_to_post": False,
"business_event_on_done": "physical_order_validated",
},
"CREATE_SHIPMENT": {
"route": "logistica",
"action_required": True,
"action": "Enviar encomenda",
"safe_to_post": False,
"business_event_on_done": "shipment_created",
},
"REVIEW_RECONSTRUCTED_PROCESS": {
"route": "rever",
"action_required": True,
"action": "Validar processo reconstruído",
"safe_to_post": False,
"business_event_on_done": "reconstructed_process_validated",
},
"SUPPORT": {
"route": "suporte",
"action_required": True,
"action": "Responder ao pedido de suporte",
"safe_to_post": True,
"business_event_on_done": "support_handled",
},
"REMOVE_FROM_LIST": {
"route": "marketing",
"action_required": True,
"action": "Remover contacto da lista",
"safe_to_post": True,
"business_event_on_done": "contact_removed_from_list",
},
"IGNORE_SPAM": {
"route": "spam",
"action_required": False,
"action": "Ignorar spam",
"safe_to_post": False,
"business_event_on_done": None,
},
"IGNORE_BOUNCE": {
"route": "sistema",
"action_required": False,
"action": "Ignorar email devolvido/bounce",
"safe_to_post": False,
"business_event_on_done": None,
},
"REVIEW_MANUALLY": {
"route": "rever",
"action_required": True,
"action": "Rever manualmente",
"safe_to_post": False,
"business_event_on_done": None,
},
"NO_ACTION": {
"route": "rever",
"action_required": False,
"action": "Sem ação necessária",
"safe_to_post": False,
"business_event_on_done": None,
},
"MARK_NO_INTEREST": {
"route": "vendas",
"action_required": True,
"action": "Marcar sem interesse",
"safe_to_post": False,
"business_event_on_done": "opportunity_no_interest",
},
"FOLLOW_UP_QUOTE": {
"route": "vendas",
"action_required": True,
"action": "Fazer follow-up do orçamento",
"safe_to_post": False,
"business_event_on_done": "follow_up_done",
},
"FOLLOW_UP_PROFORMA": {
"route": "financeiro",
"action_required": True,
"action": "Fazer follow-up do orçamento para pagamento",
"safe_to_post": False,
"business_event_on_done": "follow_up_done",
},
"FOLLOW_UP_PAYMENT": {
"route": "financeiro",
"action_required": True,
"action": "Fazer follow-up de pagamento",
"safe_to_post": False,
"business_event_on_done": "follow_up_done",
},
"FOLLOW_UP_CUSTOMER_REVIEW": {
"route": "vendas",
"action_required": True,
"action": "Fazer follow-up da informação enviada",
"safe_to_post": False,
"business_event_on_done": "follow_up_done",
},
"FOLLOW_UP_GENERIC": {
"route": "vendas",
"action_required": True,
"action": "Fazer follow-up manual",
"safe_to_post": False,
"business_event_on_done": "follow_up_done",
},
"CONFIRM_DELIVERY": {
"route": "vendas",
"action_required": True,
"action": "Confirmar receção da comunicação",
"safe_to_post": False,
"business_event_on_done": "delivery_checked",
},
"RECOVER_OPPORTUNITY": {
"route": "vendas",
"action_required": True,
"action": "Recuperar oportunidade sem resposta",
"safe_to_post": False,
"business_event_on_done": "recovery_reviewed",
},
"REVIEW_NURTURE": {
"route": "vendas",
"action_required": True,
"action": "Rever oportunidade em acompanhamento futuro",
"safe_to_post": False,
"business_event_on_done": "nurture_reviewed",
},
}
def get_action_config(action_code: str) -> dict:
code = str(action_code or "").strip().upper()
return ACTION_MAP.get(code, ACTION_MAP["REVIEW_MANUALLY"])