001 — Importar fatura do cartão de crédito (registrar cartão, anexar fatura, pagar)
A gente sobe a fatura mensal do cartão compartilhado (Nubank, ou qualquer outro). Sistema registra a conta na primeira vez, anexa a fatura com os gastos do período, e permite marcar como paga depois.
Scenario: Importar a primeira fatura do cartão
Section titled “Scenario: Importar a primeira fatura do cartão”- Given ainda não temos nenhuma fatura cadastrada no cartão Nubank (fechamento dia 25, vencimento dia 10)
- When a gente sobe a fatura de maio/2026 com 3 transações somando R$ 4.500 (fechou 25/05, vence 10/06)
- Then o cartão Nubank fica registrado
- And a fatura de maio/2026 fica anexada ao cartão, no estado
closed(PDF é pós-fechamento) - And o total da fatura é R$ 4.500
- And as 3 transações aparecem na fatura
Scenario: Importar a fatura seguinte preserva as anteriores
Section titled “Scenario: Importar a fatura seguinte preserva as anteriores”- Given o cartão Nubank já com a fatura de maio/2026 importada
- When a gente sobe a fatura de junho/2026 do mesmo cartão
- Then o cartão lista as duas faturas, ordenadas por período (maio antes de junho)
- And cada fatura preserva seu próprio total e suas próprias transações
Scenario: Pagar uma fatura tira ela do atraso
Section titled “Scenario: Pagar uma fatura tira ela do atraso”- Given a fatura de maio/2026 vencendo em 10/06, no estado
closed - When a gente marca a fatura como paga em 10/06/2026
- Then a fatura fica no estado
paid - And mesmo depois do vencimento (11/06) a fatura não conta como em atraso
Modelo
Section titled “Modelo”- Shared Kernel —
Money,BillingDay,Period(ano+mês). Primitivos financeiros reusados entre contexts. Hoje moram embudget/; precisam migrar prashared-kernel/na fase de implementação. - Aggregate Root —
Account(nome,kind: CreditCard,currency,cycle: CardCycle, lista deInvoice). Polimorfismo via composição quando apareceremChecking/Wallet. - Entity —
Invoice(period,closedAt,dueDate,status: closed | paid,transactions). Identidade natural via(account, period).isOverdue(now)é derivado, não armazenado. - Value Objects —
AccountName,CardCycle (closingDay, dueDay),TransactionDescription,Transaction (date, amount, description).
Fora de escopo
Section titled “Fora de escopo”- PDF parsing (adapter; spec recebe
Transaction[]já parseado). - Reconciliação com
RecurringExpensedo Budget (Netflix duplicado em ambos). - Atribuição de transação por Member.
- Estado
openda fatura (só faz sentido com integração ao vivo no Nubank). - Estado
overduearmazenado (é derivado). - Pagamento parcial, juros, multas.
- Rejeição de fatura duplicada (idempotência por natural key) — happy path só.
Próximo passo
Section titled “Próximo passo”Mover Money e BillingDay pra shared-kernel/, criar Period, implementar context accounts/ até os 3 scenarios passarem.