# 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 ```javascript class CSVParser { /** * Parseia arquivo CSV e retorna estrutura de dados * @param {File} file - Arquivo CSV * @returns {Promise} */ 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 ```javascript 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 ```javascript 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 ```javascript 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 ```javascript 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 ```javascript 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 ```javascript 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 ```javascript { headers: ['coluna1', 'coluna2', ...], rows: [ { coluna1: 'valor1', coluna2: 'valor2', ... }, ... ], metadata: { encoding: 'UTF-8', delimiter: ',', rowCount: 100, columnTypes: { coluna1: 'string', coluna2: 'number', ... } } } ``` ### ImportProfile ```javascript { 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 ```javascript { 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 ```javascript 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