API desenvolvida com o objetivo de simular um sistema bancário simplificado, com funcionalidades de transferência entre usuários.
- PHP 8.3
- Laravel 12
- Postgres
- RabbitMQ
- Docker + Docker compose
- Swagger
Clone o repositório do projeto
git clone https://github.com/Philipelima/bank-api.git
Suba os containers:
docker compose up -d
Acesse o container da aplicação
docker exec -it simple-bank_app bash
Dentro do container, instale as dependências
composer install
Gere a key da aplicação
php artisan key:generate
Gere a documentação Swagger
php artisan l5-swagger:generate
Configure o arquivo .env:
DB_CONNECTION=pgsql
DB_HOST={db_host}
DB_PORT={db_port}
DB_DATABASE={db_name}
DB_USERNAME={db_username}
DB_PASSWORD={db_password}
...
QUEUE_CONNECTION=rabbitmq
...
RABBITMQ_HOST={rabbitmq_host}
RABBITMQ_PORT={rabbitmq_port}
RABBITMQ_USER={rabbitmq_user}
RABBITMQ_PASSWORD={rabbitmq_password}
RABBITMQ_QUEUE={rabbitmq_queue}
Se tudo estive okay, a api está disponivel no seguinte endereço:
http://localhost:8000
E a documentação em:
http://127.0.0.1:8000/api/documentation
-
Usuários do tipo lojista não podem enviar transferências.
-
Transferências exigem saldo suficiente e validação externa de autorização.
-
Lojistas só recebem transferências, não enviam dinheiro para ninguém.
O sistema utiliza um modelo relacional composto por três principais entidades:
users
Armazena os dados dos usuários da banco, podendo ser usuários comuns (common
) ou lojistas(merchant
), através do campo user_type.
transfers
Registra todas as transferências realizadas entre usuários.
balance_history
Responsável por registrar todo o histórico de movimentações de saldo dos usuários.
Uso de UUIDs em vez de IDs autoincrementais foi adotado para garantir unicidade global e segurança, dessa forma podemos evitar que a previsibilidade dos IDs, evitando ataques com enumeração de recursos da api.
Considerando a possibilidade do sistema evoluit para uma arquitetura distribuida, o uso de uuid evita problemas de conflitos em sistemas de microserviços ou multiplos bancos.
O campo authorization_code foi adicionado para registrar um identificador único da autorização da transação. Esse código serve como uma evidência da autorização emitida por um serviço externo, permitindo rastreabilidade e auditoria de cada transferência realizada.
O campo failed_reason foi adicionado à tabela de transações com o objetivo de armazenar a razão pela qual uma transferência não foi concluída com sucesso. Isso pode ser útil para fins de auditoria, monitoramento, e para oferecer transparência ao usuário sobre falhas ocorridas.
Toda Transação inicia-se com o status de pending já no incio do processamento, podendo finalizar em
completed
oufailed
(em caso de falha).
O padrão Chain of Responsibility foi utilizado para organizar o processo de transferência em etapas desacopladas e sequenciais. Isso facilita a manutenção, torna o código mais legível e permite adicionar novas regras de negócio com pouca intervenção no código existente. Além disso, permite aplicar o princípio do fail fast, abortando o fluxo assim que uma validação falha.
O RabbitMQ foi escolhido por oferecer maior confiabilidade no tratamento de mensagens, com suporte à persistência, o que garante que nenhuma notificação seja perdida mesmo diante de falhas temporárias no consumidor. Além disso, o RabbitMQ proporciona mais controle sobre reentregas e confirmações de leitura, permitindo uma arquitetura mais resiliente, escalável e alinhada com boas práticas de sistemas distribuídos.
Para o envio de notificações, foi adotado o padrão de projeto Strategy. Essa decisão visa garantir flexibilidade, organização e facilidade de manutenção, permitindo que diferentes canais de notificação (como e-mail, SMS ou push) sejam implementados de forma isolada, respeitando o princípio da abertura para extensão e fechamento para modificação (OCP).
Dessa forma, o sistema pode crescer de forma sustentável, facilitando a adição de novos canais sem impactar os já existentes, promovendo também uma melhor testabilidade e separação de responsabilidades entre os componentes.
Para a documentação da API, foi utilizado o Swagger, permitindo que qualquer alteração no código seja rapidamente refletida na documentação, promovendo um alinhamento contínuo entre a implementação e sua descrição.
Para acessar a documentação após rodar o projeto, basta acessar:
http://127.0.0.1:8000/api/documentation
- Adição de testes automátizados para verificação do fluxo da aplicação
- Monitoramento de métricas e alertas com Prometheus + Grafana
- Implementação de logs estruturados para facilitar a rastreabilidade
- Uso de DTOs do controller para o service;
- Implementação de cache em rotas com alto volume de leitura, reduzindo carga no banco de dados e melhorando a performance das respostas da API (ex: uso de cache com Redis ou memcached)
- Adição de idempotency Key na request de transferencia;