Beatriz Tavares
Enviado el 17 oct 2026, 8:03
Evaluado el 17 oct 2026, 8:13
La nota es una recomendación de la IA; la decisión es tuya.
Evaluación
Nota final = 70% diagrama + 30% defensa de las preguntas.
Notas por dimensión
Fortalezas
- 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.
Sugerencias
- 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.
Señales de integridad
Registradas por el navegador del candidato durante el diseño y la defensa. Son señales para revisar, no prueba: un segundo monitor, una notificación o pegar las propias notas también generan registros. Y la ausencia de registros no garantiza nada, porque otro dispositivo, como un celular, no aparece. Estas señales no cambian la nota.
No se registró ninguna salida de la pestaña, texto pegado ni copia del enunciado.
Diagrama y explicación
En el celular el diagrama se ve reducido. Puedes hacer zoom con dos dedos, pero se lee mejor en la computadora.
Explicación del candidato
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.
Preguntas de defensa
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.
Evaluación de la respuesta9.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.
Evaluación de la respuesta9.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.
Evaluación de la respuesta9.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.