Skip to content

LucasSassi/challenge-nodejs

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

10 Commits
 
 
 
 
 
 
 
 

Repository files navigation

Lions Code Challenge - Sistema de Crédito com Buckets

Solução para gerenciar uma conta de crédito com buckets (principal, juros, tarifas, limite disponível) via CLI.


🏗️ Arquitetura Escolhida

A solução utiliza Clean Architecture com separação em camadas:

src/
├── index.js                    # Ponto de entrada (CLI)
├── application/
│   └── bucket-service.js       # Orquestra operações
├── domain/
│   └── bucket-account.js       # Lógica de negócio
└── infrastructure/
    └── stdin-reader.js         # Leitura de stdin

tests/
└── unit.test.js                # Testes unitários

As 4 Camadas

Camada Arquivo O que faz
Infrastructure stdin-reader.js Ler entrada de stdin
Domain bucket-account.js Lógica financeira pura (sem dependências)
Application bucket-service.js Orquestrar chamadas ao domain
Presentation index.js CLI (coordena tudo)

Benefício: Domain é isolado e testável independentemente.


🛠️ Decisões Técnicas

1. Clean Architecture em Camadas

  • Cada camada tem responsabilidade clara
  • Mudanças em I/O não afetam lógica de negócio

2. ES Modules (import/export)

  • Padrão moderno do JavaScript
  • Configurado em package.json com "type": "module"

3. Sem Dependências Externas

  • Apenas Node.js nativo (módulo readline)
  • Zero vulnerabilidades npm
  • Deploy simples

4. Estado Isolado por Linha

  • Cada linha de entrada cria um novo BucketService
  • Não há vazamento de estado entre simulações

5. Arredondamento Financeiro Correto

  • Todos os valores: Math.round(valor * 100) / 100
  • Evita erros de ponto flutuante

6. Pagamento em Cascata

  • Ordem: feesinterestprincipal
  • Usa Math.min(remaining, bucket) para segurança
  • available-limit = creditLimit - principal (só principal reduz)

⚙️ Como Executar o Projeto

Pré-requisitos

  • Node.js v14 ou superior

Instalação

npm install  # Opcional (sem dependências npm)

Execução

Modo 1: Interativo

node src/index.js
# Cole a linha JSON, pressione Enter 2x (linha vazia termina)

Modo 2: Com pipe (mais simples)

echo '[{"type": "set-limit", "amount": 1000.00}, {"type": "purchase", "amount": 200.00}]
' | node src/index.js

Modo 3: Com arquivo

node src/index.js < input.txt

Exemplo Completo

echo '[{"type": "set-limit", "amount": 1000.00}, {"type": "purchase", "amount": 500.00}, {"type": "fee", "amount": 50.00}, {"type": "interest", "amount": 100.00}, {"type": "payment", "amount": 100.00}, {"type": "payment", "amount": 200.00}]
' | node src/index.js

Saída:

[{"principal":0,"interest":0,"fees":0,"available-limit":1000},{"principal":500,"interest":0,"fees":0,"available-limit":500},{"principal":500,"interest":0,"fees":50,"available-limit":500},{"principal":500,"interest":100,"fees":50,"available-limit":500},{"principal":500,"interest":50,"fees":0,"available-limit":500},{"principal":350,"interest":0,"fees":0,"available-limit":650}]

🧪 Como Rodar os Testes

node tests/unit.test.js

Resultado esperado:

Teste 1: set-limit reseta buckets
✓ PASSOU

Teste 2: purchase aumenta principal
✓ PASSOU

Teste 3: fee aumenta fees
✓ PASSOU

Teste 4: interest aumenta interest
✓ PASSOU

Teste 5: payment aplica em ordem correta
✓ PASSOU

Teste 6: Exemplo completo do desafio
Após set-limit: ✓
Após purchase 200: ✓
Após purchase 300: ✓
Após payment 250: ✓

✓ Todos os testes completados!

Todos os 6 testes passam


💪 Pontos Fortes da Solução

1. Separação de Responsabilidades

  • Domain (BucketAccount) é puro e testável isoladamente
  • Infrastructure (StdinReader) encapsula I/O
  • Application (BucketService) orquestra operações
  • Cada componente tem responsabilidade única

2. Sem Dependências Externas

  • Apenas módulos nativos do Node.js
  • Sem vulnerabilidades npm
  • Rápido e leve

3. Testabilidade Total

  • 6 testes unitários, todos passando ✅
  • Lógica de negócio é 100% testável
  • Sem side effects

4. Corretude Matemática

  • Pagamento em cascata: fees → interest → principal
  • available-limit = creditLimit - principal (fees/interest não afetam)
  • Arredondamento a 2 casas decimais sem erros
  • Math.min() previne overpayment

5. Código Limpo

  • Nomes claros (payment, addFee, getAvailableLimit)
  • Sem comentários desnecessários
  • Funções pequenas e focadas
  • Fácil de entender e modificar

6. Estado Isolado

  • Cada linha é independente
  • Não há vazamento entre simulações
  • Previsível e determinístico

7. Tratamento de Erros

  • Valida tipos de operação
  • Try-catch para erros de JSON
  • Saídas claras em caso de erro

📋 Operações Suportadas

Operação Campo Efeito
set-limit amount Define limite, zera buckets
purchase amount Aumenta principal, reduz available-limit
fee amount Aumenta fees
interest amount Aumenta interest
payment amount Paga (fees → interest → principal)

Saída de cada operação:

{
  "principal": <número>,
  "interest": <número>,
  "fees": <número>,
  "available-limit": <creditLimit - principal>
}

🎯 Resumo

  • ✅ Implementação correta de todas as operações

  • ✅ Estado isolado entre linhas

  • ✅ Arredondamento correto (2 casas decimais)

  • ✅ Arquitetura limpa (Clean Architecture)

  • ✅ Sem dependências externas

  • ✅ 6/6 testes passando

  • ✅ Código limpo e bem estruturado

  • Desenvolvido e estruturado por: Lucas Sassi de Souza | Estudante de Eng. de Software UEPG

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors