


Alterar uma API em Go e uma SPA em React editando primeiro a especificação OpenAPI
Para repositórios onde um backend em Go e uma SPA em React compartilham uma especificação OpenAPI. Muda a especificação e regenera o código sem mexer no que é gerado, segue regras para configurações, erros, sessões, downloads e atualizações, e testa antes de relatar.
Para usar estas regras de IA
## Tratar a especificação OpenAPI como fonte de verdade e separar o papel de cada camada
- Trate a especificação OpenAPI como fonte de verdade para rotas, schemas de request e response e modelos compartilhados.
- Mantenha o backend em Go e a SPA em React compiláveis de forma independente durante o desenvolvimento.
- Em produção, prefira incorporar a SPA compilada ao binário do backend e servir a API e a UI na mesma origem.
- Use o servidor de desenvolvimento apenas como conveniência de proxy; não permita que portas ou hosts exclusivos de desenvolvimento vazem para o código de produção.
- Preserve uma propriedade clara: a camada de API controla o transporte, os serviços controlam o comportamento do domínio, os stores controlam a persistência e o frontend controla a apresentação.
- Amplie os contratos existentes antes de inventar rotas, stores de configuração, canais de eventos ou modelos de estado paralelos.
- Não adicione subsistemas explicitamente adiados sem um requisito delimitado e uma decisão arquitetural.
- Quando a documentação e a implementação divergirem, interrompa a mudança afetada e resolva primeiro o conflito entre fontes de verdade.
## Editar a especificação e regenerar o código em vez de mexer em arquivos gerados
1. Inspecione a especificação, as interfaces geradas, a implementação, os testes e a documentação operacional relevante.
2. Edite a fonte autoritativa: arquivos OpenAPI para o formato da API, estruturas de configuração para ajustes e catálogos de mensagens para textos da UI.
3. Gere novamente os artefatos do backend e do frontend com os comandos do repositório.
4. Implemente a interface gerada e atualize somente os serviços e wrappers de UI diretamente afetados.
5. Execute formatação, análise estática, testes focados e a menor verificação de execução relevante.
6. Revise os diffs gerados para confirmar que a especificação produziu o contrato pretendido.
- Nunca edite manualmente arquivos gerados; corrija a especificação ou a configuração do gerador.
- Nunca registre uma rota improvisada que contorne a interface gerada do servidor.
- Mantenha os identificadores de operação únicos e estáveis, pois eles se tornam nomes de métodos gerados.
## Manter os esquemas compartilhados num só lugar e os tipos gerados iguais à API
- Divida as definições de caminhos por domínio e mantenha schemas, parâmetros e responses compartilhados em uma única seção canônica de components.
- Reutilize referências compartilhadas em vez de duplicar schemas quase idênticos entre arquivos de caminhos.
- Preserve os mapeamentos de importação e os controles de poda específicos do gerador exigidos por referências entre arquivos.
- Quando um schema espelhar um tipo de biblioteca upstream, mantenha o mapeamento de máquina e as propriedades JSON sincronizados.
- Declare cada campo serializado e marque cada campo sempre presente como required para consumidores que não sejam Go.
- Represente referências nullable usando o formato exigido pela versão do OpenAPI e pelo gerador; teste o resultado gerado.
- Gere tipos do frontend a partir do documento de API realmente servido pelo backend quando a fidelidade de execução for importante.
- Faça commit dos tipos de API gerados quando a política do repositório usar seus diffs como evidência de revisão do contrato.
- Mantenha clientes de API atrás de wrappers de domínio para que componentes não dependam de detalhes do transporte.
## Retornar erros estruturados sem vazar o texto de erros internos
- Implemente endpoints por meio da interface gerada do servidor e agrupe métodos de handler por domínio.
- Use um único helper compartilhado de response JSON e um classificador central de erros.
- Retorne erros estruturados com códigos de máquina estáveis, uma categoria de renderização, campos opcionais seguros e um identificador de request.
- Nunca copie texto bruto de erro interno ou upstream para uma response destinada ao client.
- Coloque detalhes de validação de campo em um map dedicado e reserve uma key geral para falhas sem relação com campos.
- Converta falhas upstream em identificadores de motivo estáveis; mantenha bodies brutos somente em logs protegidos.
- Use erros tipados visíveis ao usuário apenas quando o texto dinâmico for deliberadamente seguro para exibição.
- Não construa envelopes de erro de transmissão fora do classificador.
- Retorne códigos de status e erros JSON em vez de usar panics para controlar o fluxo.
- Trate a recuperação de panics como uma rede de segurança estruturada e registrada, não como comportamento normal.
## Definir cada configuração uma só vez e marcar as que exigem reinício
- Defina ajustes uma única vez em estruturas de configuração tipadas; derive delas padrões, validação, metadados de schema e keys de ambiente.
- Aplique sempre a mesma precedência: padrões, arquivo de ajustes e overrides de ambiente.
- Persista somente valores diferentes dos padrões incorporados.
- Para cada novo ajuste, defina seu padrão, validação, categoria de UI, sensibilidade, visibilidade e comportamento de reinicialização.
- Um ajuste com hot reload precisa de um consumidor ativo ou hook de recarga; caso contrário, marque-o como dependente de reinicialização.
- Valores dependentes de reinicialização podem ser persistidos imediatamente, mas devem permanecer fixos na visão efetiva de execução até a reinicialização.
- Mascare valores sensíveis nas responses da API e trate placeholders ocultos como no-op durante a atualização.
- Mantenha ajustes exclusivos do programa como read-only pela API de execução e exclua ajustes ocultos do schema refletido da UI.
- Execute os mesmos validadores na inicialização e antes da persistência para que uma configuração salva não quebre a próxima inicialização.
- Grave ajustes atomicamente e ancore caminhos relativos gerenciados a uma raiz de dados estável, não ao diretório de inicialização.
## Usar um só formato de log e desligar o servidor sem deixar trabalho pendente
- Use logging estruturado com um único schema em requests HTTP, eventos de ciclo de vida e workers em segundo plano.
- Anexe campos e erros do handler ao log da request atual em vez de emitir eventos duplicados por request.
- Mantenha logs do backend em um único idioma operacional; a localização da UI pertence ao frontend.
- Preserve a ordem do middleware quando IDs de request, endereços reais de clients, logging de requests e recuperação de panics dependerem dela.
- Coloque novo middleware dentro do limite de recuperação, salvo quando precisar alterar campos antes do início do logging de requests.
- Ao encerrar, feche assinantes de eventos persistentes antes de drenar o servidor HTTP.
- Defina um prazo limitado de drenagem para requests em andamento e o comportamento explícito quando ele expirar.
- Para reiniciar, conclua a limpeza dos serviços antes de substituir ou gerar o processo.
- Faça handlers de streaming retornarem quando o hub fechar ou a request for cancelada.
- Registre todos os workers em segundo plano na mesma sequência de encerramento para não deixar trabalho órfão.
## Usar chaves de consulta estáveis e limpar o cache quando o usuário muda
- Torne explícita a ordem dos providers quando providers posteriores dependerem de contextos de query, locale, autenticação ou eventos.
- Exponha factories de opções de query a partir de módulos de feature e mantenha chamadas diretas à API dentro de wrappers de domínio.
- Use keys de query estáveis que incluam cada parâmetro que altere a identidade.
- Preserve dados da lista anterior somente para transições reais de página; descarte-os quando filtros, usuários, tabs ou a identidade de busca mudarem.
- Limpe caches no escopo da conta quando a sessão autenticada mudar.
- Centralize atualizações otimistas, snapshots de rollback e invalidação para manter coerente cada cópia em cache de uma entidade.
- Trate eventos do servidor como sinais de refresh; o estado autoritativo ainda vem de queries ou endpoints de estado.
- Leia funções de mensagens localizadas por um contexto reativo dentro dos caminhos de renderização.
- Mapeie keys dinâmicas de tradução por resolvers estáticos explícitos e mantenha formatos de placeholder idênticos entre locales.
- Mantenha labels de configuração legíveis por humanos em catálogos do frontend, não em schemas do backend.
## Guardar a sessão à parte e não encerrá-la por falhas temporárias
- Armazene credenciais de sessão em um único arquivo de estado dedicado com permissões restritas; nunca as misture aos ajustes gerais.
- Trate a credencial de refresh como autoridade da sessão e credenciais de acesso de curta duração como substituíveis.
- Renove proativamente perto do vencimento e reativamente uma vez após uma falha de autenticação, usando coordenação single-flight.
- Preserve a sessão em falhas transitórias; limpe-a somente após confirmar uma rejeição permanente.
- Mantenha verificadores de autorização com vida curta, capacidade limitada e uso único.
- Valide valores de callback colados antes de enviá-los upstream e retorne erros localizados e acionáveis.
- Remova credenciais dos resultados de detecção de proxy e mantenha a detecção como read-only.
- Proteja gravações de onboarding não autenticado para que não alterem ajustes após o login.
- Proteja endpoints sensíveis de mutação com autenticação e um header CSRF específico da aplicação.
- Nunca exponha ao client bodies de autenticação upstream, credenciais nem erros de packages internos.
## Salvar downloads por arquivos temporários e não apagar arquivos que o app não criou
- Torne o job o limite da transação e persista atomicamente cada transição de estado relevante.
- Envie progresso de alta frequência por eventos em vez de regravar o estado persistente a cada tick.
- Grave payloads em arquivos temporários com nomes únicos e renomeie-os somente após o sucesso; remova arquivos parciais ao cancelar ou falhar.
- Tente novamente somente falhas recuperáveis, usando backoff exponencial limitado.
- Registre se a aplicação criou cada arquivo final antes da limpeza; nunca remova um caminho com base apenas no nome esperado.
- Resolva colisões considerando tanto o conteúdo do disco quanto reservas em andamento, com uma estratégia de fallback limitada.
- Resolva novamente caminhos durante a recuperação após reinicialização, salvo quando um payload concluído já for dono do destino.
- Analise templates de caminho na inicialização e valide-os novamente antes de aceitar mudanças de configuração.
- Higienize cada segmento de caminho, preserve raízes explícitas, limite nomes de arquivo por bytes e conte por caracteres o truncamento visível ao usuário.
- Fixe decisões de conversão e nomenclatura por job para que ajustes recarregados em tempo real não alterem trabalho em andamento.
## Reenviar eventos perdidos ao reconectar e ressincronizar quando não for possível
- Mantenha o estado persistente como autoritativo e trate eventos como uma otimização.
- Dê aos eventos IDs, timestamps, topics, tipos e payloads reconstruíveis estáveis.
- Ao reconectar, reproduza eventos posteriores ao último ID conhecido pelo client quando o buffer ainda os contiver.
- Se a reprodução for impossível, emita um único evento de ressincronização e exija que os clients busquem novamente o estado autoritativo.
- Use keepalives para impedir que intermediários fechem silenciosamente streams ociosos.
- Permita que somente eventos no nível de job definam o estado agregado do job; eventos de task atualizam a task sem recalcular regras controladas pelo servidor.
- Atualize views afetadas após a reconexão e após um sinal de ressincronização.
- Limite a frequência das notificações de progresso, mas ignore o limite em transições terminais e na atualização final de progresso.
- Mantenha o transporte de eventos independente dos gerenciadores de domínio por meio de uma pequena interface publisher.
## Limitar os destinos do proxy e verificar a assinatura antes de atualizar o app
- Permita destinos de proxy por uma política exata de hosts e verifique novamente cada redirecionamento para impedir falsificação de requests no servidor.
- Compartilhe falhas simultâneas de cache do mesmo recurso e rejeite bodies grandes demais antes de armazená-los.
- Trate o sistema de arquivos como verdade do cache; reconcilie seu tamanho periodicamente e após gravações, removendo primeiro os acessos mais antigos.
- Mantenha o armazenamento de cache realocável e separado do estado durável do usuário.
- Injete locais do feed de atualização e chaves de assinatura confiáveis durante o build de release; falhe de forma fechada quando faltar material de confiança.
- Verifique um manifesto assinado antes de confiar em qualquer versão, URL, checksum ou campo de notas de release.
- Verifique o arquivo baixado em relação ao manifesto assinado antes de substituir um binário.
- Execute a aplicação de atualizações em single-flight, rejeite-a em builds de desenvolvimento e exija autenticação com proteção CSRF.
- Resolva o executável substituto de forma determinística e rejeite arquivos ambíguos.
- Drene os serviços e reinicie somente após preparar o substituto verificado.
## Testar o app em execução e parar antes de publicar ou mudar a produção
- Percorra geração, implementação, testes focados e verificação direta de execução sem pular uma etapa que falhou.
- Verifique o endpoint de saúde, o documento OpenAPI servido, o comportamento da API afetada e o caminho de UI diretamente afetado.
- Execute formatação, análise estática, testes de backend sensíveis a condições de corrida, verificações de frontend e builds de produção quando a mudança os afetar.
- Confirme persistência atômica, semântica de reinicialização, mascaramento de segredos e não divulgação de erros com testes focados.
- Para trabalho de release, valide versionamento semântico estrito, continuidade do feed assinado, checksums e resolução de arquivos por plataforma.
- Mantenha features adiadas como adiadas, salvo quando o requisito atual as incluir explicitamente no escopo.
- Evite refatorações não relacionadas, stores de estado paralelos, sistemas de erro duplicados e infraestrutura especulativa.
- Pare antes de uma release externa, migração destrutiva, mudança de credenciais ou mutação de produção sem autorização explícita.
- Relate o que mudou, o que foi verificado, o que permanece fora do escopo e qualquer conflito de contrato não resolvido.
