# Documentação - Sistema de Contas do Core Banking
## **Dupla Entrada**
### **Conceitos contábeis**
Para entender a implementação do **Sistema de Contas do Core Banking** é preciso entender alguns fundamentos básicos de contabilidade, sendo os conceitos **DÉBITO** e **CRÉDITO**, de **ATIVO**, **PASSIVO** e **PATRIMONIO LIQUIDO**, além do que também é conhecido como Médoto das **Partidas Dobradas** (Método de **Dupla Entrada**).
#### **Débito e Crédito**
O conceito de **Débito** na contabilidade é a aplicação de recurso em uma conta contábil, ou seja, significa que o dinheiro, o bem ou o serviço destina-se àquela conta. Já o conceito de **Crédito** é a origem do recurso aplicado em uma conta contábil, ou seja, significa que o dinheiro, o bem ou o serviço teve origem naquela conta.
A diferença entre o total de Débitos e o total de Créditos feitos em uma conta é denominado saldo. Se o valor dos débitos for superior ao valor dos créditos, a conta terá um **saldo devedor**. Se o valor dos Créditos for superior ao valor dos Débitos, a conta terá um **Saldo Credor**. A natureza da conta é que irá determinar o lado a ser utilizado para os aumentos e o lado para as diminuições.
#### **Contas de Ativo, Passivo e Patrimônio Liquido**
**Ativos** são os bens e direitos de uma entidade, ou seja, os recursos econômicos que ela possui ou controla como resultado de eventos passados. Em Conta de Ativos o aumento do saldo deverá ser registrado como Débito e a diminuição como Crédito. Essas Contas **SEMPRE** devem apresentar saldo devedor ou saldo nulo.
Abaixo está em tabela um exemplo de razonete de uma conta de ativo:
Débito | Crédito
--------- | ------
Aumento | Diminuição
**Passivos** são as obrigações de uma entidade, ou seja, as despesas e compromissos que ela tem com terceiros. Em Conta de Passivos o aumento do saldo deverá ser registrado como Crédito e a diminuição como Débito. Essas Contas **SEMPRE** devem apresentar saldo credor ou saldo nulo.
Abaixo está em tabela um exemplo de razonete de uma conta de passivo:
Débito | Crédito
--------- | ------
Diminuição| Aumento
**Patrimônio Líquido** é a diferença entre o ativo e o passivo, ou seja, a riqueza líquida da entidade. Em Conta de Patrimônio Líquido, assim como em contas de Passivo o aumento do saldo deverá ser registrado como Crédito e a diminuição como Débito. Essas Contas **SEMPRE** devem apresentar saldo credor ou saldo nulo.
Abaixo está em tabela um exemplo de razonete de uma conta de patrimônio líquido:
Débito | Crédito
--------- | ------
Diminuição| Aumento
**Observação:** Ao final de todas as operações, o valor da soma de todas as contas de Ativo deve ser igual ao valor da soma de todas as contas de passivo.
---
### **Casos de Uso**
De modo que fique o mais simples possível para a primeira implementação, foi definido que os casos de uso iriam abranger apenas a operação mais simples contabilmente, o que inclui apenas operações de movimentação entre contas.
## **Core Banking - MAZDRA**
### **Introdução**
#### **O que é um Core Banking?**
O **Core Banking** é um sistema de back-end que processa transações bancárias e atualiza contas e outros registros financeiros. Ele é a espinha dorsal de todas as operações bancárias, incluindo a gestão de contas, depósitos, empréstimos, processamento de transações, contabilidade e conformidade regulatória.
Este sistema é crucial para a integração de todas as atividades inerentes ao sistema bancário, auxiliando as instituições bancárias na tarefa de integrar serviços e criar uma infraestrutura simplificada e prática para as operações financeiras.
Os fundamentos de um sistema Core Banking se baseiam em permitir a execução fluida e segura de várias operações bancárias. Inclui transações bancárias diárias, como depósitos, retiradas, transferências, pagamento de empréstimos e aplicações de investimento.
Outro aspecto essencial do sistema Core Banking é a capacidade de processar e armazenar grandes volumes de informação de forma segura. Isso é fundamental para manter a confiança dos clientes e aderir a diversas obrigações regulatórias.
#### **Ledger (Livro Caixa)**
Um **Ledger** é um arquivo principal de computador para registro e totalização de transações econômicas medidas em termos de uma unidade monetária ou quantitativa de conta por tipo de conta, com débitos e créditos em colunas separadas. Ele é um registro compartilhado de informações, como um livro caixa de um banco, onde ficam registradas todas as transações financeiras feitas.
#### **O que é o MAZDRA?**
O Mazdra é um sistema de banking que atende **investment banking**, **core banking** e algumas funcionalidades de **retail banking**. Um dos pontos principais do sistema é a emissão e oferta de ativos financeiros. Atualmente o sistema também está iniciando o desenvolvimento de um módulo de Core Banking para transações bancárias, consolidação de saldo, conciliação de caixa e formação de extrato bancário.
#### **Módulos do MAZDRA**
Atualmente os módulos do Mazdra são: **Cadastros**, **Contas/Core**, **Emissão** e **Preço**.
##### **Cadastros**
O módulo de cadastros é responsável por cadastrar uma conta e inicializar seu estado em todas as suas instâncias na aplicação. Isso inclui contas de **Pessoa Física** e contas de **Instituição**.
##### **Emissão**
O módulo de emissão é reponsável por emitir papéis de negociação e registrar operações de ativos financeiros.
##### **Preço**
O módulo de preço é o módulo responsável por montar a posição (preço) dos ativos financeiros.
##### **Contas**
O módulo de contas é a API que possui os métodos para fazer requisições relacionadas às contas bancárias, modificando suas informações e alterando os saldos através das múltiplas ações e serviços disponíveis no mazdra.
##### **Core**
O módulo core é o cerne bancário da aplicação. Ele é responsável pelo registro em livro-caixa (Ledger) de todas as operações, auditoria das ações executadas sobre as contas no Mazdra, conciliação de caixa e fornece as informações necessárias para consolidação de saldo e formação de extrato.
---
### **Mapeamento de Contas**
De modo que seja facilitado a implementação inicial e atualizações futuras, foi feito um mapeamento das possíveis contas presentes em um ledger. Esse mapeamento fez a separação em **Conta Corrente**, **Conta Investimento**, **Conta Poupança** e **Patrimonio Líquido**, além de separar os tipos de conta em Ativo, Passivo/PL e Movimentação.
#### **Conta Corrente**
##### **Ativo**
* Caixa
* Valor em Trânsito
* Cheque Especial
* Gastos
* Empréstimos
##### **Passivo**
* Lançamentos Futuros
* Juros - Cheque Especial
* Juros - Empréstimo
* Lucro de Venda
##### **Movimentação**
* Transferência Interna
* Transferência Externa
* Estornos
#### **Conta Investimento**
##### **Ativo**
* Caixa
* Valor em Trânsito
* Compras
* Vendas
* Valor de Ativo - Ação
* Valor de Ativo - Renda Fixa
* Valor de Ativo - Futuro
* Valor de Ativo - Opção
* Valor de Ativo - Swap
* Estoque de Ação
* Estoque de Renda Fixa
* Estoque de Futuro
* Estoque de Estoque de Opção
* Estoque de Swap
* Dividendos
* Prêmio
* Amortização
##### **Passivo**
* Valor do Imposto de Renda
* Provisões
* Tributações - IOF
* Tributações - Dividendo
* Juros - Renda Fixa
* Lucro de Venda
##### **Movimentação**
* Transferência Interna
* Transferência Externa
* Estornos
#### **Conta Poupança**
##### **Ativo**
* Caixa
##### **Passivo**
* Valor do Imposto de Renda
* Rendimentos
##### **Movimentação**
* Transferência Interna
* Transferência Externa
* Estornos
#### **Patrimonio Líquido**
##### **Passivo**
* Capital
---
### **Modelos de Dados**
#### **Camada Core - Ledger**
##### **Entrada**
Uma entrada é um registro de movimentação em uma conta específica.
As entradas seguirão o modelo base a seguir:
```javascript
class Entrada {
id: string, // ID único
subconta: string, // ID da conta alvo
fluxo: string, // Fluxo da entrada: credito | débito
valor: number,
data_emissao: datetime,
}
```
##### **Transação**
As entradas são partes de uma transação. Cada transação gera pelo menos duas entradas.
As transações seguirão o modelo base a seguir:
```javascript
class Transacao {
id: string,
entradas: string[], // IDs das entradas da transação
data_liquidacao: datetime,
}
```
#### **Camada de Aplicação**
##### **Conta**
A entidade de Conta segura o saldo consolidado de um conjunto de subscontas. Ela seguirá o modelo base a seguir:
##### **Fluxo Contábil**
A seguir temos o fluxo contábil de uma transação de transferência interna:

