Pular para o conteúdo
© Code by Kevin · Início
Todos os projetos

Estudo de caso · 02 / 033 min de leitura

PDF Renamer

Classificação automática de documentos pelo conteúdo

Papel
Autor único
Equipe
Individual
Ano
2026
Status
Em uso diário
Stack
JavaScript · HTML · CSS · PDF.js · OCR · File System Access API · Anthropic API

TL;DR

Um classificador de documentos que roda no navegador e triplicou a capacidade da secretaria: de ~100 para ~300 documentos por dia. Uma turma, que levava 3 dias, passou a levar até 1.

Contexto e problema

Os prontuários digitais dos alunos chegam como PDFs escaneados com nomes como scan_0412.pdf. Para cada um, o fluxo era sempre o mesmo: abrir, ler, descobrir o tipo, digitar o nome padronizado, escolher a pasta do aluno e salvar. Uma turma tem cerca de 200 documentos, então organizar uma turma inteira tomava 3 dias.

O problema não era só o tempo. Nome digitado à mão gera variações ("Ficha medica", "FICHA MÉDICA", "ficha_saude"), e arquivo salvo na pasta errada some do prontuário.

Meu papel

Autor único: identifiquei o gargalo trabalhando na própria secretaria, desenhei o fluxo, construí a ferramenta e acompanhei o uso. Ela está em uso diário pela equipe.

Restrições

  • Sem instalar programas: tinha que rodar no navegador dos computadores da escola.
  • Arquivos locais: os prontuários ficam em pastas do Windows, não num servidor.
  • Documentos escaneados: muitos PDFs não têm texto pesquisável, só a imagem.
  • Usuárias que não programam: os tipos de documento e as regras mudam por setor, então ajustar não podia depender de mim.

Decisões técnicas e trade-offs

DecisãoAlternativaPor quê
Regras com pesos por palavra-chave, num dicionário editávelUm modelo de machine learningNão havia base rotulada para treinar. As regras são explicáveis e a própria secretaria ajusta pela interface.
Ler o texto do PDF primeiro e fazer OCR só quando não há textoOCR em todo documentoPDFs digitais são classificados na hora; o OCR (mais lento) fica só para os escaneados.
Ler só as 2 primeiras páginasO documento inteiroO tipo quase sempre está no cabeçalho, e em lote cada segundo conta.
Um limiar mínimo de confiançaSempre sugerir algum tipoQuando a pontuação é baixa, a ferramenta pede confirmação em vez de errar com confiança.
File System Access API grava direto na pasta do alunoBaixar o arquivo e mover à mãoElimina dois passos por documento. No Firefox, cai para o download normal.
Lembrar a pasta com IndexedDBEscolher a pasta toda vezA permissão da pasta continua entre uma sessão e outra.

Arquitetura

Fluxo de um documento
  1. 01PDFs em lotearrastar e soltar; fila com progresso
  2. 02PDF.jsvisualiza e extrai o texto
  3. 03Classificadorregras + dicionário editável
  4. 04Nome sugeridotipo + ano, padronizado
  5. 05Pasta do alunogravação direta, checa duplicados

Apoio

  • OCR (Tesseract.js)só para PDFs sem camada de texto
  • IndexedDB e localStoragepasta, perfis e configurações
  • Histórico em CSVtudo o que foi renomeado

Destaques de implementação

Um classificador que dá para explicar

O texto é normalizado (sem acento, em maiúsculas) e cada tipo de documento soma os pesos das palavras-chave encontradas. Termos curtos exigem palavra inteira, para que "RG" não seja encontrado dentro de outra palavra. O tipo vencedor só é sugerido se passar do limiar.

js/script.js (resumido)
function scoreKeyword(text, kw) {
  // termos curtos exigem palavra inteira (evita "RG" casar dentro de outra palavra)
  if (kw.length <= 3) return new RegExp("\\b" + kw + "\\b").test(text);
  return text.includes(kw);
}
 
function classify(text) {
  const t = normalizeText(text);
  let best = null,
    bestScore = 0;
  for (const rule of CLASSIFY_RULES) {
    let score = 0;
    for (const [kw, w] of rule.kw) if (scoreKeyword(t, kw)) score += w;
    if (score > bestScore) {
      bestScore = score;
      best = rule.type;
    }
  }
  return bestScore >= CLASSIFY_THRESHOLD ? { type: best, score: bestScore } : null;
}

As regras padrão convivem com as que a equipe cria na interface: um setor adiciona uma palavra-chave com um peso e ela passa a valer na hora, sem eu mexer no código.

Feito para o uso diário

  • Duplicados: se o nome já existe na pasta, a ferramenta pergunta o que fazer e sugere uma numeração livre.
  • Teclado: atalhos para confirmar, pular e navegar, para não tirar a mão do teclado no meio de um lote.
  • Histórico exportável em CSV de tudo o que foi renomeado.

Resultado e impacto

  • 3× mais documentos por dia: de ~100 para ~300.
  • Uma turma de ~200 documentos caiu de 3 dias para até 1.
  • Nomes padronizados e arquivos na pasta certa, o que reduziu erros de arquivamento no prontuário dos 545 alunos.

O que eu faria diferente e próximos passos

Links