Pular para o conteúdo principal

Instruções: Correções do Gerenciador de Dados

Este documento detalha a implementação e as correções para o componente Gerenciador de Dados, uma funcionalidade crítica do sistema Clio. Utilize as informações de arquitetura e convenções do arquivo Visão Geral de Engenharia de Rede como base para o desenvolvimento.

📋 Visão Geral da Funcionalidade

O Gerenciador de Dados (gerenciadordedados.vue) é a interface central para o registro e a verificação de integridade de documentos antes de entrarem no fluxo de catalogação de metadados.

Responsabilidades Principais:

  1. Configuração de Pastas: Permite ao usuário selecionar as pastas do Google Drive que serão monitoradas.
  2. Registro de Arquivos: Lista arquivos do Drive que ainda não foram registrados no sistema e permite sua inclusão na tabela gerenciador_dados.
  3. Verificação de Integridade: Executa uma série de verificações para encontrar inconsistências entre o Google Drive e o banco de dados local (ex: arquivos órfãos, registros ausentes).
  4. Visualização de Dados: Apresenta os dados já registrados com opções de filtro e busca.

🔧 Tecnologias e Arquivos Chave

CamadaTecnologiaArquivo PrincipalPropósito
FrontendVue.js 3, Piniaiface-frontend-vuejs/src/components/gerenciadordedados/gerenciadordedados.vueInterface do usuário para todas as operações de gerenciamento de dados.
BackendNode.js, Expressnode/backend/routes/gerenciadorDadosRoute.jsFornece os endpoints RESTful para listar, registrar e verificar arquivos.

🗄️ Estrutura de Dados e Mapeamento

O processo de registro depende da correlação entre a tabela de mapeamento do Drive (gerenciamento_googledrive) e a tabela de documentos do sistema (gerenciador_dados).

Relacionamento entre Tabelas

┌─────────────────────────────────────────────────────────────────────────┐
│ gerenciamento_googledrive │
│ (Cache/mapeamento de TODOS os arquivos no Google Drive) │
├─────────────────────────────────────────────────────────────────────────┤
│ id_drive ─────────────────────────────────────────────────────┐ │
│ (ID único do arquivo no Drive) │ │
│ │ │
│ parents ───────────────────────────────────────────────┐ │ │
│ (JSON array com IDs das pastas pai) │ │ │
└──────────────────────────────────────────────────────────│──────│────────┘
│ │
▼ ▼
┌─────────────────────────────────────────────────────────────────────────┐
│ gerenciador_dados │
│ (Registros de documentos para catalogação) │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ url_pdf ◄───── id_drive (se tipo_mimetype = 'application/pdf') │
│ │
│ url_jpg ◄───── id_drive (se tipo_mimetype LIKE 'image/%') │
│ │
│ google_drive_folder_id ◄───── parents[0] (ID da pasta pai) │
│ │
└─────────────────────────────────────────────────────────────────────────┘

Lógica de Mapeamento de Campos

Ao registrar um arquivo, os campos são preenchidos da seguinte forma:

Tipo de Arquivo no DriveCampo url_pdfCampo url_jpgCampo google_drive_folder_id
PDF (application/pdf)id_drive do arquivoNULLparents[0] (ID da pasta pai)
Imagem (image/*)NULLid_drive do arquivoparents[0] (ID da pasta pai)
Outros tipos (fallback)id_drive do arquivoNULLparents[0] (ID da pasta pai)

⚙️ Lógica do Backend (gerenciadorDadosRoute.js)

O backend orquestra o acesso ao banco de dados e aplica a lógica de negócio.

Padrão Crítico: Parser de Configuração INI

Problema: Senhas de banco de dados no arquivo .config.cfg podem conter o caractere #, que é interpretado como comentário por parsers padrão. Solução: SEMPRE utilize a função parseConfigFile presente na rota para ler as configurações de conexão.

// Exemplo de uso obrigatório
async function getConnection() {
const configPath = path.join(/*...*/, '.config.cfg');
const config = parseConfigFile(configPath); // <-- USA A FUNÇÃO CUSTOMIZADA
// ... usa a config para conectar
}

Endpoints Principais

GET /api/gerenciador-dados/arquivos-pendentes

  • Propósito: Lista arquivos do Google Drive que podem ser registrados.
  • Lógica Chave:
    1. Busca arquivos da tabela gerenciamento_googledrive.
    2. Para cada arquivo, verifica se seu id_drive já existe na coluna url_pdf ou url_jpg da tabela gerenciador_dados.
    3. Retorna a lista com um campo booleano ja_registrado.
    4. Implementa paginação com LIMIT e OFFSET para lidar com grandes volumes de dados.

