# Restruturação Billing
## Geral
### Revisar os fluxos de negócio
- Tentar simplificar as integrações para diminuir certos erros que ocorrem com frequência (Ex.: Envio de BP)
- Evitar a redundância de dados, o Billing deveria ser a "fonte única da verdade" (*Single source of truth*) em relação aos dados de cobrança (Ex.: Envio do plano de pagamento para outros 2 sistemas)
- Compensação de transações (Ex.: Estimular a deleção do plano de pagamento quando ocorrer um erro durante o fluxo de emissão)
- Envio do delta do plano de pagamento para a GW. O processo é síncrono e depende da geração da prévia do plano, que possui um péssimo desempenho hoje em dia (Segundo o Scout, para gerar essa prévia **o BC executa aproximadamente 650 consultas no DB**, gastando em média mais de 20 segundos por chamada!!!!!!)
### Modelo genérico de conciliação
- Adyen x Braspag
- Modelo atual baseado no leiaute da Braspag
### Gateway de pagamento genérico (OK)
- Não existe uma abstração coesa para representar um `Gateway` de pagamento no Billing
- Modelo atual baseado em abstrações específicas do domínio da Braspag (Ex.: `Sale`)
### Desacoplar o Billing do SAP
- Demora excessiva para implementar novas funcionalidades (Processo mais burocrático)
- SAP deveria ser responsável apenas pela parte contábil
- Restrições técnicas que inviabilizam certas soluções (Ex.: Certas rotinas foram desenvolvidas para processamento em lotes, bloqueios em nível de sistema etc.)
- Necessidade de mão de obra especializada para desenvolver novas funcionalidades (2 devs ABAP/PI dedicados X 40 devs Ruby)
### Revisar o MER (modelo de dados)
- Tabelas não estão totalmente normalizadas
- Modelagem corrente gera vários problemas no dia a dia (Ex.: Gerar todas as parcelas com antecedência, duplicação do plano de pagamento etc.)
- Modelo complexo demais ([Sugestão de MER simplificado](https://files.slack.com/files-pri/T0AB16SBH-FJE0S0LSH/billing.png))
- Certas atualizações (*updates* em registros do DB) ocasionam a perda de informações (Sobrescrever certos dados causa problemas de rastreabilidade, adotar estratégia de implementação *append-only* etc.)
### Desacoplar o billing dos demais microserviços
- Problema do **ovo e da galinha** (Billing salva o número da apólice mas plano de pagamento deve ser gerado antes da apólice)
- Evitar as lógicas de `binding` (procurar primeiro pagamento/meio de pagamento "solto" dentro do billing usando o ID de uma entidade criada em outro micro serviço)
- Inversão de dependência (Ex.: `Policy Service` passaria a salvar o ID do plano de pagamento, do meio de pagamento etc.)
- Billing conhece regras de produto (Ex.: Data de vencimento do boleto depende do tipo de produto)
### Billing tem várias responsabilidades "implícitas"
- _Reporting_, _accounting_, _endorsement_ etc.
- Código está complexo demais
- Funcionalidades não são ortogonais (Ex.: Podemos "quebrar" o código da recorrência se fizermos algum ajuste no módulo de endosso)
- Criação de mais micro serviços e/ou módulos totalmente desacoplados
## Recorrência
### Melhores práticas para a implementação do processo automático de cobrança
- O processo deve ser executado de forma automática todos os dias, num determinado horário
- Pensar num mecanismo simples para desligar ou desativar o serviço (tipo um *feature toggle*)
- Executar o processo em lotes (Ex.: Jamais carregar todas as parcelas a serem cobradas de uma vez)
- Se possível, evitar concorrência com o sistema on-line
- Desenvolver um mecanismo (*Rake task*?) para executar o processo de forma manual, como um *fallback*
- Desenvolver o processo de forma que não possa haver duas instâncias deste sendo executadas ao mesmo tempo (Ex.: Se algum usuário tentar iniciar o processo manualmente durante a janela de execução automática, ou se algum cliente tentar efetuar uma cobrança imediata)
- Processo deveria ser autossuficiente (Ex: Evitar ao máximo chamadas *HTTP* para outro serviço que não seja o gateway de pagamento para evitar pontos de falha)
- Processo deve ser idempotente (Ex.: Pode ser executado várias vezes e não deve realizar cobranças em duplicidade)