# 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 fo 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
### **Casos de Uso**
Para a modelagem de caso de uso, foram considerados os conceitos contábeis apresentados anteriormente. Porém, para melhor visualização de algumas transações, foi criado um novo tipo de conta que foi denominado como conta de movimentação, de modo que a mesma funciona como ponto intermediário para transferência de valores entre duas contas e segue a mesma lógica de uma conta de ativo.
Uma explicação mais detalhada pode ser vista na imagem abaixo:

#### **1º Caso de Uso**
Para o primeiro caso de uso foi considerado um exemplo simples de transação bancária. Esse exemplo começa com o depósito e consolidação do Capital na conta "Caixa" da **Conta Corrente**. Em seguida, ocorre uma transferência interna, que é posteriormente consolidada em uma conta "Caixa" na **Conta de Investimento**. A próxima etapa envolve a compra de ações, seguida pela compra de um investimento de renda fixa.
Após essas transações, o pagamento da amortização na renda fixa é realizado e consolidado. Os juros da renda fixa são calculados considerando uma taxa de 10%. Em seguida, o imposto sobre o rendimento é pago, também considerando uma taxa de 10%.
Finalmente, ocorre a retirada de fundos da conta, que é então consolidada.
O fluxo dessas operações pode ser visualizado abaixo:

#### **2º Caso de Uso**
Para o segundo caso de uso foi considerado uma transação que envolve, além da compra de ativos, a venda do mesmo e também uma operação utilizando o cartão de crédito. Esse modelo começa com o depósito e consolidação do Capital na conta "Caixa" da **Conta Corrente**. Em seguida, ocorre uma transferência interna, que é posteriormente consolidada em uma conta "Caixa" na **Conta de Investimento**. A próxima etapa envolve a compra de ações, seguido da venda desse mesmo ativo com um lucro de 10% sobre o valor inicialmente investido.
Após essas transações, é iniciada a transferência interna que é consolidada na conta "Caixa" da **Conta Corrente** e também uma compra de algum item não especificado utilizando um cartão de crédito.
Finalmente, ocorre a retirada de fundos da conta, que é então consolidada.
O fluxo dessas operações pode ser visualizado abaixo:

#### **3º Caso de Uso**
Para o terceiro caso de uso foi considerado uma transação que envolve, além da compra de ativos, a venda do mesmo e também uma operação utilizando o cartão de crédito, uma compra À vista e um estorno de uma compra. Esse modelo começa com o depósito e consolidação do Capital na conta "Caixa" da **Conta Corrente**. Em seguida, ocorre uma transferência interna, que é posteriormente consolidada em uma conta "Caixa" na **Conta de Investimento**.
A próxima etapa envolve a compra de ações, seguido da venda desse mesmo ativo com um lucro de 50% sobre o valor inicialmente investido. Após essas transações, é iniciada a transferência interna que é consolidada na conta "Caixa" da **Conta Corrente** e também uma compra de algum item não especificado utilizando um cartão de crédito e o pagamento desse valor.
Por fim, ocorre uma compra à vista que por algum motivo é estornada, e logo em seguida há a retirada de fundos da conta, que é então consolidada.
O fluxo dessas operações pode ser visualizado abaixo:

