image

Acesso para sempre a +2.150 cursos, inglês e IA

84
%OFF
Article image
Daniel Messeder
Daniel Messeder05/10/2026 23:05
Compartilhe

Como entrei em um projeto Go sem saber Go — e usei IA para aprender enquanto desenvolvia

  • #Docker
  • #GitHub
  • #Git
  • #TypeScript
  • #GoLang

Meu nome é Daniel Messeder. Sou estudante de Análise e Desenvolvimento de Sistemas (ADS) e estou construindo minha caminhada na área de desenvolvimento de software. Durante a maior parte do meu tempo de estudo, mantive o foco principal em Java e no ecossistema Spring para o backend, acompanhado por React e TypeScript no frontend. Era nessa zona de conforto acadêmica e de projetos pessoais que eu vinha desenvolvendo minha lógica e praticando os primeiros conceitos da programação.

Tudo mudou quando recebi a oportunidade de atuar como desenvolvedor freelancer no HeluApp — um sistema web real, em produção e evolução contínua, desenvolvido de forma colaborativa por uma equipe engajada.

Ao ingressar no projeto, deparei-me com uma realidade totalmente diferente dos exercícios de curso. O backend do HeluApp é estruturado como um monólito modular organizado por domínios e escrito predominantemente em Go (Golang) — uma linguagem com a qual eu não tinha nenhuma experiência prática anterior. Para completar a stack, o ecossistema envolve PostgreSQL, Docker, Docker Compose, LocalStack (para simular armazenamento S3), APIs REST, WebSockets, migrations SQL, Git e GitHub.

O cenário impunha um desafio imediato: eu não podia dar ao luxo de parar as entregas por três ou quatro meses para estudar Go do zero em um curso teórico para só então começar a contribuir. Eu precisava entregar valor em tarefas reais desde os primeiros dias, aprendendo enquanto o sistema se movimentava.

Foi nesse ponto de inflexão que a Inteligência Artificial entrou na minha rotina. Mas a grande decisão da minha trajetória não foi se eu usaria IA, e sim como eu a utilizaria.

O choque do projeto real: o código não começa do zero

Existe um abismo entre construir um projeto pessoal e entrar em um sistema que já existe. Em um exercício de estudo, quando um requisito se mostra complexo, é tentador refazer toda a arquitetura, renomear tabelas ou mudar a estrutura de pastas. Em um software real mantido por um time, essa liberdade não existe.

No HeluApp, precisei compreender e respeitar regras que já estavam estabelecidas:

"Em um projeto de equipe, muitas vezes a pergunta correta não é 'como eu desenharia isso do zero?', mas 'como implementar essa mudança respeitando e preservando tudo o que já existe?'."

Para fazer qualquer alteração segura, eu precisava primeiro entender como o ecossistema se comportava:

  • A comunicação entre componentes React no frontend e a camada de handlers no backend em Go;
  • A separação clara de responsabilidades entre contratos de repositório, serviços e entidades de domínio;
  • O funcionamento das migrations SQL no PostgreSQL;
  • Os padrões de DTOs, mappers e validações de tenant scope para isolamento de dados entre clientes;
  • O fluxo de colaboração no Git e a estrutura das branches da equipe.

Cada conceito técnico deixou de ser um capítulo abstrato de livro para se tornar uma necessidade prática do dia a dia. Uma transação em banco de dados deixou de ser apenas a definição de BEGIN/COMMIT e passou a ser o mecanismo fundamental para impedir que um alerta gerado no sistema ficasse parcialmente gravado caso ocorresse uma falha na tabela relacionada.

O método conversacional: IA como tutora técnica, não como piloto automático

Diante de uma stack desconhecida e de demandas urgentes, a tentação mais comum para um iniciante é recorrer a um agente de programação autônomo e dar um comando direto: "Implemente essa funcionalidade inteira no backend e no frontend."

Um agente autônomo poderia navegar por dezenas de arquivos, gerar alterações em Go, ajustar componentes em TypeScript e entregar o Pull Request pronto. Para um desenvolvedor sênior, isso representa um enorme ganho de produtividade, pois ele possui o repertório necessário para revisar criticamente cada linha gerada.

