💻 Exemplos: Capítulo 02: Estruturas de Decisão e Structural Pattern Matching (match-case)
Especialização em Sistemas com Python 3.12+ • Capítulo 02
🎯 Demonstração Prática: Motor de Roteamento Transacional com Pattern Matching
O exemplo abaixo implementa um processador de eventos e liquidação financeira utilizando todos os recursos modernos do match-case (PEP 634):
- Desestruturação de dicionários heterogêneos (Mapping Patterns).
- Validação com cláusulas de guarda (Guards) e expressões de união (
|). - Desestruturação de classes de domínio com
__match_args__. - Fallbacks seguros com wildcard pattern (
_).
"""
demonstracao_roteamento_transacoes.py
Motor de Roteamento de Pagamentos e Análise de Risco com Pattern Matching.
Compatível com Python 3.12+ (Type Hints e PEP 634).
"""
from __future__ import annotations
from dataclasses import dataclass
from decimal import Decimal
from enum import StrEnum
from typing import Any, Final
# ==============================================================================
# 1. MODELOS DE DOMÍNIO E ENUMERAÇÕES
# ==============================================================================
class CanalPagamento(StrEnum):
PIX = "PIX"
CARTAO_CREDITO = "CARTAO_CREDITO"
BOLETO = "BOLETO"
TRANSFERENCIA_TED = "TED"
class StatusRoteamento(StrEnum):
LIQUIDADO_IMEDIATO = "LIQUIDADO_IMEDIATO"
ENCAMINHADO_ANTIFRAUDE = "ENCAMINHADO_ANTIFRAUDE"
AGUARDANDO_COMPENSACAO = "AGUARDANDO_COMPENSACAO"
REJEITADO_REGRA_NEGOCIO = "REJEITADO_REGRA_NEGOCIO"
PAYLOAD_INVALIDO = "PAYLOAD_INVALIDO"
@dataclass(slots=True)
class CartaoMetadata:
bandeira: str
emissor_estrangeiro: bool
score_reputacao: int
@dataclass(slots=True)
class ParecerOperacao:
id_transacao: str
status: StatusRoteamento
motivo: str
taxa_aplicada: Decimal
valor_liquido: Decimal
# ==============================================================================
# 2. MOTOR DE AVALIAÇÃO DE TRANSAÇÕES
# ==============================================================================
LIMITE_ALERTA_PIX: Final[Decimal] = Decimal("20000.00")
TAXA_PIX: Final[Decimal] = Decimal("0.00")
TAXA_CREDITO_NACIONAL: Final[Decimal] = Decimal("0.025")
TAXA_CREDITO_INTERNACIONAL: Final[Decimal] = Decimal("0.048")
TAXA_BOLETO_FIXA: Final[Decimal] = Decimal("3.50")
def rotear_transacao(payload: dict[str, Any]) -> ParecerOperacao:
"""Classifica e calcula liquidação através de Structural Pattern Matching."""
match payload:
# Padrão 1: PIX de alto valor com acionamento de guarda antifraude
case {
"id": str(tx_id),
"canal": CanalPagamento.PIX,
"valor": Decimal(v),
"chave_origem": str(origem),
} if v >= LIMITE_ALERTA_PIX:
return ParecerOperacao(
id_transacao=tx_id,
status=StatusRoteamento.ENCAMINHADO_ANTIFRAUDE,
motivo=f"Transação PIX de R$ {v:,.2f} ultrapassou o teto seguro. Análise manual obrigatória.",
taxa_aplicada=Decimal("0.00"),
valor_liquido=v
)
# Padrão 2: PIX regular para liquidação instantânea
case {
"id": str(tx_id),
"canal": CanalPagamento.PIX,
"valor": Decimal(v),
"chave_origem": str(origem),
}:
return ParecerOperacao(
id_transacao=tx_id,
status=StatusRoteamento.LIQUIDADO_IMEDIATO,
motivo=f"PIX liquidado em tempo real via SPI para {origem}.",
taxa_aplicada=TAXA_PIX,
valor_liquido=v
)
# Padrão 3: Cartão de Crédito com desestruturação de classe aninhada e verificação de risco
case {
"id": str(tx_id),
"canal": CanalPagamento.CARTAO_CREDITO,
"valor": Decimal(v),
"metadata": CartaoMetadata(emissor_estrangeiro=True, score_reputacao=score)
} if score < 700:
return ParecerOperacao(
id_transacao=tx_id,
status=StatusRoteamento.REJEITADO_REGRA_NEGOCIO,
motivo=f"Cartão emitido no exterior com reputação insuficiente ({score}/1000).",
taxa_aplicada=Decimal("0.00"),
valor_liquido=Decimal("0.00")
)
# Padrão 4: Cartão de Crédito aprovado (nacional ou internacional com reputação alta)
case {
"id": str(tx_id),
"canal": CanalPagamento.CARTAO_CREDITO,
"valor": Decimal(v),
"metadata": CartaoMetadata(emissor_estrangeiro=bool(ext), bandeira=str(b))
}:
aliquota = TAXA_CREDITO_INTERNACIONAL if ext else TAXA_CREDITO_NACIONAL
desconto = (v * aliquota).quantize(Decimal("0.01"))
return ParecerOperacao(
id_transacao=tx_id,
status=StatusRoteamento.LIQUIDADO_IMEDIATO,
motivo=f"Venda autorizada na bandeira {b} ({'Internacional' if ext else 'Nacional'}).",
taxa_aplicada=desconto,
valor_liquido=v - desconto
)
# Padrão 5: Boleto Bancário com compensação D+1
case {
"id": str(tx_id),
"canal": CanalPagamento.BOLETO,
"valor": Decimal(v),
"codigo_barras": str(linha)
} if v >= Decimal("10.00"):
return ParecerOperacao(
id_transacao=tx_id,
status=StatusRoteamento.AGUARDANDO_COMPENSACAO,
motivo="Registro emitido na CIP. Liquidação agendada para o próximo dia útil.",
taxa_aplicada=TAXA_BOLETO_FIXA,
valor_liquido=v - TAXA_BOLETO_FIXA
)
# Fallback de segurança para requisições malformadas
case {"id": str(tx_id)}:
return ParecerOperacao(
id_transacao=tx_id,
status=StatusRoteamento.PAYLOAD_INVALIDO,
motivo="Campos mandatórios ausentes para o canal informado.",
taxa_aplicada=Decimal("0.00"),
valor_liquido=Decimal("0.00")
)
case _:
return ParecerOperacao(
id_transacao="DESCONHECIDA",
status=StatusRoteamento.PAYLOAD_INVALIDO,
motivo="Estrutura de dados totalmente irreconhecível.",
taxa_aplicada=Decimal("0.00"),
valor_liquido=Decimal("0.00")
)
# ==============================================================================
# 3. DEMONSTRAÇÃO E BATERIA DE TESTES
# ==============================================================================
if __name__ == "__main__":
transacoes_amostra: list[dict[str, Any]] = [
{
"id": "TX-001",
"canal": CanalPagamento.PIX,
"valor": Decimal("350.00"),
"chave_origem": "financeiro@empresa.com.br"
},
{
"id": "TX-002",
"canal": CanalPagamento.PIX,
"valor": Decimal("85000.00"),
"chave_origem": "diretoria@holding.com.br"
},
{
"id": "TX-003",
"canal": CanalPagamento.CARTAO_CREDITO,
"valor": Decimal("1200.00"),
"metadata": CartaoMetadata(bandeira="Mastercard", emissor_estrangeiro=False, score_reputacao=920)
},
{
"id": "TX-004",
"canal": CanalPagamento.CARTAO_CREDITO,
"valor": Decimal("5400.00"),
"metadata": CartaoMetadata(bandeira="Amex", emissor_estrangeiro=True, score_reputacao=450)
}
]
print("=" * 75)
print(" MOTOR DE LIQUIDAÇÃO E ANÁLISE DE RISCO FINANCEIRO (PYTHON 3.12+)")
print("=" * 75)
for tx in transacoes_amostra:
resultado = rotear_transacao(tx)
print(f"Transação : {resultado.id_transacao}")
print(f"Status : [{resultado.status.value}]")
print(f"Motivo : {resultado.motivo}")
print(f"Taxa Ret. : R$ {resultado.taxa_aplicada:>8.2f}")
print(f"Líquido : R$ {resultado.valor_liquido:>8.2f}")
print("-" * 75)