## **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
* Bloqueados
* Gastos
##### **Passivo**
* Lançamentos Futuros
* Juros - Cheque Especial
* Juros - Empréstimo
* Lucro de Venda
##### **Movimentação**
* Depósito
* Retirada
* Empréstimo
* 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
* Bloqueados
##### **Passivo**
* Valor do Imposto de Renda
* Provisões
* Tributações - IOF
* Tributações - Dividendo
* Juros - Renda Fixa
* Lucro de Venda
##### **Movimentação**
* Depósito
* Retirada
* Empréstimo
* Transferência Interna
* Transferência Externa
* Estornos
#### **Conta Poupança**
##### **Ativo**
* Caixa
* Bloqueados
##### **Passivo**
* Valor do Imposto de Renda
* Rendimentos
##### **Movimentação**
* Depósito
* Retirada
* Empréstimo
* 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
conta: string, // ID da conta alvo
tipo_conta: string, // Tipo da conta: "ativo" | "passivo"
fluxo: boolean, // Fluxo da entrada: true (credito) | false (debito)
valor: number,
data_emissao: datetime,
data_liquidacao: datetime,
quantidade: integer // Quantidade de estoque comprado/transferido
}
```
##### **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,
opcode: string, // Opcode: string que identifica o tipo de transação
entradas: string[], // IDs das entradas da transação
transacao_futura: string, // ID da transação futura para o caso de uma operação em que parte é resolvida no futuro
data_emissao: datetime,
data_liquidacao: datetime,
futuro: boolean // Flag de operação futura ou não
}
```
#### **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:
```javascript
class Conta {
id: string, // ID único
tags: {}, // Metadados de busca
saldo: number,
saldo_provisionado: number,
subcontas: string[], // IDs das subcontas normais
subcontas_provisoes: string[] // IDs das subcontas de provisões
}
```
##### **Subconta**
A entidade subconta segura um valor de uma natureza específica. Ela seguirá o modelo base a seguir:
```javascript
class Subconta {
id: string,
valor: number,
tipo_conta: string, // Tipo da conta: "ativo" | "passivo"
quantidade: integer // Quantidade caso seja subconta de estoque
}
```
##### **Transação Futura**
A entidade transação futura representa uma transação a ser efetuada com base no tempo. Ela pode ser a liquidação de uma transação futura ou uma transação agendada sem compromisso de sucesso. Segue o modelo a seguir:
```javascript
class Transacao_Futura {
id: string,
opcode: string, // Opcode: string que identifica o tipo de transação
id_ledger: string, // ID da transação relacionada no ledger (caso não seja apenas um agendamento) para auditoria
entradas: string[], // IDs das entradas da transação (apenas futuras)
data_emissao: datetime,
data_liquidacao: datetime
}
```
##### **Entrada Futura**
As entradas futuras são entradas de uma transação futura. Elas são geradas no momento de emissão de uma transação futura porém são incluídas no livro-caixa somente no momento da liquidação:
```javascript
class Entrada_Futura {
id: string, // ID único
conta: string, // ID da conta alvo
tipo_conta: string, // Tipo da conta: "ativo" | "passivo"
fluxo: boolean, // Fluxo da entrada: true (credito) | false (debito)
valor: number, // Valor da entrada
data_emissao: datetime,
data_liquidacao: datetime, // Data de liquidação
quantidade: integer // Quantidade de estoque comprado/transferido
}
```
#### **Agendamentos Recorrentes**
Os agendamentos recorrentes são transações agendadas para serem executadas por um número de vezes num intervalo de tempo. São armazenadas de forma diferente das transações com partes futuras ou transações unitárias agendadas, é uma tabela dedicada para ter as informações necessárias para gerar as transações e as entradas conforme chega o momentos de executar a iteração da transferência.
```javascript
class Agendamento {
id: string, // ID único
conta: string, // ID da conta
conta_alvo: string, // ID da conta alvo da transação
tipo_conta: string, // Tipo da conta: "ativo" | "passivo"
valor: number,
data_emissao: datetime,
intervalo: number, // Intervalo em dias (e.g. 15, 30, 60)
id_efetivadas: string[] // IDs das transações já efetivadas no ledger
}
```
##### **Fluxo Contábil**
A seguir temos o fluxo contábil de uma transação de transferência interna:

### **Arquitetura**

### **Possíveis Tecnologias**
#### **Immudb**
Immudb é um banco de dados imutável que se baseia em chave-valor. Foi lançado em 2020 e tem ganhado maior visibilidade. Sua linguagem de código-fonte é o Go. A principal vantagem deste banco é a imutabilidade forte, onde os estados da entradas do banco são salvos numa Merkle Tree e se uma entrada for sobrescrita o banco é corrompido, impedindo essa ação. O maior contra do immudb é a falta de ferramental pronto, onde seus clientes são enxutos e precisamos implementar muitas funcionalidades. Para atingir a performance e a segurança esperada ficamos muito restritos ao Go.
#### **Datomic**
Datomic é um gerenciador de banco de dados que garante imutabilidade e recuperação de estados anteriores das entidades. Ele é mantido pela Nubank e disponibilizado em licensa Apache 2.0. Na página do Datomic também são referenciados clientes como facebook e Netflix. A principal vantagem do Datomic é a validação pela indústria e o maior contra é que ele depende de um outro banco de dados para ser seu motor, logo a escolha do banco de dados impacta no futuro do desenvolvimento do ledger.
#### **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.
#### **PostgreSQL**
O PostgreSQL é um poderoso sistema de banco de dados relacional de objeto de código aberto que usa e estende o padrão SQL combinado com muitos recursos que armazenam e escalam com segurança as cargas de trabalho de dados mais complicadas. A documentação oficial do PostgreSQL cobre desde a instalação, a sintaxe SQL, a definição de dados, a manipulação de dados, consultas, tipos de dados, funções e operadores, conversão de tipo, índices, pesquisa de texto completo, controle de concorrência, dicas de desempenho, consulta paralela, 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).
#### **RabbitMQ**
Por outro lado, o RabbitMQ é responsável pela entrega confiável de mensagens. Ele gerencia as filas de mensagens, garantindo que nenhuma transação seja perdida. Quando um cliente faz uma transferência bancária, por exemplo, o sistema de transações envia a mensagem para uma troca no RabbitMQ. Essa troca encaminha a mensagem para a fila apropriada, onde o sistema de processamento de transações a retira e a processa. O RabbitMQ garante que todas as mensagens sejam entregues corretamente, mesmo em situações de alta carga ou falhas temporárias.
### **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**
### **Inicio**
#### **Generalização e agrupamento de transações**
Para garantir o funcionamento da lógica proposta sem que seja necessário o mapeamento manual de todas as transações, foi feito um modelo geral que aborda transações semelhantes e quais os seus possíveis fluxos de dados.
O agrupamento se deu da seguinte forma:
##### **Operação de Retirada**
Toda operação referente a retirada de valores da conta deverá seguir o seguinte padrão:
1. Crédito do valor na conta "Caixa"(poderá ser da Conta Corrente, Conta Investimento ou Conta Poupança);
2. Débito do valor na conta "Retirada"(Caminho da conta retirada será determinado a partir da conta que tenha sido creditada no passo anterior);
3. Crédito do valor na conta "Retirada"(mesmo caminho utilizada no passo anterior);
4. Débito do valor na conta "Capital" em Patrimônio Líquido.
##### **Operação de Depósito**
Toda operação referente a depósitos de valores em conta deverá seguir o seguinte padrão:
1. Crédito do valor na conta "Capital" em Patrimônio Líquido;
2. Débito do valor na conta "Depósito" (caminho irá depender da conta futura em que será depositado o valor);
3. Crédito do valor na conta "Deposito" (mesmo caminho utilizado na conta anterior);
4. Débito do valor na conta "Caixa"(poderá ser da Conta Corrente, Conta Investimento ou Conta Poupança);
##### **Operação de Transferência Interna**
Toda operação referente a transferências internas deverá seguir o seguinte padrão:
1. Crédito do valor na conta "Caixa"(poderá ser da Conta Corrente, Conta Investimento ou Conta Poupança);
2. Débito do valor na conta "Transferência Interna"(Caminho da conta retirada será determinado a partir da conta que tenha sido creditada no passo anterior);
3. Crédito do valor na conta "Transferência Interna"(mesmo caminho utilizada no passo anterior);
4. Débito do valor na conta "Caixa"(poderá ser da Conta Corrente, Conta Investimento ou Conta Poupança);
##### **Operações de compras à prazo**
Toda operação referente a compras à prazo deverá seguir o seguinte padrão:
1. Crédito do valor na conta "Contas à pagar" em Conta Corrente;
2. Débito do valor na conta "Gastos" em Conta Corrente.
##### **Operação de pagamento de compras à prazo**
Toda operação referente ao pagamento de compras à prazo deverá seguir o seguinte padrão:
1. Débito do valor na conta "Contas à pagar" em Conta Corrente;
2. Crédito do valor na conta "Caixa" em Conta Corrente.
##### **Operação de Compras à vista**
Toda operação referente a compras à vista deverá seguir o seguinte padrão:
1. Crédito do valor na conta "Caixa" em Conta Corrente;
2. Débito do valor na conta "Gastos" em Conta Corrente;
##### **Operação de Estorno**
Toda operação referentes a estorno deverá seguir o seguinte padrão:
1. Crédito do valor na conta "Gastos" em Conta Corrente;
2. Débito do valor na conta "Estorno" em Conta Corrente;
3. Crédito do valor na conta "Estorno" na Conta Corrente;
4. Débito do valor na conta "Caixa" (para compras à vista) ou na conta "Contas à pagar" (para compras à prazo) em Conta Corrente.
##### **Operação de Compra de Ativos**
Toda operação referente a compra de qualquer ativo deverá seguir o seguinte padrão:
1. Crédito do valor na conta "Caixa" em Conta Investimento;
2. Débito do valor na conta "Valor de *Ativo comprado*" em Conta Investimento;
3. Crédito da quantidade na conta "*Ativos comprado* Disponíveis" em Conta Investimento;
4. Débito da quantidade na conta "Estoque de *Ativo comprado*" em Conta investimento.
##### **Operação de Venda de Ativos**
Toda operação referente a venda de qualquer ativo deverá seguir o seguinte padrão:
1. Crédito do valor na conta "Valor de *Ativo comprado*" em Conta Investimento;
2. Débito do valor na conta "Caixa" em Conta Investimento;
3. Débito da quantidade na conta "*Ativo comprado* Disponíveis" em Conta Investimento;
4. Crédito da quantidade na conta "Estoque de *Ativo comprado*" em Conta Investimento;
**Observação**: Caso haja lucro na venda do ativo, deverá ser creditado na conta passiva "Lucro de Venda" a diferença entre o que foi creditado na conta "Valor de *Ativo comprado*" e a conta "Caixa".
#### **Testes**
#### **Benchmark**