Conn2Flow
Navegação das docs

SDD

req-138: Normalização do MIME Type no Admin-Arquivos e Correção da Comparação de Imagem no Interface-v2

O gerenciador de arquivos monta o campo mime por concatenação de rótulo interno com extensão, em admin-arquivos.php:183:

Origem: achados do agente executor durante a implementação do req-137 / BATCH-140, ao rastrear os consumidores do canal postMessage do gerenciador de arquivos. Ambos são defeitos pré-existentes, anteriores àquele lote, e por isso foram deixados fora do escopo dele e promovidos para esta requisição por decisão explícita do Engenheiro Chefe Humano.

Descrição do Problema / Contexto

1. O admin-arquivos não devolve MIME type — devolve uma string inventada

O gerenciador de arquivos monta o campo mime por concatenação de rótulo interno com extensão, em admin-arquivos.php:183:

'mime' => $tipo . '/' . strtolower(pathinfo($nome, PATHINFO_EXTENSION)),

Como $tipo vem de arquivo_tipo_por_extensao() e só pode assumir image, video, audio ou file, o resultado não é um MIME type — é um híbrido que coincide com o MIME real em alguns casos e diverge em outros:

Arquivo Valor atual MIME real Situação
foto.png image/png image/png coincide por acaso
video.mp4 video/mp4 video/mp4 coincide por acaso
foto.jpg image/jpg image/jpeg divergente
icone.svg image/svg image/svg+xml divergente
musica.mp3 audio/mp3 audio/mpeg divergente
manual.pdf file/pdf application/pdf divergente
dados.json file/json application/json divergente

Por que isso ainda não quebrou nada: todos os consumidores do canal testam apenas o prefixo (/^image\//), que está sempre correto para imagens. O sufixo nunca é comparado por ninguém.

Onde já produz efeito visível hoje: o valor é exibido cru ao usuário final em dois pontos — .widgetImage-tipo (interface-v2.js:480) e ._html-editor-imagepick-tipo (html-editor-interface.js:1214). Quem seleciona um PDF lê "file/pdf" na interface.

Risco a prazo: qualquer consumidor futuro que compare MIME exato (=== 'application/pdf'), que alimente uma tabela de ícones por MIME, ou que persista esse valor como content-type de um asset, falhará em silêncio.

Ponto único de origem: o mesmo campo mime alimenta os quatro caminhos de despacho do módulo — seleção individual, galeria modal, conclusão de upload e o despacho em lote do BATCH-140. Corrigir a origem no PHP conserta todos de uma vez, sem tocar em nenhum consumidor.

2. Comparação sempre falsa derruba o picker de imagem do interface-v2

Em interface-v2.js:471:

if (dados.tipo?.match(/image\//) === 'image/') {

String.prototype.match() sem a flag g devolve um array (['image/', index: 0, ...]) ou null — nunca uma string. A comparação estrita com 'image/' é, portanto, sempre falsa.

Consequência: o ramo de sucesso nunca executa. Ao selecionar uma imagem válida no widget de imagem do interface-v2, o código cai direto no else e exibe o alerta "Not an image" / "Não é uma imagem", sem preencher os campos nem fechar o modal. Os demais consumidores do mesmo canal usam a forma correta (/^image\//.test(dados.tipo)), o que confirma o desvio pontual.


Escopo Detalhado das Alterações

1. MIME real na origem (gestor/bibliotecas/arquivo.php + admin-arquivos.php)

  • Criar arquivo_mime_por_extensao($nome) na biblioteca arquivo.php, ao lado da já existente arquivo_tipo_por_extensao(), seguindo o mesmo padrão do arquivo (if (!function_exists(...)), docblock e resolução apenas por extensão, sem depender do arquivo em disco).

  • Mapear as extensões já classificadas por arquivo_tipo_por_extensao() (imagens, vídeos, áudios) mais os formatos de documento, arquivo compactado, fonte e texto de uso corrente no gerenciador.

  • Fallback para application/octet-stream em extensão desconhecida ou ausente.

  • Substituir a concatenação de admin-arquivos.php:183 pela chamada à nova função.

  • Invariante inegociável: toda extensão que arquivo_tipo_por_extensao() classifica como image DEVE receber um MIME iniciado por image/, sob pena de quebrar de uma vez os seis consumidores que dependem do teste de prefixo. O mesmo vale para video/ e audio/.

2. Correção da comparação no interface-v2

  • Substituir dados.tipo?.match(/image\//) === 'image/' pela forma já usada pelos demais consumidores do canal: dados.tipo && /^image\//.test(dados.tipo).

  • Não alterar o restante do fluxo do widget de imagem, o alerta do else nem a estrutura do handler.


Plano de Validação e Testes

  1. Validação de Sintaxe: php -l nos PHP alterados e node --check no interface-v2.js.

  2. Testes Automatizados:

    • Teste PHP cobrindo o mapa de MIME, o fallback e — obrigatoriamente — a invariante de prefixo contra a lista real de arquivo_tipo_por_extensao().

    • Teste JS cobrindo a comparação corrigida, incluindo o caso que hoje falha (image/jpeg válido) e a rejeição correta de não-imagem.

    • composer test e npx vitest run sem regressão.

  3. Validação Manual & Visual:

    • Selecionar uma imagem no picker e confirmar que o tipo exibido é o MIME real (image/jpeg).

    • Confirmar que o despacho em lote do BATCH-140 segue funcionando com o MIME normalizado.

    • Confirmar que o widget de imagem do interface-v2 deixa de recusar imagens válidas.

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