Conn2Flow
Navegação das docs

SDD

req-113: Cache HTTP de Arquivos Estáticos e Invalidação Automática de Assets em Release, Sincronização e Deploy

O PageSpeed da instância [REDACTED] apontou baixa eficiência de cache dos arquivos estáticos. A análise do core identificou que…

  • Status do intake: implemented-pending-homologation

  • Data: 2026-08-14

  • Origem: solicitação direta do Engenheiro Chefe durante a análise do PageSpeed de https://[REDACTED].com/

  • Classificação preliminar: mudança operacional/normativa nos entrypoints de release, sincronização, build, deploy e atualização

  • Batch candidato: BATCH-113


Contexto e problema observado

O PageSpeed da instância [REDACTED] apontou baixa eficiência de cache dos arquivos estáticos. A análise do core identificou que gestor/controladores/arquivo-estatico/arquivo-estatico.php entregava os recursos com política privada, impedindo o aproveitamento correto pelo navegador e pela CDN.

Uma correção local já foi preparada no core para:

  • entregar assets públicos com cache longo quando a URL contém uma versão válida em ?v=;

  • manter TTL menor para URLs sem versão;

  • emitir ETag e Last-Modified e responder 304 Not Modified;

  • preservar Range, 206 Partial Content, 416 e o comportamento de HEAD.

Essa política torna explícito um contrato adicional: sempre que o conteúdo de um asset versionado mudar, a versão presente na URL também precisa mudar. Caso contrário, navegador e CDN podem continuar servindo o conteúdo anterior sob uma URL marcada como immutable.

Atualmente esse contrato não é garantido por todos os fluxos operacionais:

  • ?️ Manager - GIT Release chama ai-workspace/en/scripts/releases/release.sh, que incrementa somente $_GESTOR['versao'] em gestor/config.php através de version.php;

  • assets próprios de módulos usam a chave versao do JSON do módulo, normalmente mantida de forma manual;

  • bibliotecas que servem JS/CSS possuem versões próprias em PHP, também mantidas manualmente;

  • projetos privados usam $_GESTOR['project-version'] em config-project.php, sem atualização automática no deploy;

  • a instância [REDACTED]/[REDACTED] possui módulos privados e assets como contents/tailwindcss/output.css e contents/project/html-editor.js, entregues pelo mesmo controlador estático;

  • existem vários entrypoints de sincronização, build, deploy e atualização, e a invalidação não pode depender de o operador lembrar qual deles foi utilizado.


Diagnóstico dos fluxos existentes

Release público do core

  1. .vscode/tasks.json → ?️ Manager - GIT Release.

  2. ai-workspace/en/scripts/releases/release.sh chama version.php, incrementa apenas a versão global, cria commit/tag e publica.

  3. .github/workflows/release-gestor.yml compila o Tailwind do core, recompila recursos e monta gestor.zip.

  4. Não existe etapa geral que valide ou atualize a versão dos assets pertencentes a módulos e bibliotecas.

Ambiente local e sincronização do core

  • Manager - Synchronize => Files - Test Environment chama synchronize-manager.sh.

  • Manager - Build Local chama build-local-manager.sh.

  • Projects - Sync Core -> ID chama sync-core-to-project.sh.

  • Os scripts compilam/copiam assets, mas não possuem um contrato único de geração de cache-bust.

Projeto privado e deploy por API

  1. Projects - Synchronize => Resources -> ID chama update-resource-data.sh, que compila o Tailwind e os recursos do projeto.

  2. Projects - Synchronize => Files -> ID chama synchronize-project.sh, que copia o projeto para o ambiente de teste.

  3. Projects - Deploy Project -> ID chama deploy-project-v2.sh, que executa update-resource-data.sh, cria um ZIP e o envia para /_api/project/update.

  4. O endpoint copia o conteúdo do projeto para a instalação e atualiza banco/hooks, mas não deve inventar versões depois que o pacote já foi produzido.

Atualização remota do sistema

  • Projects - Update Current Project e Projects - Update Project -> ID chamam update-system.sh.

  • Esse fluxo consome um artefato público do core já produzido. Portanto, deve validar/propagar as versões presentes no artefato, não gerar versões diferentes no servidor de destino.

Fluxo inverso

  • Projects - Recover ... apenas recupera e recompila recursos locais.

  • O recover não publica arquivos e não deve alterar versões de cache por si só. A geração deve ocorrer no próximo sync/deploy.


Requisitos solicitados

1. Formalizar a política de cache do controlador estático

  • Assets com ?v=<valor-válido> devem poder usar public, max-age=31536000, immutable.

  • Assets sem versão devem continuar atualizáveis, com TTL limitado e revalidação.

  • ETag, Last-Modified, 304, HEAD, Range, 206 e 416 devem permanecer cobertos por testes.

  • Páginas PHP, HTML dinâmico do banco, AJAX e API não devem passar a ser armazenados por essa política.

