<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Daniel Porto</title>
    <description>The latest articles on DEV Community by Daniel Porto (@trainedloop).</description>
    <link>https://dev.to/trainedloop</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3934979%2Fc8e71d7a-1711-47e5-ae14-b006e44d6309.png</url>
      <title>DEV Community: Daniel Porto</title>
      <link>https://dev.to/trainedloop</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/trainedloop"/>
    <language>en</language>
    <item>
      <title>Diário de dev #3: o bug que só aparece quando alguém usa</title>
      <dc:creator>Daniel Porto</dc:creator>
      <pubDate>Mon, 08 Jun 2026 21:35:21 +0000</pubDate>
      <link>https://dev.to/trainedloop/diario-de-dev-3-o-bug-que-so-aparece-quando-alguem-usa-117p</link>
      <guid>https://dev.to/trainedloop/diario-de-dev-3-o-bug-que-so-aparece-quando-alguem-usa-117p</guid>
      <description>&lt;p&gt;No trabalho, nenhum código mudou. O que mudou foi a forma como os clientes inserem os dados. E isso quebrou coisas que nenhum teste existente pegou.&lt;/p&gt;

&lt;h2&gt;
  
  
  O bug que só aparece quando alguém usa
&lt;/h2&gt;

&lt;p&gt;A motivação pra montar E2E do zero veio de um problema específico.&lt;/p&gt;

&lt;p&gt;Você precisava acessar a aplicação pra quebrar. Não era um erro de lógica isolado que um teste unitário pegaria. Era uma combinação de dados reais num fluxo real produzindo um resultado errado que só aparecia na tela. Os clientes chegavam lá antes da gente.&lt;/p&gt;

&lt;p&gt;É uma categoria de problema que teste de código não resolve, porque o problema não está no código. Está na interação entre o código, os dados e o ambiente. A forma mais rápida de pegar antes é rodar o fluxo completo do jeito que o usuário roda.&lt;/p&gt;

&lt;p&gt;Ficou com smoke tests cobrindo os principais fluxos do produto, configuração pra rodar contra múltiplos ambientes, e notificação no Slack quando o nightly quebra.&lt;/p&gt;

&lt;p&gt;A parte mais útil não são os testes em si. É saber antes do cliente reportar.&lt;/p&gt;

&lt;h2&gt;
  
  
  Autocrop: quando nenhuma ferramenta resolve tudo
&lt;/h2&gt;

&lt;p&gt;Num projeto paralelo que mantenho, passei o fim de semana montando autocrop automático pra imagens.&lt;/p&gt;

&lt;p&gt;A ideia inicial era usar o imgproxy Pro, que tem detecção de objeto embutida. Não ficou preciso o suficiente pra variedade de imagens que eu tinha. Fui pro Rekognition, que retorna bounding boxes. Mais controle, mas bounding box tem um limite: é um retângulo. Objetos não são retângulos.&lt;/p&gt;

&lt;p&gt;Aí descobri o rembg, que faz algo diferente. Em vez de delimitar uma área, ele cria uma máscara pixel por pixel usando uma rede chamada U2Net, treinada pra segmentação de primeiro plano. O resultado foi bem superior — ele recorta o objeto, não uma caixa em torno dele.&lt;/p&gt;

&lt;p&gt;Colocar isso em Lambda foi onde a semana ficou mais lenta. O modelo precisava estar acessível pro processo do Lambda, coloquei em &lt;code&gt;/root&lt;/code&gt;, Lambda não lê de lá. Movi pro &lt;code&gt;/opt&lt;/code&gt;, chmod 755. O NUMBA tentou escrever cache em diretório read-only, defini &lt;code&gt;NUMBA_CACHE_DIR=/tmp&lt;/code&gt;. Depois OOM em imagens maiores, aumentei pra 2048 MB. Cada um levou um ciclo de deploy pra aparecer.&lt;/p&gt;

&lt;p&gt;A pipeline final ficou com critérios de aceite diferentes por camada: rembg com padrão rigoroso primeiro. Se não atingir, Rekognition em paralelo com rembg em critérios mais flexíveis. Se nenhum passar, review manual. Nenhuma abordagem de ML funciona pra 100% dos casos — a arquitetura respeita isso.&lt;/p&gt;

&lt;p&gt;A review UI que construí em cima foi consequência: se o fallback é humano, precisa de interface decente. O fallback virou feature.&lt;/p&gt;




&lt;p&gt;Se quiser o contexto dos anteriores, o &lt;a href="https://dev.to/trainedloop/diario-de-dev-0-o-mes-em-que-eu-deletei-mais-do-que-adicionei-2lg3"&gt;#0&lt;/a&gt; e o &lt;a href="https://dev.to/trainedloop/diario-de-dev-1-o-que-15-minutos-desbloqueou"&gt;#1&lt;/a&gt; estão no dev.to. O #2 foi uma semana mais calma e ficou só no LinkedIn.&lt;/p&gt;

</description>
      <category>devjournal</category>
      <category>testing</category>
      <category>aws</category>
      <category>portuguese</category>
    </item>
    <item>
      <title>Diário de dev #1: o que 15 minutos desbloqueou</title>
      <dc:creator>Daniel Porto</dc:creator>
      <pubDate>Sun, 24 May 2026 03:41:54 +0000</pubDate>
      <link>https://dev.to/trainedloop/diario-de-dev-1-o-que-15-minutos-desbloqueou-1a38</link>
      <guid>https://dev.to/trainedloop/diario-de-dev-1-o-que-15-minutos-desbloqueou-1a38</guid>
      <description>&lt;p&gt;Segunda semana do diário. Se a &lt;a href="https://dev.to/trainedloop/diario-de-dev-0-o-mes-em-que-eu-deletei-mais-do-que-adicionei-2lg3"&gt;anterior&lt;/a&gt; foi sobre um mês inteiro de construir e jogar fora, essa foi mais mundana. Infra que ninguém vê, um projeto pequeno que virou ferramenta pra outra pessoa, e uma noite explorando um problema que ainda não tem resposta.&lt;/p&gt;

&lt;h2&gt;
  
  
  A última milha que ninguém pensa
&lt;/h2&gt;

&lt;p&gt;Alguém do time de marketing me mostrou uma página de evento que tinha construído com IA. Ficou boa. Sério, boa mesmo: cores certas, espaçamento certo, seguindo o design system. Aí veio a pergunta: "como eu coloco isso no ar?"&lt;/p&gt;

&lt;p&gt;Esse gap me pegou de surpresa. O trabalho difícil estava feito. A parte que eu esperaria ser o obstáculo, criar a interface, tinha sido resolvida por alguém sem experiência técnica usando IA. O que travou foi publicar. Um detalhe de infraestrutura que pra qualquer dev é trivial, mas que pra quem nunca mexeu com git ou servidores é uma parede.&lt;/p&gt;

&lt;p&gt;Montei um repo no GitHub Pages onde cada pasta vira automaticamente uma URL em nosso domínio. Faz upload, aparece em dominio.com/nome-do-evento. Quinze minutos de configuração.&lt;/p&gt;

&lt;p&gt;O que me ficou foi pensar em quantas outras pessoas estão nessa situação agora. IA abaixou muito o piso pra criar interfaces, mas a infraestrutura ainda pressupõe conhecimento que a maioria das pessoas não tem e provavelmente não quer ter. O trabalho de dev vai mudando, mas não necessariamente diminuindo. Às vezes vira isso: resolver a última milha pra quem chegou até lá sozinho.&lt;/p&gt;

&lt;h2&gt;
  
  
  A semana que não aparece em nenhum demo
&lt;/h2&gt;

&lt;p&gt;No trabalho foi uma semana de trabalho que ninguém vai mostrar numa apresentação. Infraestrutura, permissões, estado inconsistente.&lt;/p&gt;

&lt;p&gt;Tem uma categoria de bug que eu acho particularmente frustrante: o que não grita. Sem exception, sem mensagem de erro, sem log óbvio. Só um usuário preso num fluxo de login que não avançava e não explicava por quê. Quando você finalmente entende o que estava acontecendo, a solução cabe em três linhas. O difícil foi chegar até lá.&lt;/p&gt;

&lt;p&gt;Além disso, rodou um ciclo de QA mais pesado numa tela complexa do produto, aquele tipo de tela onde o estado vem de vários lugares ao mesmo tempo e as fontes se interferem de formas que só aparecem quando você junta tudo. Tínhamos testes. Não eram suficientes.&lt;/p&gt;

&lt;p&gt;Não é que os testes fossem ruins. É que teste automatizado tende a verificar o que você imaginou que poderia dar errado. QA externo encontra o que você não imaginou. São dois tipos de cobertura diferentes, e essa semana ficou claro de novo que um não substitui o outro.&lt;/p&gt;