---
### **Arquitetura**
A Arquitetura do Core Banking foi pensada para ser divida em duas camadas,a Core e a de Aplicação. Na Camada Core será utilizado o Apache Kafka como sistema de mensageria e sua funcionalidade de streaming para processamento de informações em tempo real, e o Apache Cassandra para como Banco de Dados, que será imutável através da logica de combinação de *hashs* onde caso haja inconsistencias entre as entradas subsequentes, o mesmo acusará erro.
Já na Camada de Aplicação estarão os serviços que irão consumir as informações que foram consolidadas no Ledger, como por exemplo o Extrato, Saldo, Precificação, Conciliação, Long Term Storage entre outros.

---
### **Possíveis Tecnologias**
#### **Apache Cassandra**
O Apache Cassandra é um banco de dados NoSQL distribuído de código aberto, confiável por milhares de empresas por sua escalabilidade e alta disponibilidade sem comprometer o desempenho. Ele é adequado para aplicações que não podem perder dados, mesmo quando um data center inteiro cai. O Cassandra é testado em clusters de até 1.000 nós e com centenas de casos de uso e esquemas do mundo real. Ele oferece suporte à replicação em vários data centers, fornecendo menor latência para seus usuários e a tranquilidade de saber que você pode sobreviver a interrupções regionais. A documentação oficial do Apache Cassandra cobre desde a instalação, a linguagem de consulta do Cassandra (CQL), a configuração, operação, ferramentas como cqlsh e nodetool, entre outros.
#### **Apache Kafka**
O Apache Kafka atua como o canal de comunicação entre os diversos sistemas bancários. Ele permite que os diferentes componentes do sistema, como aplicativos de internet banking, caixas eletrônicos e sistemas de gerenciamento de contas, compartilhem dados em tempo real. Os produtores (como os sistemas de transações) enviam mensagens para tópicos específicos no Kafka, e os consumidores (como os sistemas de relatórios) se inscrevem nesses tópicos para receber as informações relevantes. As mensagens são armazenadas em partições, garantindo escalabilidade e alta disponibilidade.
#### **Kafka Streaming**
O Kafka Streaming é o cliente de streaming do Kafka. Ele é uma ferramenta de streaming utilizada largamente no mercado, porém é conhecido pela complexidade de sustentação em produção. A grande vantagem é a facilidade de implementar operações em streaming com seus clientes JVM-based. As desvantagens são a complexidade de alterar, manter e fazer backup de seu motor implantado em produção e a falta de customização de suas funcionalidades, já que ele opera de forma autônoma seu cache de entradas (utiliza RocksDB para fazer sua memória KV).
---
### **Observabilidade**
Utilizaremos a stack **Prometheus** + **Grafana** para observabilidade. Boa parte dos serviços fornecem integração nativa com o Prometheus e existem boas dashboards prontas para o Grafana.
## **Implementação**
### **Uso do Kafka**
Decidimos utilizar o kafka também como um *banco de dados* secundario para garantir a replicação de dados.
### **Imutabilidade**
No sistema de contas do Core Banking, o Ledger desempenha a função principal no sistema, onde o mesmo precisa garantir que as informações registradas nele estejam corretas e livres de ação humana.
O Apache Cassandra, banco de dados NoSQL escolhido para ser o Ledger do Core, não garante a imutabilidade nativamente. Por conta disso, essa imutabilidade será implementada por nós através da logica de *hashs* encadeados, onde cada entrada irá gerar um *hash* de si mesmo que irá ser usado para se ligar com a proxima entrada, que irá também gerar um *hash* de si mesma utilizando o *hash* anterior, contatenado com o seu conteúdo.
A logica pode ser melhor visualizada na imagem abaixo:

Além disso, também será implementada a lógica de Merkle Tree para garantir que blocos de dados serão recebidos intactos e inalterados e para verificar se a entrada faz parte do sistema.
---
### **Testes**
---
### **Benchmark**