2. Automatizar o cache-bust de módulos públicos e privados

  • Mudanças em assets de um módulo (.js, .css, variantes como .widget.js, .toolbar.js e demais arquivos efetivamente servidos) devem resultar automaticamente em uma nova URL.

  • O mecanismo deve funcionar tanto nos módulos do core quanto nos módulos existentes dentro de projetos privados.

  • Módulos sem chave semântica versao não podem gerar URL vazia nem warning.

  • Uma versão semântica mantida pelo desenvolvedor não deve ser incrementada desnecessariamente apenas para operar cache.

3. Automatizar o cache-bust dos assets de bibliotecas do core

  • Assets pertencentes a bibliotecas, como os arquivos de interface, html-editor, formulario e configuracao, devem participar da mesma garantia.

  • Deve existir uma fonte única por asset/proprietário, eliminando números fixos duplicados escritos manualmente em consumidores diferentes.

4. Automatizar o cache-bust dos assets próprios de projeto

  • O deploy/sync de projeto deve atualizar automaticamente o token utilizado por @[[project#version]]@, ou substituí-lo por um token específico de assets com fallback compatível.

  • A geração deve ocorrer depois da compilação do Tailwind e dos recursos, mas antes da cópia ou criação do ZIP.

  • Assets privados de módulo continuam usando o mecanismo do próprio módulo; assets globais do projeto usam o token do projeto.

5. Cobrir todos os entrypoints de entrega

O mecanismo comum deve ser chamado ou verificado, conforme aplicável, por:

  • Manager - GIT Release;

  • workflow automático release-gestor.yml;

  • Manager - Synchronize => Files - Test Environment;

  • Manager - Build Local;

  • Projects - Sync Core -> ID;

  • Projects - Synchronize => Resources -> ID;

  • Projects - Synchronize => Files -> ID;

  • Projects - Deploy Current Project e Projects - Deploy Project -> ID;

  • fluxos compostos Projects - Update => All/Core/Project;

  • atualização remota Projects - Update Current Project/Project -> ID, como consumidora de um artefato já versionado.

O fluxo Recover fica explicitamente fora da geração, pois não entrega arquivos ao runtime.

6. Segurança operacional e observabilidade

  • A rotina deve ser determinística e idempotente: mesmos conteúdos produzem o mesmo resultado.

  • Deve falhar antes de commit, tag, cópia ou upload quando encontrar JSON inválido, configuração inconsistente ou asset sem proprietário/versionamento.

  • Deve imprimir resumo legível dos módulos, bibliotecas e assets de projeto que tiveram o cache-bust alterado.

  • Deve possuir modo de verificação/dry-run utilizável em teste e CI.

  • Não deve executar git commit, git tag, git push, deploy ou purge de CDN por conta própria.

  • Não deve expor tokens, URLs secretas ou conteúdo sensível de environment.json em logs.


Direção arquitetural recomendada para classificação

A recomendação é separar a versão semântica da versão de cache:

  1. Gerar um token determinístico curto a partir do conteúdo dos assets, com ordenação estável dos caminhos.

  2. Armazenar o token de módulo em uma chave dedicada, por exemplo asset_version, no JSON do módulo.

  3. Resolver URLs com a precedência asset_version → versao → versão global do sistema, preservando compatibilidade com módulos antigos.

  4. Manter $_GESTOR['versao'] como versão semântica do release do core.

  5. Gerar o token global do projeto a partir dos assets próprios efetivamente versionados e aplicá-lo ao placeholder de projeto com fallback compatível.

  6. Centralizar a geração/verificação em um único utilitário reutilizável pelos scripts Bash e pelo workflow, em vez de duplicar regex e regras em cada entrypoint.

Essa abordagem é preferível a incrementar indiscriminadamente todas as versões semânticas em todo release: somente conteúdos alterados mudam de URL, não há dependência do histórico de tags e o mesmo resultado pode ser reproduzido no release público, no build local e no deploy privado.

A adoção dessa direção altera o contrato operacional documentado no baseline e deve abrir um Change Request antes do batch de implementação.


Plano preliminar de implementação

Slice 1 — contrato e gerador puro

  • Abrir Change Request e decisão arquitetural para separar versão semântica e versão de assets.

  • Implementar gerador/verificador determinístico sem efeitos de Git ou rede.

  • Cobrir módulos com múltiplos assets, módulos sem versao, JSON inválido, asset novo/removido e execução idempotente.

Slice 2 — resolução de URLs no runtime

  • Atualizar helpers de inclusão de CSS/JS de módulos e bibliotecas para usar o token de assets com fallback.

  • Eliminar consumidores com versão fixa ou herança incorreta da versão global.

  • Preservar URLs e comportamento de módulos legados que ainda não possuam o novo campo.

Slice 3 — release e artefatos do core

  • Integrar o gerador no release.sh antes de git add/commit/tag.

  • Integrar verificação defensiva no workflow depois de Tailwind/recursos e antes do ZIP.

  • Integrar nos fluxos de sincronização e build local do core.

Slice 4 — projetos privados

  • Integrar a geração no fluxo de recursos do projeto depois do Tailwind/compilador.

  • Adicionar guarda antes de sincronizar ou compactar o projeto.

  • Cobrir módulos privados e o token global de assets de projeto.

Slice 5 — validação ponta a ponta

  • Validar localmente que alterar um asset muda a URL e que repetir sem alteração mantém a URL.

  • Validar MISS seguido de HIT no CDN e nova MISS após mudança do token.

  • Validar que conteúdo dinâmico não recebeu a política immutable.

  • Executar PHPUnit, Vitest e testes focados dos scripts/fixtures antes do fechamento.


Critérios de aceite

  • Alterar somente PHP/HTML/dados dinâmicos não muda nem depende do cache de assets.

  • Alterar um JS/CSS de módulo do core gera automaticamente nova URL no release/sync/build correspondente.

  • Alterar um JS/CSS de módulo privado gera automaticamente nova URL no sync/deploy do projeto.

  • Recompilar contents/tailwindcss/output.css ou alterar asset global de projeto gera novo token de projeto antes do ZIP/cópia.

  • Não alterar nenhum asset mantém os tokens estáveis em execuções repetidas.

  • Versões semânticas existentes continuam preservadas e editáveis pelo desenvolvedor.

  • Um módulo legado sem asset_version continua funcionando pelo fallback.

  • Um módulo com asset mas sem qualquer versão válida é normalizado ou bloqueado com mensagem acionável, conforme a decisão aprovada.

  • Todos os entrypoints listados chegam ao mesmo gerador/verificador ou consomem artefato já verificado.

  • O pacote público e o pacote privado contêm os mesmos tokens que o HTML/runtime utilizará.

  • O controlador estático responde com os cabeçalhos esperados sem quebrar streaming, download parcial ou HEAD.

  • Nenhum teste, script ou fluxo realiza commit/push/deploy automaticamente fora da task explicitamente acionada pelo operador.


Fora de escopo inicial

  • Cache de página HTML no Cloudflare ou regras externas de Cache Everything.

  • Purge automático da CDN, pois a mudança de URL deve tornar o purge desnecessário no fluxo normal.

  • Versionamento de uploads de usuários em contents/; esses arquivos devem preferencialmente usar nome imutável ou permanecer no TTL curto sem ?v=.

  • Alterações funcionais nos módulos e projetos que não sejam necessárias para a resolução/versionamento de assets.


Estado local que o futuro executor deve preservar

No momento deste intake existem alterações locais ainda não commitadas em:

  • gestor/controladores/arquivo-estatico/arquivo-estatico.php;

  • tests/Unit/PHP/ArquivoEstaticoRangeTest.php.

Essas alterações pertencem à origem desta solicitação e devem ser revisadas/incorporadas pelo BATCH-113, não descartadas nem sobrescritas sem análise.


Implementação realizada em 2026-08-14

  • controlador estático atualizado com cache público, modo imutável para ?v=, ETag, Last-Modified, 304, HEAD e If-Range, preservando 206/416;

  • criado atualizacao-versoes-assets.php, gerador puro de tokens SHA-256 curtos, determinístico, idempotente, com --check e sem efeitos de Git/rede/deploy;

  • asset_version passa a ser gravado nos JSONs de módulos que possuem assets, sem alterar a chave semântica versao;

  • criado manifesto do core assets/asset-versions.json e token de projeto contents/asset-version.json;

  • runtime usa precedência asset_version -> versao -> token global, e expõe assetVersion, projectAssetVersion e moduloAssetVersion ao JavaScript;

  • bibliotecas interface, html-editor, formulario e configuracao passaram a resolver automaticamente o token do diretório proprietário;

  • integração adicionada ao release, workflow, build local, sincronização do gestor, sync core -> projeto, atualização de recursos, sincronização de arquivos e deploy;

  • core real: 32 módulos verificados; [REDACTED] real: 12; uma segunda execução alterou zero tokens;

  • validação: PHPUnit completo com 255 testes/985 asserções, quatro skips e uma depreciação preexistente; sintaxe PHP, JavaScript e Git Bash aprovada.

Pendente para fechamento: publicar em homologação e confirmar os cabeçalhos/HIT-MISS da CDN e a troca de URL após alterar um asset real.

O Futuro é Híbrido: Humano + IA.

O Conn2Flow é a ferramenta. Se você precisa do Arquiteto para desenhar a estratégia da sua empresa usando essa tecnologia...

Contrate Consultoria Especializada