Para mim, contudo, essa abordagem traria um risco silencioso e perigoso: a ilusão da entrega sem a construção do aprendizado. Eu correria o risco de concluir a tarefa, mesclar o código e continuar sem entender uma única linha de Go ou sem saber explicar como o banco de dados foi atualizado.

Por isso, tomei a decisão consciente de não terceirizar meu raciocínio. Escolhi utilizar a IA de forma conversacional e incremental, atuando como um chatbot e funcionando como um verdadeiro tutor técnico ao vivo.

Estabeleci um fluxo estrito de trabalho pautado em um bloco lógico por vez:

  1. Análise de demanda e mapeamento: Identificávamos os arquivos envolvidos e entendíamos o fluxo arquitetural antes de escrever código.
  2. Execução no ambiente local: Eu executava os comandos, compilações ou testes no terminal da minha própria máquina.
  3. Envio e interpretação de saídas: Eu copiava a saída do terminal ou os logs do compilador e enviava para o chatbot.
  4. Explicação técnica e conceitos: Antes de aplicar qualquer correção, a IA explicava o motivo do erro ou a razão de determinada função em Go existir (por exemplo, a diferença de responsabilidade entre um Service e um Repository).
  5. Pequenas alterações e validação contínua: Aplicávamos uma modificação pontual, executávamos os testes locais novamente e analisávamos o impacto antes de avançar.
"Em vez de pedir para a IA programar por mim, comecei a pedir para ela programar comigo — e me explicar o porquê de cada decisão técnica ao longo do caminho."

A IA passou a funcionar como um andaime de aprendizagem (scaffolding). O andaime permite alcançar alturas arquiteturais às quais eu ainda não chegaria sozinho, mas ele não substitui a construção da estrutura. A cada novo bloco compreendido, o andaime podia ser levemente recuado.

image

Infográfico: Método conversasional com IA. - Elaborado por Daniel Messeder, com Inteligência Artificial.

Terminal, testes e erros como material de estudo

Trabalhar de forma incremental mudou minha relação com os erros de terminal. Em vez de encará-los como sinais de insatisfação do sistema, passei a enxergá-los como dados valiosos de diagnóstico.

Um exemplo marcante dessa dinâmica ocorreu durante o desenvolvimento do módulo de Ordens de Serviço. Em meio aos testes, o compilador de Go acusou uma falha indicando que o repositório não possuía um método específico: repository.FindByID undefined.

Em vez de aceitar um código pronto para contornar a mensagem, usei a oportunidade para questionar o chatbot:

  • Por que esse método deveria obrigatoriamente existir nessa camada?
  • Qual é a responsabilidade do repositório em relação às regras de tenant e isolamento de dados?
  • Como devemos tratar corretamente o cenário em que o registro não é encontrado no PostgreSQL sem violar os contratos da aplicação?

Após entender a fundo a necessidade da interface, implementamos o método e executamos a validação com go test ./.... Cada ciclo de erro → investigação → explicação → alteração → teste funcionou como uma aula particular contextualizada no próprio código do produto.

Outra mudança profunda na minha postura profissional foi entender que os testes automatizados não servem apenas para a etapa final de entrega. Eles guiam o desenvolvimento. No frontend em React e TypeScript, os testes da suíte cresceram gradativamente a cada entrega — passando de 156 testes na etapa inicial de alertas para 661 testes aprovados no ciclo da Pending Issues 3.

Além dos testes unitários e de integração, adotamos a prática de gravar vídeos de evidência funcional para cada bloco entregue (produzindo 5 vídeos na Pending 3 e 3 vídeos na Pending 4). Gravar a tela reproduzindo o fluxo operacional (como a abertura de um chamado ou o disparo de um alerta) obrigava-me a assumir a perspectiva do usuário final, garantindo que o software não apenas "passasse nos testes", mas entregasse uma experiência de uso (UX) fluida e consistente.

Casos práticos da jornada no HeluApp

A evolução técnica não aconteceu em teoria, mas ao longo de mais de 100 horas de atividade técnica registrada e grandes entregas funcionais no histórico do projeto:

1. Sistema de Alertas e Comunicação em Tempo Real via WebSocket

Entre julho e agosto de 2026, participei da construção da base persistente de alertas do sistema. A funcionalidade exigiu criar um serviço transacional com suporte a rollback, garantindo idempotência e consistência no banco PostgreSQL. No frontend, implementamos um provider global de WebSockets com reconexão automática, controle de autenticação e deduplicação de mensagens. A entrega culminou no Backend PR #12 e Frontend PR #13, validados com suítes de teste completas e checagem manual de fluxo.

2. Ordens de Serviço e a responsabilidade com Migrations SQL

No módulo de Ordens de Serviço (Backend PR #17 e Frontend PR #18), trabalhei com regras complexas de vínculo entre alertas e chamados, anexos e permissões. Foi nessa etapa que compreendi o perigo de uma migration SQL mal gerida. Em sistemas colaborativos, um salto de numeração ou uma migration criada sem conferir a branch origin/dev pode paralisar o ambiente de desenvolvimento de toda a equipe. Adotamos o hábito rigoroso de verificar a sequência exata de migrations executadas no banco antes de criar novos arquivos SQL (alcançando sequências superiores a 88 migrations no histórico do projeto em setembro).

3. Validação de Viagens e a distinção entre conceitos de negócio

No ciclo Pending Issues 3, deparei-me com a distinção fundamental entre o status de conclusão de uma viagem e a sua validação. Uma viagem poderia estar tecnicamente concluída no fluxo sem necessariamente ter sido validada pela equipe operacional. Essa separação conceitual mostrou-me como regras de negócio reais exigem precisão do desenvolvedor para não misturar conceitos apenas porque eles parecem visualmente similares na interface.

4. Painel Operacional, Quilometragem Histórica e Ocorrências

Durante o ciclo Pending Issues 4 (Backend PR #32 e Frontend PR #35), enfrentei um dos problemas de regra de negócio mais instigantes: o registro de ocorrências históricas.

Imagine a seguinte situação: um caminhão da frota encontra-se com a quilometragem atual de 1.500 km no sistema. O motorista precisa registrar uma ocorrência que aconteceu anteriormente, quando o veículo estava com 1.200 km. O sistema precisava armazenar a ocorrência com a data e quilometragem históricas de 1.200 km, mas não podia sob hipótese alguma reduzir o odômetro atual do caminhão de 1.500 km para 1.200 km.

A solução exigiu uma atualização atômica no backend Go:

  • O evento histórico armazena os 1.200 km para auditoria;
  • O cadastro principal do veículo só atualiza a quilometragem atual se o valor do novo evento for estritamente superior ao valor já registrado no banco.

Nessa mesma etapa, evoluímos o painel para iniciar sem nenhum veículo pré-selecionado (separando o histórico do usuário do contexto específico do caminhão) e expandimos o suporte para múltiplas imagens (até 5 anexos por ocorrência), incluindo previews, remoção individual e uma galeria modal interativa. No backend em Go, tivemos o cuidado arquitetural de realizar buscas em lote (batch fetch) para evitar o problema clássico de consultas N+1 ao banco de dados.

A vida real além do localhost: conflitos, CI/CD e ambiente

Entrar em um projeto real significa descobrir que os problemas não acabam quando o código funciona na máquina local (localhost).

Tive contato direto com conflitos de Git do tipo add/add em arquivos de serviço, repositório, mapper e testes durante a integração de branches com a dev. Em vez de resolver o conflito na cega ou aceitar automaticamente a sugestão da ferramenta, o processo exigia entender o que a minha branch havia alterado e o que a equipe havia mesclado, garantindo que ambas as intenções fossem preservadas.

Outra lição valiosa veio da integração contínua (CI/CD):

"Um teste verde na máquina local e um Pull Request aprovado não significam que o trabalho terminou. A integração contínua é a camada definitiva da verdade."

Após a entrega da Pending 4, o Frontend PR #35 foi mergeado após todos os 90 testes principais e 6 testes de galeria passarem localmente. Contudo, o build da branch de integração dev falhou no ambiente remoto por causa de três testes legados de TypeScript que ainda mantinham referências a campos de status antigos. O deploy não chegou a executar. O episódio ensinou-me a acompanhar o ciclo de vida da aplicação até a implantação final.

Da mesma forma, aprendi a diagnosticar problemas de infraestrutura local. Quando os containers em Docker subiam e as migrations em Go atingiam a versão 88, mas a aplicação falhava ao iniciar, o problema não estava na lógica da linguagem, mas na falta de carregamento adequado da variável de ambiente DATABASE_CONN_STRING. Diferenciar falhas de código de falhas de ambiente de execução tornou-se parte da minha maturidade profissional.

image

Infográfico: HQ resumindo o artigo. - Elaborado por Daniel Messeder, com Inteligência Artificial.

Como minhas perguntas mudaram: a evolução do raciocínio

A maior prova de que a IA foi utilizada como ferramenta de aprendizado — e não como muleta — esteve na evolução da minha forma de interagir com o chatbot ao longo dos meses.

No início da jornada no HeluApp, meus prompts eram reativos e abertos:

"Apareceu este erro no terminal ao compilar em Go. O que eu faço agora?"

Com o passar do tempo, o acúmulo de contexto e a vivência na arquitetura transformaram minhas perguntas em proposições técnicas estruturadas:

"Analisando a falha de validação no fluxo de ordens de serviço, percebi que o erro ocorre na camada de Service porque o tenant scope não está sendo repassado na busca do repositório. Estou pensando em ajustar o DTO de entrada e adicionar um teste de integração cobrindo esse cenário. Essa abordagem respeita o padrão arquitetural do projeto ou existiria um risco de regressão nas viagens?"

Essa mudança de postura demonstra que a ferramenta continuava presente, mas o protagonismo do raciocínio técnico pertencia a mim. Problemas que antes exigiam explicações longas sobre a sintaxe de Go começaram a se tornar familiares, permitindo que eu focasse nas regras de negócio e na qualidade da entrega.

Conclusão: a IA como aceleradora de entendimento para iniciantes

Minha trajetória como desenvolvedor freelancer no HeluApp continua em andamento. Ainda sou um desenvolvedor em formação. Continuo consultando documentações, tirando dúvidas com a equipe, cometendo erros e estudando diariamente. Meu foco principal de estudos acadêmicos permanece em Java e no ecossistema frontend, mas a vivência prática em Go expandiu horizontes que nenhum curso isolado seria capaz de oferecer.

A grande lição dessa experiência pode ser resumida em uma distinção fundamental:

Existe uma diferença brutal entre usar a Inteligência Artificial para eliminar a dificuldade e usar a Inteligência Artificial para tornar a dificuldade compreensível.

Se você utiliza a IA para apagar qualquer fricção de aprendizado, gerando blocos inteiros de código sem leitura crítica, você pode até entregar uma tarefa mais rápido hoje, mas continuará dependente amanhã. Por outro lado, quando você utiliza a IA para traduzir logs complexos, explicar decisões de arquitetura e validar suas próprias hipóteses, a ferramenta encurta anos de distância entre a teoria do curso e a prática do mercado.

Para outros estudantes e desenvolvedores iniciantes que estão dando os primeiros passos ou enfrentando a insegurança de uma stack desconhecida, deixo um convite prático:

Na próxima vez em que for utilizar uma IA para resolver um problema de código, mude sua pergunta. Em vez de pedir 'escreva a solução para mim', peça 'ajude-me a entender a causa desse problema e me explique qual é o melhor caminho para corrigi-lo'.

Assuma o volante do seu aprendizado. A IA pode lhe dar o próximo degrau, mas quem precisa subir a escada é você.

Vamos nos conectar

Você pode acompanhar meus projetos e minha evolução por aqui:

LinkedIn: Daniel Messeder

GitHub: Messeder-Daniel

Compartilhe
Recomendados para você
GitHub Copilot - Código na Prática
Microsoft 50 Anos - GitHub Copilot
Microsoft AI for Tech - GitHub Copilot
Comentários (0)