Uma nota é uma coisa que quebrou e a regra que sobrou dela. Curta de propósito: se precisar de mais de trezentas palavras, vira estudo de caso.
Abertas em agosto de 2026, todas de uma vez. As cinco primeiras já existiam enterradas dentro dos estudos de caso, onde ninguém que não abrisse a página inteira ia encontrar. Estão aqui em versão curta, com a origem citada. Daqui para frente é aqui que coisa nova aparece, sem precisar redesenhar nada.
Didata
Infraestrutura
O pooler que trava em vez de falhar
Sete deploys seguidos morreram no timeout de 45 minutos, sem mensagem de erro. A causa era o pooler de transação do Postgres, que é a conexão correta para runtime serverless e a errada para migration: ele não suporta as transações DDL longas do migrate deploy, e o comando trava em vez de recusar.
A URL de runtime e a URL de linha de comando são duas variáveis, não uma. E a mesma variável precisa existir na plataforma e nos secrets da CI, porque a CI roda o mesmo build.
Aumentar o limite de corpo das Server Actions quebrava o build com erro de tipo, e só na infraestrutura da plataforma: o build local não reproduzia. Foram cerca de seis horas de bisect até isolar, e o resultado foi não conseguir aumentar.
Então o limite ficou no default de 1 MB, nenhuma Server Action pode receber arquivo, e todo upload do produto é route handler. Uma regra de arquitetura inteira nasceu de um bug de terceiro que nunca foi resolvido.
Contorno não é desenho. Vale escrever qual dos dois é, porque quem chegar depois não distingue, e um dia o bug some e a regra fica sem motivo.
Dois produtos meus, sobre o mesmo Postgres, com escolhas opostas. O CRM tem 133 policies de row level security sobre 29 tabelas: o banco recusa a linha, aconteça o que acontecer na aplicação. O Didata autoriza na aplicação.
A diferença não é maturidade, é quantas portas existem. O CRM é alcançado por um painel, por um servidor MCP de 70 ferramentas, por páginas públicas com token e por rotinas agendadas. Quatro portas, e a regra escrita em cada uma seria a mesma regra escrita quatro vezes, divergindo na primeira pressa. O Didata tem uma porta.
Conte as portas antes de escolher onde a regra mora. Uma porta, a aplicação basta e custa menos. Mais de uma, a regra desce para o banco, senão ela vira várias.
O modelo devolve uma alternativa por questão e um número de confiança de 0 a 100. Gravar a nota direto acima de um limiar seria trivial, e o sistema não faz: sugerida e confirmada são estados distintos no banco, e o boletim só conta o que o professor confirmou. Inclusive as de confiança alta.
Custa caro em conveniência: uma prova de 30 alunos por 10 questões são 300 leituras para aceitar. A mitigação não foi afrouxar a regra, foi baratear o aceite, com confirmação em lote e uma fila que sobe o que pede atenção. O viés da fila é declarado e pró-cautela: questão sem leitura nenhuma conta como incerta.
Quando a regra dói, a saída é baixar o custo de obedecer, não abrir exceção. A primeira exceção é a que ninguém consegue explicar seis meses depois.
No dia de ligar o painel em produção, as requisições ficavam penduradas para sempre. O framework de RPC do servidor tem dois transportes independentes, e o recurso que eu chamava só tinha registrado um deles. O evento saía e ninguém escutava. Sem erro, sem timeout, sem log.
A correção foi uma linha. O diagnóstico não, porque falha silenciosa não te diz onde procurar, e eu tinha testado os dois lados separados: cada um passava.
Bug de junção não aparece testando as pontas. Antes de migrar treze telas, um teste de fumaça atravessando a pilha inteira, do HTTP até o banco, e uma única vez.