Demo with fictional candidates

Request a free pilot
← Back to the ranking

Diego Moraes

diego.moraes@example.comEvaluated

Submitted on Oct 17, 2026, 8:51 AM

Evaluated on Oct 17, 2026, 9:00 AM

The score is an AI recommendation; the decision is yours.

Evaluation

Final score
7.3
Diagram
6.8
Defense
8.5

Final score = 70% diagram + 30% defense of the follow-up questions.

Scores by dimension

Reliability30%5.5
Data Modeling25%6.5
Async & Decoupling20%7.5
Trade-Offs15%5.5
Scalability10%7.0

Strengths

  • Uso adequado de mensageria (Kafka) desacoplando o processamento assíncrono do sistema de pagamentos externo.
  • Separação das regras de campanha em banco relacional com cache no Redis com TTL curto, permitindo alterações dinâmicas pelo marketing sem necessidade de deploy.
  • Adoção de abordagem append-only de lançamentos/transações para compor o histórico financeiro do cliente.

Weaknesses

  • Tratamento de concorrência e chave de unicidade incompatível: foi afirmado que a tabela de transações possui `purchase_id` único, mas logo em seguida é dito que reembolsos gravam um registro com o mesmo `purchase_id`. Se a restrição única for estrita no `purchase_id`, o estorno falhará por colisão de chave primária/única.
  • Falha em lidar com desordem de eventos (out-of-order delivery): a restrição explicitou que um reembolso pode chegar antes da confirmação da compra, mas o fluxo não descreve como tratar essa inversão cronológica sem gerar inconsistência ou falha de processamento.
  • Condição de corrida no resgate: a validação de saldo seguida de inserção direta no checkout sem bloqueio atômico ou mecanismo de reserva (pessimistic lock, compare-and-swap ou chave de idempotência com saldo condicional no banco) permite que requisições concorrentes deixem o saldo negativo, violando o NFR.

Suggestions

  • Modelar a chave de idempotência composta (ex: `purchase_id` + `event_type` ou `operation_id`), permitindo registrar tanto a compra quanto eventuais reembolsos parciais ou totais para o mesmo pedido.
  • Armazenar um saldo materializado na carteira com verificação atômica (`UPDATE wallet SET balance = balance - amount WHERE balance >= amount`) ou padrão de reserva durante o checkout para garantir atomicidade sob concorrência.
  • Inverter o fluxo no diagrama onde o Redis consulta o Postgres: caches não buscam dados sozinhos; deve ser o 'Serviço de carteira' que busca no banco em caso de cache miss e popula o Redis (padrão Cache-Aside).
  • Definir uma Dead-Letter Queue (DLQ) para mensagens que falharem repetidamente no cálculo ou persistência de regras de cashback.

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.

  • Left the tab or window 1× for 12 s in total.

Timeline

Time counted from the start of each step.

  1. Design 19:10Left the tab for 12 s

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

Os pagamentos publicam os eventos de compra no Kafka e um worker consome, calcula o cashback com as regras e grava na tabela de transações com purchase_id único, então se o evento repetir o insert falha e eu ignoro. As regras ficam no Postgres com cache no Redis de 1 minuto, assim o marketing muda sem deploy. Reembolso gera uma transação negativa com o mesmo purchase_id e tipo estorno. Reembolso parcial calcula proporcional ao valor devolvido. O saldo fica no Redis para responder rápido no app. Quando entra transação nova eu invalido a chave e o próximo acesso recalcula somando as transações do cliente. No checkout o serviço de carteira confere o saldo e grava uma transação de resgate negativa. Para a Black Friday escalo os workers horizontalmente pelo número de partições.

Defense questions

  1. 1. Como sua arquitetura lida com a condição de corrida no checkout para garantir que o saldo nunca fique negativo se o cliente tentar realizar dois resgates simultâneos?

    Do jeito que desenhei, o serviço lê o saldo do Redis, então dois resgates ao mesmo tempo podem passar. Eu mudaria para um UPDATE condicional numa tabela de saldo no Postgres: UPDATE saldos SET saldo = saldo - :valor WHERE cliente = :id AND saldo >= :valor. Se não afetar nenhuma linha, o resgate é recusado. É atômico, e o Redis vira só cache de leitura.

    Answer review9.0

    A resposta identifica com precisão a vulnerabilidade da leitura em cache e propõe a solução canônica com UPDATE condicional atômico no banco de dados relacional. Faltou apenas detalhar a reserva temporária versus débito definitivo caso o checkout externo falhe após a dedução.

  2. 2. Você mencionou invalidar a chave do Redis e recalcular o saldo somando todas as transações no Postgres na leitura seguinte; como evitar gargalos no banco e picos de latência (cache stampede) na Black Friday com esse modelo?

    Somar tudo a cada leitura não aguenta a Black Friday. Eu passaria a manter o saldo materializado no Postgres, atualizado na mesma transação do insert, e o Redis com TTL curto. Para o stampede, um lock com SET NX para que só uma requisição recalcule quando a chave expira; as outras leem o valor antigo por alguns segundos.

    Answer review8.5

    A solução resolve com eficiência o gargalo ao materializar o saldo na escrita e adotar bloqueio com SET NX para mitigar o cache stampede. Poderia ter especificado uma estratégia de atualização direta do cache (write-through) para dispensar completamente recálculos síncronos na rota de leitura.

  3. 3. Se um evento de reembolso ou estorno chegar antes da confirmação da compra (fora de ordem), como o worker processará o cálculo proporcional e a persistência sem quebrar a restrição de purchase_id único?

    Eu deixaria a unicidade por (purchase_id, tipo). Se o estorno chega antes, o worker não acha a compra e devolve a mensagem para retry com atraso, até a confirmação chegar e o estorno poder ser calculado.

    Answer review8.0

    A resposta corrige a chave de unicidade para uma restrição composta e adota fila de retry com atraso para aguardar a confirmação da compra. Deixou de contemplar o tratamento com Dead Letter Queue caso a compra de origem nunca chegue ou seja cancelada.

Want to see your own candidates ranked?

The pilot is free: 1 process with up to 10 candidates, no credit card. Sign up with your work e-mail; we review the request and unlock the pilot.