Beatriz Tavares
Submitted on Oct 17, 2026, 8:03 AM
Evaluated on Oct 17, 2026, 8:13 AM
The score is an AI recommendation; the decision is yours.
Evaluation
Final score = 70% diagram + 30% defense of the follow-up questions.
Scores by dimension
Strengths
- Tratamento robusto de idempotência com chave única composta (purchase_id, entry_type) no ledger append-only e atualização atômica da projeção de saldo na mesma transação.
- Excelente estratégia para lidar com eventos fora de ordem, persistindo estornos pendentes que reconciliam no momento em que a confirmação correspondente chega.
- Mecanismo de resgate em duas fases (reserva com TTL e confirmação) garantindo atomicamente via condição no banco que o saldo nunca fique negativo.
- Desacoplamento assíncrono bem implementado via Kafka particionado por customer_id, protegendo o fluxo de pagamento e mantendo ordenação por cliente.
- Isolamento de leituras do extrato em réplica de leitura e reconciliação diária em lote para auditoria e governança financeira.
Suggestions
- Considere utilizar eventos do Kafka ou cache invalidation via pub/sub para mudanças de campanhas em vez de polling a cada 30 segundos, reduzindo latência de atualização e consultas redundantes ao banco.
- Para estornos parciais múltiplos da mesma compra, avalie registrar cada reembolso com um identificador do evento de reembolso (refund_id) além do purchase_id para suportar mais de um estorno parcial sem colisão de chave.
Integrity signals
Recorded by the candidate's browser during the design and the defense. They are signals to review, not proof: a second monitor, a notification or pasting one's own notes also create records. And no records doesn't rule anything out, because another device, such as a phone, doesn't show up. These records don't change the score.
No tab exits, pastes or statement copies were recorded.
Diagram and explanation
On a phone the diagram is shown smaller. You can pinch to zoom, but it reads better on a computer.
Candidate's explanation
Fluxo de crédito: o sistema de pagamentos publica purchase.confirmed e purchase.refunded num tópico Kafka particionado por customer_id, então todos os eventos de um cliente são processados em ordem por um único consumidor. O pagamento nunca espera o cashback. Idempotência: o ledger é append-only com UNIQUE (purchase_id, entry_type). Evento repetido bate na constraint e é descartado. O saldo é uma linha por cliente atualizada na MESMA transação do lançamento, então ledger e saldo nunca divergem. Fora de ordem: se o reembolso chega antes da confirmação, gravo um estorno pendente. Quando a confirmação chega, o consumidor vê o estorno e credita só a diferença (reembolso parcial) ou nada. Regras: as campanhas ficam no Postgres e o motor de regras recarrega a cada 30 s, sem deploy. O lançamento guarda o id e a versão da regra aplicada, para auditoria e para o estorno usar o mesmo percentual. Tetos mensais são checados contra a soma do mês no ledger. Resgate: o checkout chama reservar (UPDATE saldo - valor WHERE saldo >= valor, com uma reserva com TTL de 15 min) e depois confirmar ou cancelar. Isso garante saldo nunca negativo sem lock longo. Leitura: saldo vem da tabela de saldos (chave primária, p95 baixo) e o extrato de uma réplica de leitura, paginado por data. A réplica pode atrasar alguns segundos, o que cabe no SLA de 1 minuto. Operação: eventos que falham 5 vezes vão para a DLQ com alerta. Um job diário compara o ledger com o relatório do sistema de pagamentos e abre correção para divergências. Na Black Friday, 400 eventos/s cabem em 12 partições com folga; o lag do consumidor é a métrica de alerta.
Defense questions
1. Sua estratégia de idempotência utiliza a restrição UNIQUE (purchase_id, entry_type) no ledger. Como sua modelagem suporta múltiplos reembolsos parciais legítimos de uma mesma compra sem que os eventos subsequentes colidam nessa restrição e sejam descartados incorretamente?
A constraint como escrevi quebraria no segundo reembolso parcial. A chave certa é o id do evento de origem: o crédito usa UNIQUE (purchase_id, 'credit'), porque só existe um por compra, e cada estorno usa UNIQUE (refund_id), que o sistema de pagamentos manda em cada reembolso. O estorno guarda purchase_id e refund_id e vale cashback creditado × (valor reembolsado / valor da compra), limitado ao que ainda não foi estornado. Evento repetido do mesmo reembolso continua batendo na constraint.
Answer review9.5
A resposta identificou com precisão a falha da constraint inicial e redefiniu a chave de idempotência para o refund_id em estornos parciais, além de apresentar a fórmula proporcional correta para o cálculo do valor. Demonstrou domínio técnico claro ao separar o ciclo de vida do crédito e dos múltiplos reembolsos.
2. Para validar o teto mensal por cliente, você propôs calcular a soma do mês diretamente no ledger durante o consumo do evento. Sob o pico de 400 compras/s na Black Friday, qual é o impacto desse aggregate (SUM) na latência das transações do Postgres e como você otimizaria esse controle de cota?
Um SUM no ledger a cada evento seria uma varredura por cliente dentro da transação e não escala no pico. Mantenho um contador por (customer_id, mês) atualizado na mesma transação do lançamento: UPDATE ... SET total = total + x WHERE total + x <= teto; se não afetar linha, credito só o que ainda cabe. Como o tópico é particionado por customer_id, um único consumidor escreve cada linha, então não há disputa de lock; o custo vira um UPDATE por chave primária. O SUM no ledger fica só para a reconciliação diária conferir o contador.
Answer review9.5
A resposta substituiu corretamente a agregação custosa por um contador materializado por cliente e mês atualizado via chave primária. Também aproveitou de forma consistente o particionamento do Kafka por customer_id para justificar a ausência de contenção de locks concorrentes.
3. Ao receber um evento de reembolso antes da confirmação da compra (out-of-order), como o consumidor sabe o valor exato de cashback a estornar ou reter se as categorias dos produtos comprados e a versão da regra de campanha aplicada ainda não estão registradas no seu banco?
Nesse momento o consumidor não calcula nada: grava o reembolso numa tabela de pendências (purchase_id, refund_id, valor) e confirma o offset. Quando a confirmação chega, ela traz itens e categorias; calculo o cashback com a versão da campanha vigente na data da compra (as campanhas são versionadas com início e fim de vigência), credito e aplico as pendências na mesma transação, então o cliente nunca vê um crédito que já deveria ter sido estornado. Pendência sem confirmação depois de 7 dias é tratada pela reconciliação com alerta.
Answer review9.5
A estratégia de persistir o reembolso como pendência e adiar o cálculo até a chegada do evento de confirmação com os itens resolve elegantemente a falta de contexto. O uso da vigência temporal da campanha e a cobertura de pendências órfãs via reconciliação com TTL fecham o ciclo de consistência sem lacunas.