&lt;p&gt;O resto foi infra. Esse tipo de trabalho tem um ritmo próprio: você acha que vai ser rápido, descobre que não é, ajusta, testa de novo. Cloud costuma ter pelo menos uma surpresa guardada em algum canto de permissão que você não esperava precisar configurar.&lt;/p&gt;

&lt;h2&gt;
  
  
  Uma noite tentando dar voz a personagens em português
&lt;/h2&gt;

&lt;p&gt;RPGTeller é um engine de livros-jogos que estou construindo. Essa semana queria explorar narração por voz, dar vozes distintas pra cada personagem.&lt;/p&gt;

&lt;p&gt;Comecei pelo Kokoro, uma opção de síntese de voz que roda offline. Tem apelo óbvio pra um projeto assim: sem dependência de API, sem custo por caractere, roda localmente. O problema é que dublagem em português brasileiro ficou robótica demais. Funcional, mas longe de imersiva.&lt;/p&gt;

&lt;p&gt;Migrei pro ElevenLabs. Ficou melhor, suficiente pra eu conseguir atribuir vozes específicas por personagem: uma voz de narrador, outra pra Svetlana, outra pro guerreiro. Dá pra imaginar como vai soar no jogo.&lt;/p&gt;

&lt;p&gt;Mas ElevenLabs é uma API paga por caractere. Antes de seguir por esse caminho, quero saber se consigo qualidade aceitável rodando algo local. Ainda não sei a resposta.&lt;/p&gt;

&lt;p&gt;Não terminei essa exploração. Ainda quero testar mais opções, especialmente coisas que rodam localmente e têm qualidade aceitável em pt-BR. Por enquanto ficou Kokoro ruim, ElevenLabs bom mas online.&lt;/p&gt;




&lt;p&gt;O diário #0 cobriu um mês. Esse cobriu uma semana normal. Se quiser acompanhar os próximos, segue lá.&lt;/p&gt;

</description>
      <category>devjournal</category>
      <category>webdev</category>
      <category>ai</category>
      <category>portuguese</category>
    </item>
    <item>
      <title>Diário de dev #0: o mês em que eu deletei mais do que adicionei</title>
      <dc:creator>Daniel Porto</dc:creator>
      <pubDate>Sat, 16 May 2026 16:00:08 +0000</pubDate>
      <link>https://dev.to/trainedloop/diario-de-dev-0-o-mes-em-que-eu-deletei-mais-do-que-adicionei-2lg3</link>
      <guid>https://dev.to/trainedloop/diario-de-dev-0-o-mes-em-que-eu-deletei-mais-do-que-adicionei-2lg3</guid>
      <description>&lt;p&gt;Decidi começar um diário de desenvolvimento. A ideia é simples: toda semana, olhar pro que eu fiz, escolher o que vale contar, e escrever. Sem fórmula, sem tutorial, só o que aconteceu de verdade.&lt;/p&gt;

&lt;p&gt;Este primeiro é diferente. Estou começando no meio do mês, então vai cobrir os últimos 30 dias. Os próximos serão semanais. Vamos ver se consigo manter o ritmo.&lt;/p&gt;

&lt;p&gt;O mês foi movimentado, mas o que mais me marcou não foi o que eu construí. Foi o que eu decidi jogar fora.&lt;/p&gt;

&lt;h2&gt;
  
  
  O processo de trabalho também precisa de refatoração
&lt;/h2&gt;

&lt;p&gt;No trabalho, foi um mês de coisas que ficam invisíveis mas mudam como o produto evolui.&lt;/p&gt;

&lt;p&gt;A entrega mais concreta foi a integração do PostHog num facade de analytics. Antes, as chamadas pra ferramenta estavam espalhadas pelo código em vários lugares. O problema com isso não é técnico agora, é daqui a seis meses: quando você precisar entender o que está sendo rastreado, ou trocar de ferramenta, ou só auditar o que acontece, você vai ter que caçar chamada por chamada por todo o repositório. Centralizar num facade não resolve nada hoje. Resolve um problema que você vai agradecer no futuro.&lt;/p&gt;

&lt;p&gt;Junto com isso, isolei um módulo que tinha crescido além do que devia. Ele estava pegando dependências de várias partes do sistema e exportando acoplamento pra todo lado. Ficou com fronteira bem definida: o que entra, o que sai. Essas coisas são mais difíceis de fazer do que parecem quando você está dentro do código há meses e já perdeu a noção do que deveria pertencer a quem.&lt;/p&gt;