POST /api/gerenciador-dados/registrar

  • Propósito: Registra um ou mais arquivos na tabela gerenciador_dados.
  • Lógica Chave:
    1. Recebe um array de objetos de arquivo.
    2. Para cada arquivo, determina se é PDF ou Imagem para preencher url_pdf ou url_jpg corretamente.
    3. Extrai o ID da pasta pai do campo parents.
    4. Executa uma verificação final de duplicatas antes de inserir.
    5. Insere o novo registro na tabela gerenciador_dados.

GET /api/gerenciador-dados/check-integrity

  • Propósito: Realiza verificações de consistência entre as tabelas.
  • Lógica Chave:
    • Modo Resumo: Se chamado sem parâmetros, retorna apenas a contagem de problemas em cada categoria.
    • Modo Detalhado: Se chamado com ?problemType=<tipo>, retorna uma lista paginada dos registros que apresentam aquele problema específico.
  • Verificações:
    • url_pdf_orfaos: url_pdf em gerenciador_dados que não existe em gerenciamento_googledrive.
    • url_jpg_orfaos: url_jpg em gerenciador_dados que não existe em gerenciamento_googledrive.
    • folder_id_orfaos: google_drive_folder_id em gerenciador_dados que não existe em gerenciamento_googledrive.
    • nao_catalogados: Arquivos em gerenciamento_googledrive que não estão em gerenciador_dados.

🖥️ Lógica do Frontend (gerenciadordedados.vue)

A interface reativa que consome os dados do backend.

Padrão Crítico: Reatividade com computed e ref

Utilize ref para estado reativo (filtros, página atual, dados brutos da API) e computed para dados derivados (listas filtradas, totais, estado de paginação).

Paginação e Filtragem Eficiente

Problema: A paginação era aplicada sobre a lista completa de dados, ignorando os filtros, o que causava inconsistências na UI. Solução: Encadeie computed properties para garantir a ordem correta das operações.

// 1. Dados brutos da API
const arquivosParaRegistro = ref<ArquivoDrive[]>([]);

// 2. Aplica filtros sobre os dados brutos
const arquivosAposFiltros = computed(() => {
return arquivosParaRegistro.value.filter(arquivo => {
// ... lógica de filtro aqui ...
});
});

// 3. Aplica paginação sobre a lista JÁ FILTRADA
const arquivosPaginados = computed(() => {
const start = (currentPage.value - 1) * itemsPerPage.value;
const end = start + itemsPerPage.value;
return arquivosAposFiltros.value.slice(start, end);
});

// 4. A UI renderiza `arquivosPaginados`
// 5. Os totais e o número de páginas são calculados com base em `arquivosAposFiltros.length`
const totalPages = computed(() => Math.ceil(arquivosAposFiltros.value.length / itemsPerPage.value));

Reset de Página ao Mudar Filtros

Problema: O usuário podia ficar em uma página que não existe mais após aplicar um filtro (ex: estava na página 5, mas o resultado filtrado só tem 1 página). Solução: Use watch para observar as variáveis de filtro e resetar a página atual para 1.

watch([filterColecao, filterTipo, searchQuery], () => {
currentPage.value = 1;
});

⚠️ Erros Comuns e Soluções

  1. Erro de Build: "Object is possibly 'null' or 'undefined'"

    • Causa: TypeScript detecta que uma variável pode ser nula. Comum ao acessar document.getElementById ou um ref de template antes de ser montado.
    • Solução: Use optional chaining (?.) ou adicione uma verificação de nulidade (if (variavel) { ... }).
  2. Erro de Template: Mismatched <div> tags

    • Causa: Um <div> extra ou ausente no template Vue.
    • Solução: Use a indentação do editor para inspecionar visualmente o aninhamento dos blocos e corrigir a estrutura.
  3. Erro de Backend: "Unknown column 'collections' in 'field list'"

    • Causa: A query SQL está tentando selecionar uma coluna collections que não existe.
    • Solução: Corrija a query para usar collections_json, que é o nome correto da coluna no banco de dados.
  4. Inconsistência de Dados: ja_registrado vs jaRegistrado

    • Causa: O backend retorna o campo no formato snake_case do banco de dados, mas o frontend espera camelCase.
    • Solução: Padronize a transformação no backend. Ao enviar dados para o frontend, converta os nomes dos campos para camelCase.
  5. Performance Lenta na Aba "Integridade"

    • Causa: A API /check-integrity estava buscando todos os registros detalhados de todos os problemas de uma só vez, causando timeouts com +25.000 registros.
    • Solução: Refatorar a API para o padrão Resumo/Detalhe, onde a chamada inicial busca apenas as contagens e chamadas subsequentes (e paginadas) buscam os detalhes de um problema específico.