Skip to content

lucasfdcampos/digital-wallet

Repository files navigation

Digital wallet

Solução para carteira digital

Index

Solução

Esta solução consiste em dois microsserviços onde é possível realizar as seguintes operações:

  • Cadastro de conta
    • Obter conta
  • Cadastro de wallet
    • Obter wallet
  • Extrato (history)
  • Transações: depósito, retirada, compra, cancelamento e estorno
  • Listagem de transações
    • Obter transação
  • Listagem de auditoria

Arquitetura

image info

Conforme a figura acima, toda estrutura está em containers Docker onde temos dois microsserviços: Account e Transaction. Ambos serviços se conectam e trocam eventos através do Apache Kafka e cada um tem seu próprio banco de dados PostgreSQL para persistencia e fonte de dados. O serviço Transaction se conecta ao MongoDB para salvar dados de auditoria.

Ambos serviços estão conectados ao Kong API-Gateway.

Account

Esse serviço é responsável por cadastrar uma conta e as wallets dessa conta, consultar o extrato (history), consulta da wallet (saldo) e envio de eventos de algumas transações para o serviço Transaction como: depósito, compra e saque (retirada).

Este serviço recebe um evento de atualizações de saldo e que também cria históricos de movimentações.

Transaction

Esse serviço é responsável por receber e processar eventos de transações que foram enviadas pelo Account e também criar transações de cancelamento e estorno. O Transaction também contém listagem de transações e de auditoria.

Todo envio de eventos são enviados pelo Apache Kafka e salvos no banco de dados PostgreSQL. A cada transacão recebida é gerado uma auditoria com MongoDB.

A premissa é que o Account seja um serviço mais “voltado ao cliente”, onde faria operações (transações) que teria mais controle, como: depósito, saque e efetuar compras. Já o serviço de Transaction seria um processamento das transações com a possibilidade da Companhia cancelar ou efetuar estornos, listar as transações e verificar dados de auditoria.

Cancelamento

Coloquei como regra para o Cancelamento que faça apenas para transactions do tipo PURCHASE (compra) e somente quando for último registro de compra. Assim ele gera um registro de transaction do tipo CANCELLATION e retorna o valor ao saldo da conta.

Estorno

O Estorno contém a mesma regra, porém é possível estornar qualquer transação do tipo PURCHASE, sem ser a ultima necessariamente.

Executando

Makefile

O comando abaixo irá subir todos os serviços Docker necessários:

make up-all

Manualmente

Caso prefira subir o ambiente sem o Makefile acima:

docker network create wallet-net
docker-compose up -d

Utilizando as APIs

Pode ser importado as collections do Insomnia (made by Kong) ou utilizar os comandos diretamente no terminal. É necessário ter o curl instalado!

Run in Insomnia}

Criando account

curl --request POST \
  --url http:https://localhost:8000/v1/account \
  --header 'Content-Type: application/json' \
  --data '{
	"name": "Jane Smith",
	"email": "[email protected]"
}'

Buscando account por id

curl --request GET \
  --url http:https://localhost:8000/v1/account/<id>

Criando wallet

curl --request POST \
  --url http:https://localhost:8000/v1/wallet \
  --header 'Content-Type: application/json' \
  --data '{
	"accountId": "<account_id>"
}'

Buscando wallet por id

curl --request GET \
  --url http:https://localhost:8000/v1/wallet/<id>

Enviar trasação de deposit, purchase ou withdraw

curl --request POST \
  --url http:https://localhost:8000/v1/wallet/<wallet_id>/transactions \
  --header 'Content-Type: application/json' \
  --data '{
	"type": "deposit",
	"value": 100
}'

Listar extrato (history)

curl --request GET \
  --url 'http:https://localhost:8000/v1/history?walletId=<wallet_id>&createdAtStart=2023-07-19&createdAtEnd=2023-07-23'

Buscar history por id