&lt;p&gt;Mas o que tomou mais tempo foi um problema que eu estava adiando: as instruções que guiam os agentes de IA no nosso processo de desenvolvimento tinham virado um nó. Um arquivo de contexto aqui, uma regra ali, uma instrução que contradiz outra que ninguém mais lembra de onde veio. O resultado não era catastrófico, mas era inconsistente. O mesmo tipo de tarefa produzia resultados com qualidade variável dependendo de como você perguntava e em que ordem.&lt;/p&gt;

&lt;p&gt;Parei e fui desmontar isso. Defini o que cada tipo de agente pode decidir sozinho, o que precisa confirmar antes de avançar, como reporta o que fez. Eliminei o que estava duplicado. A qualidade das entregas ficou mais previsível logo depois.&lt;/p&gt;

&lt;p&gt;Processo precisa de refatoração com a mesma frequência que código. Só que código quebra em prod e te avisa. Processo vai deteriorando devagar e você só percebe quando já tá feio demais pra ignorar.&lt;/p&gt;

&lt;h2&gt;
  
  
  O projeto que nasceu e já quis crescer além do que devia
&lt;/h2&gt;

&lt;p&gt;RPGTeller é um projeto pessoal meu, um engine de livros-jogos narrativos. Comecei do zero há pouco mais de um mês, usando Claude Code e Cursor pesado no desenvolvimento, com agentes rodando em paralelo pra cada parte do trabalho.&lt;/p&gt;

&lt;p&gt;O problema apareceu cedo. Quando você tem vários agentes rodando ao mesmo tempo, precisa de alguma forma de coordenar o trabalho. Qual agente tá fazendo o quê? Qual terminou? O que pode começar agora?&lt;/p&gt;

&lt;p&gt;Minha solução foi construir um orquestrador próprio. Levei dias nisso, servidor, banco de dados pra persistir o estado de cada tarefa, interface pra monitorar tudo em tempo real. Funcionava. Era até satisfatório de usar.&lt;/p&gt;

&lt;p&gt;Aí no fim de abril, o Cursor lançou o &lt;code&gt;/multitask&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Faz exatamente o que eu tinha construído. Identifica as partes independentes do trabalho, cria agentes em paralelo, coordena a execução. Nativamente, em um clique.&lt;/p&gt;

&lt;p&gt;Passei alguns dias tentando justificar por que o meu era melhor. "Mas tem mais controle." "Posso customizar." Até que parei e perguntei honestamente: o que esse orquestrador tem a ver com RPGTeller? Nada. Era infraestrutura pela infraestrutura, e eu estava gastando energia mantendo ela.&lt;/p&gt;

&lt;p&gt;Deletei tudo. Centenas de linhas foram embora num commit só. No lugar ficou uma configuração mínima pro Cursor entender como coordenar os agentes no contexto do projeto.&lt;/p&gt;

&lt;p&gt;Com a coordenação funcionando de verdade, o trabalho no design system acelerou bastante. Mais de quinze componentes auditados e alinhados ao padrão visual nas semanas seguintes, cada um em paralelo, sem conflito, sem overhead de gerenciamento.&lt;/p&gt;

&lt;p&gt;Pode ser que no seu caso não faça sentido jogar fora. Às vezes o que você construiu tem nuances que a ferramenta nativa não cobre, e vale manter. Mas se fizer sentido deletar, não precisa ter dor no coração com isso.&lt;/p&gt;

&lt;h2&gt;
  
  
  Testes que só passam às vezes
&lt;/h2&gt;

&lt;p&gt;Num projeto pessoal de estudos, os testes automatizados tinham um problema que eu ficava adiando resolver: o resultado dependia de quando você rodava.&lt;/p&gt;

&lt;p&gt;Com vários workers em paralelo, os testes brigavam por estado compartilhado. Um criava dados que o outro não esperava encontrar. O resultado era aquele flake clássico, passa agora, falha amanhã, passa de novo. Impossível confiar.&lt;/p&gt;

&lt;p&gt;A correção foi consolidar o ambiente num servidor único compartilhado e criar um estado base comum pra todos os testes partirem do mesmo ponto. A ordem de execução parou de importar. CI voltou a ser confiável.&lt;/p&gt;

&lt;p&gt;Testes flaky são piores do que não ter testes. Pelo menos sem testes você sabe que não tem cobertura.&lt;/p&gt;




&lt;p&gt;Da semana que vem em diante, o diário vai ser semanal. O que você acha da ideia?&lt;/p&gt;

</description>
      <category>devjournal</category>
      <category>webdev</category>
      <category>ai</category>
      <category>portuguese</category>
    </item>
  </channel>
</rss>
