Files
SteelBase/.kiro/specs/importador-inteligente-csv/design.md

21 KiB
Raw Blame History

Design Document

Overview

Sistema inteligente de importação de CSV com interface visual de mapeamento de colunas, sugestão automática baseada em similaridade de strings, memorização de perfis e validação de dados em tempo real.

Architecture

Componentes Principais

┌─────────────────────────────────────────────────────────┐
│                    Interface do Usuário                  │
├─────────────────────────────────────────────────────────┤
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐  │
│  │   Upload     │  │  Mapeamento  │  │  Validação   │  │
│  │     CSV      │  │   Visual     │  │   Preview    │  │
│  └──────────────┘  └──────────────┘  └──────────────┘  │
└─────────────────────────────────────────────────────────┘
                          ↓
┌─────────────────────────────────────────────────────────┐
│                  Motor de Processamento                  │
├─────────────────────────────────────────────────────────┤
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐  │
│  │   Parser     │  │  Sugestão    │  │  Validador   │  │
│  │     CSV      │  │  Automática  │  │   de Dados   │  │
│  └──────────────┘  └──────────────┘  └──────────────┘  │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐  │
│  │  Conversor   │  │  Calculador  │  │ Categorizador│  │
│  │  Unidades    │  │   Fórmulas   │  │  Automático  │  │
│  └──────────────┘  └──────────────┘  └──────────────┘  │
└─────────────────────────────────────────────────────────┘
                          ↓
┌─────────────────────────────────────────────────────────┐
│                 Camada de Persistência                   │
├─────────────────────────────────────────────────────────┤
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐  │
│  │  Perfis de   │  │    Banco     │  │   Metadata   │  │
│  │  Importação  │  │   de Dados   │  │  Importação  │  │
│  │ (localStorage)│  │(BANCO_DADOS) │  │(localStorage)│  │
│  └──────────────┘  └──────────────┘  └──────────────┘  │
└─────────────────────────────────────────────────────────┘

Components and Interfaces

1. CSVParser

Responsabilidade: Ler e parsear arquivos CSV

class CSVParser {
    /**
     * Parseia arquivo CSV e retorna estrutura de dados
     * @param {File} file - Arquivo CSV
     * @returns {Promise<ParsedCSV>}
     */
    async parse(file) {
        // Detecta encoding (UTF-8, ISO-8859-1)
        // Detecta delimitador (vírgula, ponto-e-vírgula, tab)
        // Parseia linhas e colunas
        // Retorna { headers, rows, metadata }
    }
    
    /**
     * Detecta tipos de dados de cada coluna
     * @param {Array} rows - Linhas de dados
     * @returns {Object} - Mapa coluna -> tipo
     */
    detectColumnTypes(rows) {
        // Analisa valores e infere tipo (number, string, date)
    }
}

2. ColumnMapper

Responsabilidade: Gerenciar mapeamento de colunas

class ColumnMapper {
    /**
     * Sugere mapeamento automático baseado em similaridade
     * @param {Array} csvHeaders - Cabeçalhos do CSV
     * @param {Array} systemFields - Campos do sistema
     * @returns {Object} - Mapa sugerido
     */
    suggestMapping(csvHeaders, systemFields) {
        // Usa algoritmo de similaridade (Levenshtein)
        // Considera sinônimos
        // Retorna mapeamento sugerido
    }
    
    /**
     * Valida mapeamento
     * @param {Object} mapping - Mapeamento atual
     * @returns {ValidationResult}
     */
    validateMapping(mapping) {
        // Verifica campos obrigatórios
        // Verifica tipos compatíveis
        // Retorna erros e avisos
    }
}

3. ImportProfile

Responsabilidade: Gerenciar perfis de importação salvos

class ImportProfile {
    /**
     * Salva perfil de importação
     * @param {string} materialType - Tipo de material
     * @param {Object} profile - Configuração do perfil
     */
    save(materialType, profile) {
        // Salva no localStorage
        // Inclui: mapeamento, conversões, regras
    }
    