curl --request GET \
  --url http:https://localhost:8000/v1/history/<history_id>

Buscar transaction por id

curl --request GET \
  --url http:https://localhost:8000/v1/transaction/<transaction_id>

Listar transactions

curl --request GET \
  --url 'http:https://localhost:8000/v1/transaction?walletId=<wallet_id>&createdAtStart=2023-07-19&createdAtEnd=2023-07-23'

Enviar cancelamento

curl --request POST \
  --url http:https://localhost:8000/v1/transaction/cancel/<transaction_id>

Enviar estorno

curl --request POST \
  --url http:https://localhost:8000/v1/transaction/reverse/<transaction_id>

Listar auditoria

curl --request GET \
  --url http:https://localhost:8000/v1/audit

Testes

Para os testes é necessário passar algumas variáveis ambiente para conexão com PostgreSQL e MongoDB, mas já enviei preenchidas. Estes são encontrados em services/*/.env . Não é correto enviar as secrets - mas por ser um projeto challenge acabei enviando.

DB_TEST_HOST=localhost
DB_TEST_USER=admin
DB_TEST_PASSWORD=admin
DB_TEST_DATABASE=transaction
MONGO_URL_TEST=mongodb:https://admin:example@localhost/db_audit?authSource=db_audit

Account

make test-account

Transaction

make test-transaction

Tecnologias

  • Docker
  • NestJS
  • Apache Kafka
  • PostgreSQL
  • MongoDB
  • Kong API-Gateway
  • TypeORM

Escolhas técnicas

Clean code

Procurei ao máximo deixar as classes e métodos com atribuições únicas e com escopo reduzido, com apenas uma única funcionalidade e objetivo. O NestJs contém um pattern que contribui para esta premissa.

Microservice

Arquitetura escolhida pela escabilidade, modularidade, elasticidade, tolerância a falhas, testabilidade e confiabilidade.

Apache Kafka

Garantia de entrega: O Kafka oferece segurança na entrega de mensagens, evitando perdas de dados e garantindo consistência.

Escalabilidade: Mesmo num projeto pequeno como este, o Kafka possibilita o crescimento do sistema de forma ágil e eficiente, suportando maior volume de dados conforme necessário.

Integração e Flexibilidade: Com APIs e suporte a várias linguagens, o Kafka se integra facilmente a diferentes componentes e tecnologias, oferecendo flexibilidade para a evolução do projeto.

Kong Api-Gateway

Uma Api-Gateway entrega muitas vantagens, neste pequeno projeto serve para direcionar as requests para o microservice adequado, mas de uma maneira geral, contém diversas vantagens, como: suporte a plugins, balanceamento de carga e estabilidade, rate limiting e throttling, suporte a vários protocolos e escalabidade.

Mongo

No contexto do projeto, o MongoDB foi uma escolha estratégica como banco de dados para a auditoria das transações. Sua natureza NoSQL permitiu armazenar esses registros de forma flexível, adaptando-se às mudanças nos dados ao longo do tempo sem interrupções no fluxo da aplicação.

Event-Driven

Trabalhar com microservices pode ser muito complexo dependendo do domínio da aplicação. Um dos grandes problemas desta arquitetura são as chamadas síncronas entre serviços, que podem gerar lentidão no sistema como um todo ou falharem devido a problemas de rede. Event-Driven é descrito por Mark Richards e Neal Ford em Fundamentals of Software Architecture: An Engineering Approach como uma arquitetura. Nesta arquitetura, cada transaction gera um evento e este será usado por outra ação que também irá gerar um evento e assim por diante.

Devido a esta característica, microservices "casam" bem como uma arquitetura baseada em eventos, pois os erros de rede são drasticamente diminuídos e tudo acontece de forma assíncrona.

Swagger

A documentação Swagger está divida entre os microserviços:

Account

Swagger Account

Transaction

Swagger Transaction


Made by

About

Digital wallet project

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages