O card de revisão do vault que nunca rotacionava
O Greenhouse tem um card diário “Rescue or Keep” para a coisa mais antiga parada no vault. Rescue faz sentido, ele puxa o item de volta para fora. Keep devia ser a outra resposta válida: deixa quieto, já olhei para isso, me pergunta de novo depois. Só que “depois” nunca chegava. Encontrei o bug enquanto trabalhava num issue vizinho, e é um bom exemplo de um comentário mentindo para mim durante semanas antes de alguém pegar isso.
A lógica de escolha é determinística de propósito: ordena todos os itens no vault por quanto tempo estão dormentes, e a revisão diária mostra o mais antigo. É um design razoável. O problema era o que “Keep” de fato fazia com essa escolha. Tinha um comentário bem ao lado explicando que clicar em Keep dispensa o card e a escolha “muda naturalmente (amanhã).” Li esse comentário, acreditei, e segui para o próximo issue. Está errado. Keep não escrevia nada no banco de dados. Ele definia um pedaço de estado no componente Svelte e considerava resolvido. O card sumia pelo resto daquela sessão porque um id do lado do cliente era marcado como dispensado, mas a query por trás nunca mudava. Recarregue o app, ou volte no dia seguinte, e o mesmo item exato ganha de novo a disputa de “mais dormente.” Para sempre. Todo outro item no vault simplesmente… nunca era revisado.
A correção acabou sendo uma única coluna anulável. Adicionei last_reviewed_at na tabela de itens, separada de vaulted_at. Essa separação importou mais do que eu esperava enquanto escrevia: vaulted_at é a base da ordenação por dormência, então se o Keep tivesse mexido nessa coluna, teria resetado o relógio de dormência do item e começado a corromper exatamente a ordenação de que a revisão depende, a mesma armadilha que o design original do Keep evitou ao não chamar o comando de vault de novo. Duas perguntas diferentes, duas colunas diferentes: “há quanto tempo isso está no vault” e “quando foi a última vez que olhei para isso e decidi deixar quieto.”
Com a coluna nova no lugar, a escolha diária ganhou mais um filtro: pula qualquer coisa revisada dentro da cadência configurada, e então pega o item mais antigo do que sobrou. Keep agora faz uma chamada de verdade ao backend, e a flag de dispensa do lado do cliente em que eu estava confiando simplesmente deixa de existir, comentário e tudo.
A parte para a qual eu continuo voltando é que esse bug era invisível em todo sentido óbvio. Sem crash, sem erro, sem teste falhando. O card se comportava exatamente como o comentário dizia que se comportaria, dentro de uma única sessão. Você só notaria que algo estava errado se continuasse usando o app por vários dias e começasse a se perguntar por que a revisão do vault ficava mostrando a mesma ideia de música dormente de três semanas atrás. Que foi exatamente como isso acabou sendo reportado.
Lição que levo desse aqui: um comentário que explica por que o comportamento atual está correto é uma afirmação, não um fato, e precisa da mesma desconfiança que o código em si merece. “Muda naturalmente amanhã” soa como uma afirmação sobre o sistema. Na verdade era uma afirmação sobre a intenção de alguém para o sistema, que nunca chegou a ser construída.
Leitura relacionada
Corrigindo uma race, um bug da tecla Esc e um crash de chave duplicada no Greenhouse
Um contador monotônico para refreshes fora de ordem, um evento de diálogo cancelável no Esc, e um crash de chave duplicada no mesmo segundo.
O bug que meus testes unitários jamais poderiam ter encontrado
Um quadro kanban renderizava uma prop que ficava obsoleta com dados novos, e todo teste mockado passava porque um mock não consegue expressar isso.
O callback que não conseguia dizer o que aconteceu
Corrigir um bug de atualização do dashboard expôs um segundo escondido no mesmo componente compartilhado, e um terceiro bug que no fim não existia.
Você também pode achar útil
Proton Mail
E-mail criptografado de ponta a ponta, com arquitetura de acesso zero.
Como parceiro da Proton, ganho com compras qualificadas dos serviços de privacidade e segurança da Proton (Pass, Mail, VPN, Drive).
Saiba maisProton Pass
Gerenciador de senhas focado em privacidade, da equipe por trás do Proton Mail.
Como parceiro da Proton, ganho com compras qualificadas dos serviços de privacidade e segurança da Proton (Pass, Mail, VPN, Drive).
Saiba maiseSIM Airalo
eSIM de dados local para viagens - sem necessidade de trocar um SIM físico.
Este é meu link de indicação da Airalo. Você recebe um desconto no seu primeiro eSIM e eu ganho crédito da Airalo para o meu.
Saiba mais