    /**
     * Carrega perfil salvo
     * @param {string} materialType - Tipo de material
     * @returns {Object|null} - Perfil ou null
     */
    load(materialType) {
        // Carrega do localStorage
    }
    
    /**
     * Lista todos os perfis
     * @returns {Array} - Lista de perfis
     */
    listAll() {
        // Retorna todos os perfis salvos
    }
}

4. DataValidator

Responsabilidade: Validar dados antes da importação

class DataValidator {
    /**
     * Valida linha de dados
     * @param {Object} row - Linha de dados
     * @param {Object} schema - Schema esperado
     * @returns {ValidationResult}
     */
    validateRow(row, schema) {
        // Valida tipos
        // Valida ranges (min/max)
        // Valida campos obrigatórios
        // Retorna erros específicos
    }
    
    /**
     * Valida lote de dados
     * @param {Array} rows - Linhas de dados
     * @param {Object} schema - Schema esperado
     * @returns {BatchValidationResult}
     */
    validateBatch(rows, schema) {
        // Valida todas as linhas
        // Retorna estatísticas (válidas, inválidas)
        // Retorna lista de erros por linha
    }
}

5. UnitConverter

Responsabilidade: Converter unidades de medida

class UnitConverter {
    /**
     * Converte valor entre unidades
     * @param {number} value - Valor a converter
     * @param {string} fromUnit - Unidade origem
     * @param {string} toUnit - Unidade destino
     * @returns {number} - Valor convertido
     */
    convert(value, fromUnit, toUnit) {
        // Tabela de conversões
        // Aplica fator de conversão
    }
    
    /**
     * Detecta unidade de uma coluna
     * @param {Array} values - Valores da coluna
     * @param {string} columnName - Nome da coluna
     * @returns {string|null} - Unidade detectada
     */
    detectUnit(values, columnName) {
        // Analisa nome da coluna
        // Analisa range de valores
        // Retorna unidade provável
    }
}

6. FormulaCalculator

Responsabilidade: Calcular campos derivados

class FormulaCalculator {
    /**
     * Avalia fórmula
     * @param {string} formula - Fórmula a avaliar
     * @param {Object} context - Contexto com valores
     * @returns {number} - Resultado
     */
    evaluate(formula, context) {
        // Parseia fórmula
        // Valida sintaxe
        // Calcula resultado
    }
    
    /**
     * Valida fórmula
     * @param {string} formula - Fórmula a validar
     * @param {Array} availableFields - Campos disponíveis
     * @returns {ValidationResult}
     */
    validateFormula(formula, availableFields) {
        // Verifica sintaxe
        // Verifica campos existem
        // Retorna erros
    }
}

7. AutoCategorizer

Responsabilidade: Categorizar itens automaticamente

class AutoCategorizer {
    /**
     * Aplica regras de categorização
     * @param {Object} item - Item a categorizar
     * @param {Array} rules - Regras de categorização
     * @returns {string} - Categoria atribuída
     */
    categorize(item, rules) {
        // Avalia cada regra em ordem
        // Retorna primeira categoria que match
        // Retorna "Sem Categoria" se nenhuma match
    }
    
    /**
     * Cria regra de categorização
     * @param {Object} ruleConfig - Configuração da regra
     * @returns {Rule}
     */
    createRule(ruleConfig) {
        // Cria regra com condições
        // Suporta: >, <, =, !=, contains, range
    }
}

Data Models

ParsedCSV

{
    headers: ['coluna1', 'coluna2', ...],
    rows: [
        { coluna1: 'valor1', coluna2: 'valor2', ... },
        ...
    ],
    metadata: {
        encoding: 'UTF-8',
        delimiter: ',',
        rowCount: 100,
        columnTypes: {
            coluna1: 'string',
            coluna2: 'number',
            ...
        }
    }
}

ImportProfile

{
    id: 'perfis_hp_v1',
    materialType: 'perfis_hp',
    name: 'Perfis HP - Usiminas',
    createdAt: '2025-11-09T...',
    updatedAt: '2025-11-09T...',
    mapping: {
        'altura_mm': 'Altura (mm)',
        'aba_mm': 'Largura Aba',
        'peso_kg_m': 'Peso Linear',
        ...
    },
    conversions: {
        'altura_mm': { from: 'mm', to: 'mm' },
        'peso_kg_m': { from: 'lb/ft', to: 'kg/m', factor: 1.488 },
        ...
    },
    calculatedFields: {
        'area_cm2': {
            formula: 'peso_kg_m / 0.00785',
            description: 'Área calculada a partir do peso'
        }
    },
    categorizationRules: [
        {
            condition: 'altura_mm < 150',
            category: 'Pequeno'
        },
        {
            condition: 'altura_mm >= 150 AND altura_mm < 250',
            category: 'Médio'
        },
        ...
    ],
    requiredFields: ['nome', 'altura_mm', 'peso_kg_m'],
    optionalFields: ['momento_inercia_xx_cm4', ...]
}

ValidationResult

{
    valid: true/false,
    errors: [
        {
            row: 5,
            field: 'peso_kg_m',
            message: 'Valor deve ser numérico',
            value: 'abc'
        },
        ...
    ],
    warnings: [
        {
            row: 10,
            field: 'area_cm2',
            message: 'Valor fora do range esperado',
            value: 1000
        },
        ...
    ],
    statistics: {
        totalRows: 100,
        validRows: 95,
        invalidRows: 5,
        warningRows: 10
    }
}

Error Handling

Tipos de Erro

  1. ParseError: Erro ao ler CSV

    • Encoding inválido
    • Formato corrompido
    • Delimitador não detectado
  2. MappingError: Erro no mapeamento

    • Campo obrigatório não mapeado
    • Tipo incompatível
    • Coluna não encontrada
  3. ValidationError: Erro na validação

    • Tipo de dado incorreto
    • Valor fora do range
    • Campo obrigatório vazio
  4. ConversionError: Erro na conversão

    • Unidade não suportada
    • Valor não conversível
    • Fator de conversão inválido

Estratégia de Tratamento

try {
    // Processar importação
} catch (error) {
    if (error instanceof ParseError) {
        // Mostrar erro de parsing
        // Sugerir verificar formato do arquivo
    } else if (error instanceof MappingError) {
        // Destacar campos problemáticos
        // Permitir correção no mapeamento
    } else if (error instanceof ValidationError) {
        // Mostrar linhas com erro
        // Permitir importar apenas válidas
    } else if (error instanceof ConversionError) {
        // Mostrar erro de conversão
        // Permitir ajustar configuração
    }
}

Testing Strategy

Testes Unitários

  1. CSVParser

    • Testar parsing de diferentes formatos
    • Testar detecção de encoding
    • Testar detecção de tipos
  2. ColumnMapper

    • Testar sugestão de mapeamento
    • Testar validação de mapeamento
    • Testar similaridade de strings
  3. DataValidator

    • Testar validação de tipos
    • Testar validação de ranges
    • Testar campos obrigatórios
  4. UnitConverter

    • Testar conversões conhecidas
    • Testar detecção de unidades
    • Testar erros de conversão

Testes de Integração

  1. Fluxo Completo de Importação

    • Upload → Mapeamento → Validação → Importação
    • Testar com CSVs reais
    • Testar com perfis salvos
  2. Importação em Lote

    • Múltiplos arquivos
    • Diferentes tipos de materiais
    • Relatório consolidado

Testes de Interface

  1. Drag & Drop de Colunas

    • Arrastar coluna CSV para campo
    • Visual feedback
    • Desfazer mapeamento
  2. Preview de Dados

    • Mostrar valores originais
    • Mostrar valores convertidos
    • Mostrar valores calculados
  3. Validação em Tempo Real

    • Destacar erros
    • Mostrar estatísticas
    • Atualizar ao modificar mapeamento

Interface Design

Tela Principal de Importação

┌─────────────────────────────────────────────────────────────┐
│  📥 Importador Inteligente de CSV                           │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  1⃣ Selecionar Arquivo                                      │
│  ┌─────────────────────────────────────────────────────┐   │
│  │  📁 Escolher CSV...                                  │   │
│  │  ✅ tubos_rhs_fornecedor_x.csv (35 linhas, 15 cols) │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  2⃣ Tipo de Material                                        │
│  ┌─────────────────────────────────────────────────────┐   │
│  │  [Dropdown: Tubos RHS ▼]                            │   │
│  │  💾 Perfil salvo encontrado: "Fornecedor X"         │   │
│  │  [Usar Perfil] [Criar Novo]                         │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  3⃣ Mapeamento de Colunas                                   │
│  ┌─────────────────────────────────────────────────────┐   │
│  │  CSV                    →    Sistema                │   │
│  │  ─────────────────────────────────────────────────  │   │
│  │  📊 "Largura (mm)"      →    largura_mm ✅          │   │
│  │  📊 "Altura (mm)"       →    altura_mm ✅           │   │
│  │  📊 "Espessura"         →    espessura_mm ✅        │   │
│  │  📊 "Peso Linear"       →    peso_kg_m ✅           │   │
│  │     🔄 Converter: lb/ft → kg/m                      │   │
│  │  📊 "Aplicação"         →    aplicacao ✅           │   │
│  │  📊 "Coluna Extra"      →    [Ignorar] ⚠️           │   │
│  │                                                      │   │
│  │  ⚠️ Campo obrigatório não mapeado: tipo             │   │
│  │  💡 Sugestão: Criar regra de categorização          │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  4⃣ Preview e Validação                                     │
│  ┌─────────────────────────────────────────────────────┐   │
│  │  📊 Estatísticas:                                    │   │
│  │  • Total: 35 linhas                                 │   │
│  │  • Válidas: 33 ✅                                    │   │
│  │  • Com erro: 2 ❌                                    │   │
│  │  • Com aviso: 5 ⚠️                                   │   │
│  │                                                      │   │
│  │  [Ver Erros] [Ver Preview]                          │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  [Cancelar]  [💾 Salvar Perfil]  [📥 Importar Dados]       │
└─────────────────────────────────────────────────────────────┘

Modal de Mapeamento Visual

┌─────────────────────────────────────────────────────────────┐
│  🎯 Mapeamento Visual de Colunas                            │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  Arraste as colunas do CSV para os campos do sistema       │
│                                                             │
│  ┌──────────────────┐         ┌──────────────────┐         │
│  │  Colunas CSV     │         │  Campos Sistema  │         │
│  ├──────────────────┤         ├──────────────────┤         │
│  │ 📊 Largura       │────────→│ ✅ largura_mm    │         │
│  │ 📊 Altura        │────────→│ ✅ altura_mm     │         │
│  │ 📊 Espessura     │────────→│ ✅ espessura_mm  │         │
│  │ 📊 Peso Linear   │────────→│ ✅ peso_kg_m     │         │
│  │ 📊 Aplicação     │────────→│ ✅ aplicacao     │         │
│  │ 📊 Coluna Extra  │         │ ⚠️ tipo          │         │
│  │                  │         │    (obrigatório) │         │
│  └──────────────────┘         └──────────────────┘         │
│                                                             │
│  💡 Dica: Clique em "Sugerir Automático" para mapear       │
│                                                             │
│  [Sugerir Automático]  [Limpar Tudo]  [Confirmar]          │
└─────────────────────────────────────────────────────────────┘

Performance Considerations

  1. Parsing de CSV Grande

    • Usar Web Workers para não bloquear UI
    • Processar em chunks de 1000 linhas
    • Mostrar progresso
  2. Validação em Tempo Real

    • Debounce de 300ms ao modificar mapeamento
    • Validar apenas primeiras 100 linhas para preview
    • Validação completa apenas ao importar
  3. Armazenamento de Perfis

    • Comprimir perfis grandes (>100KB)
    • Limitar a 50 perfis salvos
    • Limpar perfis não usados há >6 meses
  4. Importação em Lote

    • Processar arquivos em paralelo (máx 3)
    • Usar IndexedDB para arquivos >5MB
    • Liberar memória após cada arquivo