Vibe coding para retomar onboarding de onde parou: o marcador que faltava
Campo vazio no banco não prova que a tela nunca foi aberta. O bug que apareceu na tela 11 do Fumava e as 2 horas que evitaram uma migração.
Um campo vazio no banco não prova que a pessoa nunca passou por aquela tela. Prova só que ela não escreveu nada ali. Quem usa o primeiro fato para deduzir o segundo abre um buraco no produto, e o buraco tem sempre o mesmo formato: alguém fecha o aplicativo no meio do caminho, abre de novo e recomeça do zero.
Foi o que apareceu no onboarding do Fumava, o app de parar de fumar que Martin está construindo ao vivo, na live em que o banco ficou de pé e as 6 primeiras telas chegaram ao emulador. Ninguém foi atrás desse bug. O agente testava outra coisa, voltou algumas telas, avançou de novo e a tela veio em branco, com o botão de continuar apagado. O dado estava salvo. A tela é que não leu que já tinha sido respondida.
A tela em branco, e o que ela custava de verdade
Voltar telas dentro da sessão era só o jeito mais fácil de enxergar o problema. O agente descreveu o estrago que importava:
"Se a pessoa fechar o app na tela 11 e abrir de novo, ela começa na tela um com tudo em branco."
O produto tinha a regra escrita desde o começo, o onboarding retoma de onde parou, e o código não tinha essa regra em canto nenhum. O diagnóstico saiu na frase seguinte:
"Eu escrevi a regra e não implementei."
Essa é a distância entre um documento de produto e um app instalado no celular de alguém. A regra existia no papel, a leitura que a tornaria real nunca foi escrita, e nada no uso normal denunciava a falta, porque dentro de uma mesma sessão a memória em cima do banco cobria o rombo. Isso aparece também em vibe coding para pedir segunda opiniao de ia sobre o projeto.
Com 6 telas o conserto custa 2 horas; com 21 ele vira migração
O agente não empurrou o problema para frente nem tratou como incêndio. Disse que com o número de telas de hoje ninguém fecha o app no meio, mas que com o total planejado alguém fecha, e colocou 2 caminhos na mesa: parar agora, gastar as 2 horas estimadas e fazer com que as telas seguintes já nascessem certas, ou seguir construindo e resolver quando o onboarding estivesse inteiro. Quem decidiu foi o builder:
"Então já conserta isso agora e daí a gente já faz certo pra frente, tá?"
A conta vale para qualquer fluxo em etapas. São 6 telas prontas e 21 planejadas. Cada tela nova construída sobre a suposição errada nasce com o mesmo defeito, então o custo não fica parado nas 2 horas, ele cresce por tela. E quando o defeito é sobre o que ficou gravado, adiar troca uma refatoração por uma migração de dado já coletado, mais a pergunta chata de o que fazer com quem entrou pela versão quebrada.
O marcador de passagem é um fato à parte
O conserto exigiu uma coluna nova cuja única função é dizer que a tela foi vista. O motivo, na fala do agente:
"Sem o marcador explícito, quem pula o nome ficaria preso nele para sempre. A retomada acharia que a tela nunca foi vista."
"Esta tela foi vista" e "este campo tem valor" são 2 fatos diferentes. Todo fluxo que guarda só o segundo perde o primeiro exatamente nas telas em que os 2 divergem, e são mais do que parecem: a tela opcional que a pessoa pulou fica indistinguível da tela que ela nunca abriu, e a tela que só mostra informação também. Quem pulasse a pergunta do nome ficaria preso na pergunta do nome em toda reabertura, para sempre, porque o app iria procurar um valor que essa pessoa decidiu não dar.
O efeito colateral foi coerente com isso: a última tela do onboarding não coleta nada, e passou a marcar passagem também. Uma tela que só informa ainda precisa registrar que informou.
Marcar a passagem, porém, só resolve metade: o app ainda precisa saber qual é a próxima tela depois da última marcada. E isso depende de como a sequência está escrita no código. Se cada tela souber apenas para onde ela mesma aponta, a ordem fica espalhada por 21 arquivos e retomar vira adivinhação; manter uma lista única de telas em vez de tela apontando pra próxima transforma "onde a pessoa parou" numa busca por índice nessa lista, e não numa caçada pela cadeia de ponteiros. O mesmo problema apareceu em vibe coding para nao mostrar a tela de quem parou no caminho de quem reduz.
O teste que revela o buraco, e por que ele escapa no vibe coding
Cadastro em etapas, checkout, formulário longo, verificação de documento. Qualquer fluxo que a pessoa possa abandonar no meio e retomar depois carrega a mesma armadilha, e ela é sedutora porque a leitura por campo preenchido funciona nos primeiros dias, quando toda tela guarda alguma coisa obrigatória. A primeira tela opcional que entra no fluxo já quebra a dedução, e quem construiu rápido não tem motivo para desconfiar.
O teste é barato. Percorra o fluxo até o meio, feche o aplicativo de verdade, deslize para fora dos recentes, abra de novo. Voltar telas dentro da sessão não serve, porque a memória da sessão pode estar mostrando um progresso que o banco não conhece — é por isso que testar a retomada matando o app de verdade é o único jeito de saber se o fluxo volta mesmo de onde parou. Foi assim que o agente confirmou o conserto: matou o app numa tela do meio e ele reabriu na seguinte, com o campo já preenchido.
Essa disciplina de fechar tudo e voltar é o que separa quem faz vibe coding de quem só faz o app rodar na própria máquina. Vale notar o paralelo com o checklist de retomada no vibe coding: lá quem retoma é o builder, que anota no fim da sessão o passo a passo para religar o ambiente no dia seguinte; aqui quem retoma é o usuário dentro do produto. Mesma palavra, 2 sujeitos, e os 2 quebram pelo mesmo motivo, que é ninguém ter escrito o que já foi feito. Foi o mesmo caminho de vibe coding para deixar usuario corrigir escolha do onboarding.
Se você está construindo um fluxo de várias etapas agora, abra o esquema do banco e procure a coluna que diz que a etapa foi concluída. Se a resposta for que dá para saber pelos campos preenchidos, você tem o mesmo bug, e ele ainda está barato: escreva o marcador de passagem antes da próxima etapa entrar, faça toda etapa gravar esse marcador mesmo quando não coletar nada, e teste matando o aplicativo no meio do caminho. A live inteira desse conserto está em assistir à live.