Initial commit SteelBase - Oficiais e Funcionando
This commit is contained in:
566
.kiro/specs/importador-inteligente-csv/design.md
Normal file
566
.kiro/specs/importador-inteligente-csv/design.md
Normal file
@@ -0,0 +1,566 @@
|
||||
# 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<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
|
||||
|
||||
```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
|
||||
137
.kiro/specs/importador-inteligente-csv/requirements.md
Normal file
137
.kiro/specs/importador-inteligente-csv/requirements.md
Normal file
@@ -0,0 +1,137 @@
|
||||
# Requirements Document
|
||||
|
||||
## Introduction
|
||||
|
||||
Sistema inteligente de importação de CSV que permite ao usuário mapear colunas de forma visual e memoriza as configurações para futuras importações automáticas.
|
||||
|
||||
## Glossary
|
||||
|
||||
- **CSV**: Arquivo de valores separados por vírgula contendo dados tabulares
|
||||
- **Mapeamento de Colunas**: Correlação entre colunas do CSV e campos do sistema
|
||||
- **Perfil de Importação**: Configuração salva de mapeamento para um tipo específico de material
|
||||
- **Campo Obrigatório**: Campo que deve ser preenchido para importação válida
|
||||
- **Campo Opcional**: Campo que pode ficar vazio sem impedir a importação
|
||||
- **Sistema**: Aplicação AÇO CALC PRO
|
||||
- **Usuário**: Engenheiro ou técnico que importa dados de materiais
|
||||
|
||||
## Requirements
|
||||
|
||||
### Requirement 1
|
||||
|
||||
**User Story:** Como usuário, quero importar um CSV com qualquer estrutura de colunas, para que eu possa usar dados de diferentes fornecedores sem precisar reformatar os arquivos.
|
||||
|
||||
#### Acceptance Criteria
|
||||
|
||||
1. WHEN o usuário seleciona um arquivo CSV, THE Sistema SHALL detectar automaticamente todas as colunas presentes
|
||||
2. WHEN o Sistema detecta as colunas, THE Sistema SHALL exibir uma interface de mapeamento visual
|
||||
3. WHEN o usuário visualiza o mapeamento, THE Sistema SHALL mostrar preview dos dados de cada coluna
|
||||
4. WHERE existe um perfil de importação salvo, THE Sistema SHALL aplicar o mapeamento automaticamente
|
||||
5. IF o CSV tem colunas não mapeadas, THEN THE Sistema SHALL permitir que o usuário as ignore ou mapeie
|
||||
|
||||
### Requirement 2
|
||||
|
||||
**User Story:** Como usuário, quero mapear visualmente as colunas do CSV para os campos do sistema, para que eu possa garantir que os dados sejam importados corretamente.
|
||||
|
||||
#### Acceptance Criteria
|
||||
|
||||
1. THE Sistema SHALL exibir lado a lado as colunas do CSV e os campos esperados
|
||||
2. WHEN o usuário arrasta uma coluna CSV, THE Sistema SHALL permitir soltar sobre um campo do sistema
|
||||
3. WHEN o usuário mapeia uma coluna, THE Sistema SHALL mostrar preview dos valores que serão importados
|
||||
4. THE Sistema SHALL destacar campos obrigatórios que ainda não foram mapeados
|
||||
5. WHEN todos os campos obrigatórios estão mapeados, THE Sistema SHALL habilitar o botão de importação
|
||||
|
||||
### Requirement 3
|
||||
|
||||
**User Story:** Como usuário, quero que o sistema sugira automaticamente o mapeamento de colunas, para que eu economize tempo em importações repetitivas.
|
||||
|
||||
#### Acceptance Criteria
|
||||
|
||||
1. WHEN o Sistema detecta colunas do CSV, THE Sistema SHALL comparar nomes com campos conhecidos
|
||||
2. WHEN existe similaridade entre nomes, THE Sistema SHALL sugerir mapeamento automático
|
||||
3. THE Sistema SHALL usar algoritmo de similaridade de strings (Levenshtein ou similar)
|
||||
4. WHEN o Sistema sugere mapeamento, THE Sistema SHALL permitir que o usuário aceite ou modifique
|
||||
5. THE Sistema SHALL considerar sinônimos comuns (ex: "diametro" = "diameter" = "diam")
|
||||
|
||||
### Requirement 4
|
||||
|
||||
**User Story:** Como usuário, quero que o sistema memorize meus mapeamentos de colunas, para que importações futuras do mesmo tipo sejam automáticas.
|
||||
|
||||
#### Acceptance Criteria
|
||||
|
||||
1. WHEN o usuário completa um mapeamento, THE Sistema SHALL salvar o perfil no localStorage
|
||||
2. THE Sistema SHALL associar o perfil ao tipo de material (cantoneiras, tubos, etc)
|
||||
3. WHEN o usuário importa novamente o mesmo tipo, THE Sistema SHALL aplicar o perfil automaticamente
|
||||
4. THE Sistema SHALL permitir que o usuário edite ou delete perfis salvos
|
||||
5. THE Sistema SHALL exportar/importar perfis de mapeamento em JSON
|
||||
|
||||
### Requirement 5
|
||||
|
||||
**User Story:** Como usuário, quero validar os dados antes da importação, para que eu possa corrigir erros antes de salvar no banco de dados.
|
||||
|
||||
#### Acceptance Criteria
|
||||
|
||||
1. WHEN o usuário mapeia as colunas, THE Sistema SHALL validar tipos de dados (números, texto)
|
||||
2. WHEN existe erro de tipo, THE Sistema SHALL destacar a linha com erro
|
||||
3. THE Sistema SHALL mostrar estatísticas de validação (X linhas válidas, Y com erro)
|
||||
4. WHEN o usuário confirma importação, THE Sistema SHALL importar apenas linhas válidas
|
||||
5. THE Sistema SHALL gerar relatório de erros com linhas que falharam
|
||||
|
||||
### Requirement 6
|
||||
|
||||
**User Story:** Como usuário, quero converter unidades automaticamente durante a importação, para que eu possa usar CSVs com diferentes sistemas de medida.
|
||||
|
||||
#### Acceptance Criteria
|
||||
|
||||
1. WHEN o Sistema detecta coluna numérica, THE Sistema SHALL permitir especificar unidade
|
||||
2. THE Sistema SHALL suportar conversões: mm↔pol, kg↔lb, MPa↔ksi
|
||||
3. WHEN o usuário seleciona conversão, THE Sistema SHALL aplicar fator de conversão automaticamente
|
||||
4. THE Sistema SHALL mostrar preview dos valores convertidos
|
||||
5. THE Sistema SHALL salvar preferência de conversão no perfil de importação
|
||||
|
||||
### Requirement 7
|
||||
|
||||
**User Story:** Como usuário, quero criar campos calculados durante a importação, para que eu possa derivar dados que não estão no CSV.
|
||||
|
||||
#### Acceptance Criteria
|
||||
|
||||
1. THE Sistema SHALL permitir criar campos calculados usando fórmulas
|
||||
2. WHEN o usuário cria fórmula, THE Sistema SHALL validar sintaxe
|
||||
3. THE Sistema SHALL suportar operações: +, -, *, /, potência, raiz
|
||||
4. WHEN a fórmula é válida, THE Sistema SHALL calcular valores automaticamente
|
||||
5. THE Sistema SHALL mostrar preview dos valores calculados
|
||||
|
||||
### Requirement 8
|
||||
|
||||
**User Story:** Como usuário, quero categorizar automaticamente os itens durante a importação, para que eu não precise adicionar manualmente a categoria de cada item.
|
||||
|
||||
#### Acceptance Criteria
|
||||
|
||||
1. THE Sistema SHALL permitir definir regras de categorização
|
||||
2. WHEN o usuário define regra, THE Sistema SHALL usar condições (SE...ENTÃO)
|
||||
3. THE Sistema SHALL suportar condições baseadas em valores numéricos e texto
|
||||
4. WHEN a regra é aplicada, THE Sistema SHALL atribuir categoria automaticamente
|
||||
5. THE Sistema SHALL mostrar preview das categorias atribuídas
|
||||
|
||||
### Requirement 9
|
||||
|
||||
**User Story:** Como usuário, quero importar múltiplos CSVs de uma vez, para que eu possa atualizar todo o banco de dados rapidamente.
|
||||
|
||||
#### Acceptance Criteria
|
||||
|
||||
1. THE Sistema SHALL permitir selecionar múltiplos arquivos CSV
|
||||
2. WHEN múltiplos arquivos são selecionados, THE Sistema SHALL processar em lote
|
||||
3. THE Sistema SHALL aplicar perfil de importação correspondente a cada arquivo
|
||||
4. THE Sistema SHALL mostrar progresso de importação em tempo real
|
||||
5. WHEN a importação em lote termina, THE Sistema SHALL gerar relatório consolidado
|
||||
|
||||
### Requirement 10
|
||||
|
||||
**User Story:** Como usuário, quero exportar o banco de dados atual para CSV, para que eu possa fazer backup ou compartilhar dados.
|
||||
|
||||
#### Acceptance Criteria
|
||||
|
||||
1. THE Sistema SHALL permitir exportar cada tipo de material para CSV
|
||||
2. WHEN o usuário exporta, THE Sistema SHALL incluir todas as colunas do banco
|
||||
3. THE Sistema SHALL usar formato compatível com reimportação
|
||||
4. THE Sistema SHALL permitir exportar todos os tipos de uma vez (ZIP)
|
||||
5. THE Sistema SHALL incluir metadata (data de exportação, versão)
|
||||
419
.kiro/specs/sistema-cache-perfis/design.md
Normal file
419
.kiro/specs/sistema-cache-perfis/design.md
Normal file
@@ -0,0 +1,419 @@
|
||||
# Design Document - Sistema de Cache de Perfis
|
||||
|
||||
## Overview
|
||||
|
||||
Sistema de cache intermediário usando IndexedDB para armazenar dados de perfis estruturais. O sistema fornece uma camada de abstração entre os arquivos CSV originais e o aplicativo, permitindo carregamento rápido, sincronização sob demanda, e gerenciamento flexível de fontes de dados.
|
||||
|
||||
## Architecture
|
||||
|
||||
### High-Level Architecture
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────┐
|
||||
│ Application Layer │
|
||||
│ (UI Components, Sections, Calculations) │
|
||||
└────────────────────┬────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────┐
|
||||
│ Data Service API │
|
||||
│ getPerfis() | searchPerfis() | getPerfilById() │
|
||||
└────────────────────┬────────────────────────────────────┘
|
||||
│
|
||||
┌────────────┴────────────┐
|
||||
▼ ▼
|
||||
┌──────────────┐ ┌──────────────┐
|
||||
│ Cache Layer │ │ CSV Loader │
|
||||
│ (IndexedDB) │◄────────►│ (Fetch API) │
|
||||
└──────────────┘ └──────────────┘
|
||||
│ │
|
||||
▼ ▼
|
||||
┌──────────────┐ ┌──────────────┐
|
||||
│ Browser │ │ BD/perfis/ │
|
||||
│ Storage │ │ *.csv │
|
||||
└──────────────┘ └──────────────┘
|
||||
```
|
||||
|
||||
### Component Diagram
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────┐
|
||||
│ CacheManager │
|
||||
│ - init() │
|
||||
│ - checkHealth() │
|
||||
│ - clearAll() │
|
||||
└────────────────────┬────────────────────────────────────┘
|
||||
│
|
||||
┌────────────┼────────────┬────────────┐
|
||||
▼ ▼ ▼ ▼
|
||||
┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
|
||||
│ DataStore│ │SyncManager│ │CSVParser │ │DataService│
|
||||
│ │ │ │ │ │ │ │
|
||||
│ -get() │ │ -sync() │ │ -parse() │ │ -query() │
|
||||
│ -set() │ │ -check() │ │ -validate│ │ -filter()│
|
||||
│ -delete()│ │ -update()│ │ │ │ -search()│
|
||||
└──────────┘ └──────────┘ └──────────┘ └──────────┘
|
||||
```
|
||||
|
||||
## Components and Interfaces
|
||||
|
||||
### 1. CacheManager (Core)
|
||||
|
||||
**Responsabilidade:** Gerenciar ciclo de vida do cache e coordenar componentes
|
||||
|
||||
```javascript
|
||||
class CacheManager {
|
||||
constructor(config) {
|
||||
this.dbName = 'AcoCalcProDB';
|
||||
this.version = 1;
|
||||
this.db = null;
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
async init() {
|
||||
// Inicializar IndexedDB
|
||||
// Criar object stores
|
||||
// Verificar versão
|
||||
}
|
||||
|
||||
async checkHealth() {
|
||||
// Verificar integridade do cache
|
||||
// Retornar estatísticas
|
||||
}
|
||||
|
||||
async clearAll() {
|
||||
// Limpar todo o cache
|
||||
}
|
||||
|
||||
getStats() {
|
||||
// Retornar estatísticas de uso
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2. DataStore (Storage Layer)
|
||||
|
||||
**Responsabilidade:** Interface com IndexedDB
|
||||
|
||||
```javascript
|
||||
class DataStore {
|
||||
constructor(db) {
|
||||
this.db = db;
|
||||
}
|
||||
|
||||
async get(storeName, key) {
|
||||
// Buscar item por chave
|
||||
}
|
||||
|
||||
async getAll(storeName) {
|
||||
// Buscar todos os itens
|
||||
}
|
||||
|
||||
async set(storeName, data) {
|
||||
// Armazenar dados
|
||||
}
|
||||
|
||||
async delete(storeName, key) {
|
||||
// Deletar item
|
||||
}
|
||||
|
||||
async clear(storeName) {
|
||||
// Limpar store
|
||||
}
|
||||
|
||||
async count(storeName) {
|
||||
// Contar itens
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3. SyncManager (Synchronization)
|
||||
|
||||
**Responsabilidade:** Sincronizar dados entre CSV e cache
|
||||
|
||||
```javascript
|
||||
class SyncManager {
|
||||
constructor(dataStore, csvParser) {
|
||||
this.dataStore = dataStore;
|
||||
this.csvParser = csvParser;
|
||||
this.sources = {}; // Mapeamento tipo -> caminho CSV
|
||||
}
|
||||
|
||||
async syncAll(progressCallback) {
|
||||
// Sincronizar todos os tipos
|
||||
}
|
||||
|
||||
async syncType(tipo, progressCallback) {
|
||||
// Sincronizar tipo específico
|
||||
}
|
||||
|
||||
async checkUpdates() {
|
||||
// Verificar se há atualizações disponíveis
|
||||
}
|
||||
|
||||
async getLastSync(tipo) {
|
||||
// Retornar timestamp da última sincronização
|
||||
}
|
||||
|
||||
async calculateHash(csvText) {
|
||||
// Calcular hash MD5 do CSV
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 4. CSVParser (Data Processing)
|
||||
|
||||
**Responsabilidade:** Parse e validação de arquivos CSV
|
||||
|
||||
```javascript
|
||||
class CSVParser {
|
||||
async parse(csvText, schema) {
|
||||
// Parse CSV para objetos
|
||||
// Validar contra schema
|
||||
// Retornar dados processados
|
||||
}
|
||||
|
||||
validate(data, schema) {
|
||||
// Validar estrutura dos dados
|
||||
}
|
||||
|
||||
transform(data, transformFn) {
|
||||
// Aplicar transformações
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 5. DataService (API Layer)
|
||||
|
||||
**Responsabilidade:** API pública para acesso aos dados
|
||||
|
||||
```javascript
|
||||
class DataService {
|
||||
constructor(cacheManager, syncManager) {
|
||||
this.cache = cacheManager;
|
||||
this.sync = syncManager;
|
||||
}
|
||||
|
||||
async getPerfis(tipo, options = {}) {
|
||||
// Buscar perfis do cache ou CSV
|
||||
// options: { forceRefresh, includeMetadata }
|
||||
}
|
||||
|
||||
async searchPerfis(tipo, filters) {
|
||||
// Buscar com filtros
|
||||
// filters: { nome, peso_min, peso_max, etc }
|
||||
}
|
||||
|
||||
async getPerfilById(tipo, id) {
|
||||
// Buscar perfil específico
|
||||
}
|
||||
|
||||
async getMetadata(tipo) {
|
||||
// Retornar metadados (última sync, count, etc)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Data Models
|
||||
|
||||
### IndexedDB Schema
|
||||
|
||||
```javascript
|
||||
const DB_SCHEMA = {
|
||||
name: 'AcoCalcProDB',
|
||||
version: 1,
|
||||
stores: {
|
||||
// Store para cada tipo de perfil
|
||||
cantoneiras: {
|
||||
keyPath: 'id',
|
||||
indexes: [
|
||||
{ name: 'nome', keyPath: 'nome', unique: false },
|
||||
{ name: 'tipo', keyPath: 'tipo', unique: false },
|
||||
{ name: 'peso_kg_m', keyPath: 'peso_kg_m', unique: false }
|
||||
]
|
||||
},
|
||||
perfis_w: {
|
||||
keyPath: 'id',
|
||||
indexes: [
|
||||
{ name: 'nome', keyPath: 'nome', unique: false },
|
||||
{ name: 'peso', keyPath: 'peso', unique: false }
|
||||
]
|
||||
},
|
||||
// ... outros tipos
|
||||
|
||||
// Store para metadados
|
||||
_metadata: {
|
||||
keyPath: 'tipo',
|
||||
indexes: []
|
||||
},
|
||||
|
||||
// Store para configuração
|
||||
_config: {
|
||||
keyPath: 'key',
|
||||
indexes: []
|
||||
}
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
### Metadata Model
|
||||
|
||||
```javascript
|
||||
{
|
||||
tipo: 'cantoneiras',
|
||||
lastSync: 1699564800000, // timestamp
|
||||
hash: 'a1b2c3d4e5f6...', // MD5 hash do CSV
|
||||
count: 39,
|
||||
version: '1.0',
|
||||
source: 'BD/perfis/cantoneiras_brasil_completo.csv',
|
||||
size: 12345 // bytes
|
||||
}
|
||||
```
|
||||
|
||||
### Config Model
|
||||
|
||||
```javascript
|
||||
{
|
||||
key: 'csv_sources',
|
||||
value: {
|
||||
cantoneiras: 'BD/perfis/cantoneiras_brasil_completo.csv',
|
||||
perfis_w: 'BD/perfis/perfis_w_brasil_completo.csv',
|
||||
// ... outros
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Error Handling
|
||||
|
||||
### Error Types
|
||||
|
||||
```javascript
|
||||
class CacheError extends Error {
|
||||
constructor(message, code, details) {
|
||||
super(message);
|
||||
this.name = 'CacheError';
|
||||
this.code = code;
|
||||
this.details = details;
|
||||
}
|
||||
}
|
||||
|
||||
// Códigos de erro
|
||||
const ERROR_CODES = {
|
||||
DB_NOT_AVAILABLE: 'DB_NOT_AVAILABLE',
|
||||
SYNC_FAILED: 'SYNC_FAILED',
|
||||
CSV_PARSE_ERROR: 'CSV_PARSE_ERROR',
|
||||
DATA_NOT_FOUND: 'DATA_NOT_FOUND',
|
||||
QUOTA_EXCEEDED: 'QUOTA_EXCEEDED'
|
||||
};
|
||||
```
|
||||
|
||||
### Fallback Strategy
|
||||
|
||||
```
|
||||
1. Tentar carregar do cache
|
||||
↓ (falha)
|
||||
2. Tentar carregar do CSV
|
||||
↓ (falha)
|
||||
3. Usar dados em memória (se disponível)
|
||||
↓ (falha)
|
||||
4. Exibir erro ao usuário
|
||||
```
|
||||
|
||||
## Testing Strategy
|
||||
|
||||
### Unit Tests
|
||||
|
||||
- DataStore: CRUD operations
|
||||
- CSVParser: Parse e validação
|
||||
- SyncManager: Lógica de sincronização
|
||||
- DataService: API pública
|
||||
|
||||
### Integration Tests
|
||||
|
||||
- Fluxo completo: CSV → Cache → UI
|
||||
- Sincronização com múltiplos tipos
|
||||
- Fallback quando IndexedDB não disponível
|
||||
|
||||
### Performance Tests
|
||||
|
||||
- Tempo de carregamento do cache
|
||||
- Tempo de sincronização
|
||||
- Uso de memória
|
||||
- Tamanho do banco de dados
|
||||
|
||||
## Migration Strategy
|
||||
|
||||
### Phase 1: Implementação Base
|
||||
- Criar estrutura do cache
|
||||
- Implementar DataStore e CSVParser
|
||||
- Testes unitários
|
||||
|
||||
### Phase 2: Integração
|
||||
- Integrar com código existente
|
||||
- Manter compatibilidade
|
||||
- Testes de integração
|
||||
|
||||
### Phase 3: UI Admin
|
||||
- Painel de administração
|
||||
- Botões de sincronização
|
||||
- Estatísticas
|
||||
|
||||
### Phase 4: Otimizações
|
||||
- Web Workers para parsing
|
||||
- Compressão de dados
|
||||
- Lazy loading
|
||||
|
||||
## Configuration
|
||||
|
||||
### Default Configuration
|
||||
|
||||
```javascript
|
||||
const DEFAULT_CONFIG = {
|
||||
dbName: 'AcoCalcProDB',
|
||||
version: 1,
|
||||
autoSync: false, // Sincronizar automaticamente na inicialização
|
||||
syncInterval: null, // Intervalo de sincronização automática (ms)
|
||||
cacheExpiry: 7 * 24 * 60 * 60 * 1000, // 7 dias
|
||||
enableCompression: false,
|
||||
enableWebWorkers: false,
|
||||
debug: false,
|
||||
sources: {
|
||||
cantoneiras: 'BD/perfis/cantoneiras_brasil_completo.csv',
|
||||
barras: 'BD/perfis/barras_brasil_completo.csv',
|
||||
// ... outros
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
## Performance Considerations
|
||||
|
||||
### Optimization Techniques
|
||||
|
||||
1. **Indexing**: Criar índices para campos frequentemente buscados
|
||||
2. **Lazy Loading**: Carregar apenas dados necessários
|
||||
3. **Compression**: Comprimir dados grandes antes de armazenar
|
||||
4. **Web Workers**: Parse de CSV em background thread
|
||||
5. **Batch Operations**: Inserir múltiplos registros de uma vez
|
||||
|
||||
### Expected Performance
|
||||
|
||||
- Cache hit: < 100ms
|
||||
- Cache miss + CSV load: < 2s
|
||||
- Sync all types: < 10s
|
||||
- Search with filters: < 50ms
|
||||
|
||||
## Security Considerations
|
||||
|
||||
- IndexedDB é isolado por origem (same-origin policy)
|
||||
- Dados não são criptografados (não contêm informações sensíveis)
|
||||
- Validar dados do CSV antes de armazenar
|
||||
- Limitar tamanho máximo do cache (50MB)
|
||||
|
||||
## Future Enhancements
|
||||
|
||||
1. **Sync com servidor remoto**: Permitir sincronizar com API REST
|
||||
2. **Versionamento de dados**: Manter histórico de versões
|
||||
3. **Diff e merge**: Detectar conflitos entre versões
|
||||
4. **Export/Import**: Exportar cache para backup
|
||||
5. **Compression**: Comprimir dados automaticamente
|
||||
6. **Service Worker**: Cache de arquivos CSV para offline completo
|
||||
152
.kiro/specs/sistema-cache-perfis/requirements.md
Normal file
152
.kiro/specs/sistema-cache-perfis/requirements.md
Normal file
@@ -0,0 +1,152 @@
|
||||
# Requirements Document - Sistema de Cache de Perfis
|
||||
|
||||
## Introduction
|
||||
|
||||
Sistema de cache intermediário para armazenar dados de perfis estruturais carregados de arquivos CSV. O sistema permitirá carregar dados uma vez, armazená-los localmente no navegador (IndexedDB), e fornecer uma interface para atualizar/sincronizar quando os arquivos CSV forem modificados.
|
||||
|
||||
## Glossary
|
||||
|
||||
- **IndexedDB**: Banco de dados NoSQL do navegador para armazenamento local persistente
|
||||
- **CSV Source**: Arquivos CSV originais em `BD/perfis/`
|
||||
- **Cache Layer**: Camada intermediária que armazena dados processados
|
||||
- **Sync Manager**: Componente responsável por sincronizar dados entre CSV e cache
|
||||
- **Data Service**: API unificada para acesso aos dados de perfis
|
||||
- **Admin Panel**: Interface administrativa para gerenciar o cache
|
||||
|
||||
## Requirements
|
||||
|
||||
### Requirement 1: Armazenamento Local com IndexedDB
|
||||
|
||||
**User Story:** Como desenvolvedor, quero armazenar dados de perfis localmente no navegador, para que o aplicativo não precise carregar CSVs repetidamente.
|
||||
|
||||
#### Acceptance Criteria
|
||||
|
||||
1. WHEN o aplicativo inicializa, THE Sistema SHALL criar um banco IndexedDB chamado "AcoCalcProDB"
|
||||
2. THE Sistema SHALL criar object stores separadas para cada tipo de perfil (cantoneiras, perfis_w, perfis_i, etc.)
|
||||
3. THE Sistema SHALL armazenar metadados incluindo timestamp de última atualização e versão dos dados
|
||||
4. THE Sistema SHALL persistir dados entre sessões do navegador
|
||||
5. THE Sistema SHALL suportar até 50MB de dados armazenados
|
||||
|
||||
### Requirement 2: Carregamento Inteligente de Dados
|
||||
|
||||
**User Story:** Como usuário, quero que o aplicativo carregue dados rapidamente, para que eu não precise esperar toda vez que abrir uma seção.
|
||||
|
||||
#### Acceptance Criteria
|
||||
|
||||
1. WHEN o usuário acessa uma seção de perfil, THE Sistema SHALL verificar se dados existem no cache local
|
||||
2. IF dados existem no cache, THEN THE Sistema SHALL carregar do cache em menos de 100ms
|
||||
3. IF dados não existem no cache, THEN THE Sistema SHALL carregar do CSV e armazenar no cache
|
||||
4. THE Sistema SHALL exibir indicador de loading durante carregamento inicial
|
||||
5. THE Sistema SHALL funcionar offline após primeiro carregamento
|
||||
|
||||
### Requirement 3: Interface de Sincronização
|
||||
|
||||
**User Story:** Como administrador, quero atualizar os dados do cache quando modificar arquivos CSV, para que as alterações sejam refletidas no aplicativo.
|
||||
|
||||
#### Acceptance Criteria
|
||||
|
||||
1. THE Sistema SHALL fornecer botão "🔄 Atualizar Dados" no painel administrativo
|
||||
2. WHEN usuário clica em atualizar, THE Sistema SHALL recarregar todos os CSVs
|
||||
3. THE Sistema SHALL mostrar progresso da sincronização (0-100%)
|
||||
4. THE Sistema SHALL exibir timestamp da última sincronização
|
||||
5. THE Sistema SHALL permitir atualização seletiva por tipo de perfil
|
||||
|
||||
### Requirement 4: Versionamento e Validação
|
||||
|
||||
**User Story:** Como desenvolvedor, quero detectar quando dados estão desatualizados, para que o sistema possa atualizar automaticamente.
|
||||
|
||||
#### Acceptance Criteria
|
||||
|
||||
1. THE Sistema SHALL armazenar hash MD5 de cada arquivo CSV
|
||||
2. WHEN aplicativo inicializa, THE Sistema SHALL comparar hashes dos arquivos
|
||||
3. IF hash mudou, THEN THE Sistema SHALL marcar dados como desatualizados
|
||||
4. THE Sistema SHALL exibir notificação quando dados estiverem desatualizados
|
||||
5. THE Sistema SHALL permitir configurar atualização automática ou manual
|
||||
|
||||
### Requirement 5: API Unificada de Acesso
|
||||
|
||||
**User Story:** Como desenvolvedor, quero uma API simples para acessar dados, para que não precise me preocupar se vêm do cache ou CSV.
|
||||
|
||||
#### Acceptance Criteria
|
||||
|
||||
1. THE Sistema SHALL fornecer função `getPerfis(tipo)` que retorna dados do cache ou CSV
|
||||
2. THE Sistema SHALL fornecer função `searchPerfis(tipo, filtros)` para busca com filtros
|
||||
3. THE Sistema SHALL fornecer função `getPerfilById(tipo, id)` para busca por ID
|
||||
4. THE Sistema SHALL retornar Promises para todas operações assíncronas
|
||||
5. THE Sistema SHALL tratar erros gracefully com fallback para CSV
|
||||
|
||||
### Requirement 6: Gerenciamento de Espaço
|
||||
|
||||
**User Story:** Como usuário, quero gerenciar o espaço usado pelo cache, para que não ocupe muito armazenamento do navegador.
|
||||
|
||||
#### Acceptance Criteria
|
||||
|
||||
1. THE Sistema SHALL exibir espaço total usado pelo cache no painel admin
|
||||
2. THE Sistema SHALL permitir limpar cache de tipos específicos de perfis
|
||||
3. THE Sistema SHALL permitir limpar todo o cache com um botão
|
||||
4. THE Sistema SHALL avisar quando espaço disponível for menor que 10MB
|
||||
5. THE Sistema SHALL funcionar mesmo se IndexedDB não estiver disponível (fallback para CSV)
|
||||
|
||||
### Requirement 7: Migração e Compatibilidade
|
||||
|
||||
**User Story:** Como desenvolvedor, quero migrar dados existentes para o novo sistema, para que não haja perda de funcionalidade.
|
||||
|
||||
#### Acceptance Criteria
|
||||
|
||||
1. THE Sistema SHALL detectar se é primeira execução
|
||||
2. WHEN primeira execução, THE Sistema SHALL carregar todos os CSVs e popular cache
|
||||
3. THE Sistema SHALL manter compatibilidade com código existente
|
||||
4. THE Sistema SHALL permitir desabilitar cache via configuração
|
||||
5. THE Sistema SHALL migrar automaticamente entre versões do schema
|
||||
|
||||
### Requirement 8: Monitoramento e Debug
|
||||
|
||||
**User Story:** Como desenvolvedor, quero monitorar operações do cache, para que possa debugar problemas.
|
||||
|
||||
#### Acceptance Criteria
|
||||
|
||||
1. THE Sistema SHALL logar todas operações de cache no console (modo debug)
|
||||
2. THE Sistema SHALL exibir estatísticas de hit/miss do cache
|
||||
3. THE Sistema SHALL permitir exportar dados do cache para JSON
|
||||
4. THE Sistema SHALL permitir importar dados de JSON para cache
|
||||
5. THE Sistema SHALL fornecer ferramenta de diagnóstico no painel admin
|
||||
|
||||
### Requirement 9: Performance e Otimização
|
||||
|
||||
**User Story:** Como usuário, quero que o aplicativo seja rápido, para que eu possa trabalhar eficientemente.
|
||||
|
||||
#### Acceptance Criteria
|
||||
|
||||
1. THE Sistema SHALL carregar dados do cache em menos de 100ms
|
||||
2. THE Sistema SHALL indexar campos comuns (nome, tipo) para busca rápida
|
||||
3. THE Sistema SHALL usar Web Workers para parsing de CSV em background
|
||||
4. THE Sistema SHALL implementar lazy loading para perfis não utilizados
|
||||
5. THE Sistema SHALL comprimir dados antes de armazenar (se >1MB)
|
||||
|
||||
### Requirement 10: Configuração Flexível de Fontes
|
||||
|
||||
**User Story:** Como administrador, quero configurar caminhos dos arquivos CSV, para que possa reorganizar estrutura de pastas.
|
||||
|
||||
#### Acceptance Criteria
|
||||
|
||||
1. THE Sistema SHALL permitir configurar caminho base dos CSVs no painel admin
|
||||
2. THE Sistema SHALL permitir configurar nome de arquivo para cada tipo de perfil
|
||||
3. THE Sistema SHALL validar se arquivos existem antes de tentar carregar
|
||||
4. THE Sistema SHALL salvar configuração no localStorage
|
||||
5. THE Sistema SHALL fornecer configuração padrão funcional
|
||||
|
||||
## Technical Constraints
|
||||
|
||||
- Deve funcionar em navegadores modernos (Chrome 60+, Firefox 60+, Safari 12+, Edge 79+)
|
||||
- Deve usar apenas JavaScript vanilla (sem frameworks)
|
||||
- Deve ser compatível com código existente
|
||||
- Deve funcionar offline após primeiro carregamento
|
||||
- Deve ter fallback para CSV se IndexedDB não disponível
|
||||
|
||||
## Non-Functional Requirements
|
||||
|
||||
- **Performance**: Carregamento do cache < 100ms
|
||||
- **Reliability**: Taxa de sucesso > 99.9%
|
||||
- **Usability**: Interface intuitiva no painel admin
|
||||
- **Maintainability**: Código modular e bem documentado
|
||||
- **Scalability**: Suportar até 10.000 registros por tipo de perfil
|
||||
168
.kiro/specs/sistema-cache-perfis/tasks.md
Normal file
168
.kiro/specs/sistema-cache-perfis/tasks.md
Normal file
@@ -0,0 +1,168 @@
|
||||
# Implementation Plan - Sistema de Cache de Perfis
|
||||
|
||||
## Overview
|
||||
|
||||
Este plano implementa um sistema de cache intermediário usando IndexedDB para armazenar dados de perfis estruturais, permitindo carregamento rápido, sincronização sob demanda, e gerenciamento flexível de fontes de dados.
|
||||
|
||||
## Tasks
|
||||
|
||||
- [ ] 1. Criar estrutura base do sistema de cache
|
||||
|
||||
|
||||
- Criar arquivo `js/core/cache-manager.js` com classe CacheManager
|
||||
- Implementar inicialização do IndexedDB
|
||||
- Criar schema do banco de dados com stores para cada tipo de perfil
|
||||
- Implementar tratamento de erros e fallback
|
||||
- _Requirements: 1.1, 1.2, 1.3, 1.4_
|
||||
|
||||
- [ ] 2. Implementar DataStore (camada de armazenamento)
|
||||
- Criar arquivo `js/core/data-store.js` com classe DataStore
|
||||
- Implementar operações CRUD (get, getAll, set, delete, clear)
|
||||
- Implementar contagem de registros
|
||||
- Adicionar suporte a índices para busca rápida
|
||||
- _Requirements: 1.2, 1.3, 9.2_
|
||||
|
||||
- [ ] 3. Implementar CSVParser (processamento de dados)
|
||||
- Criar arquivo `js/core/csv-parser.js` com classe CSVParser
|
||||
- Implementar parse de CSV para objetos JavaScript
|
||||
- Adicionar validação de schema
|
||||
- Implementar transformações de dados (trim, parseFloat, etc)
|
||||
- Tratar linhas vazias e caracteres especiais
|
||||
- _Requirements: 2.3, 4.2_
|
||||
|
||||
- [ ] 4. Implementar SyncManager (sincronização)
|
||||
- Criar arquivo `js/core/sync-manager.js` com classe SyncManager
|
||||
- Implementar sincronização de todos os tipos de perfis
|
||||
- Implementar sincronização seletiva por tipo
|
||||
- Adicionar cálculo de hash MD5 para detecção de mudanças
|
||||
- Implementar callback de progresso
|
||||
- Armazenar metadados de sincronização (timestamp, hash, count)
|
||||
- _Requirements: 3.1, 3.2, 3.3, 4.1, 4.2, 4.3_
|
||||
|
||||
- [ ] 5. Implementar DataService (API pública)
|
||||
- Criar arquivo `js/core/data-service.js` com classe DataService
|
||||
- Implementar `getPerfis(tipo, options)` com fallback para CSV
|
||||
- Implementar `searchPerfis(tipo, filters)` com suporte a múltiplos filtros
|
||||
- Implementar `getPerfilById(tipo, id)` para busca por ID
|
||||
- Implementar `getMetadata(tipo)` para informações de sincronização
|
||||
- Adicionar cache em memória para dados frequentemente acessados
|
||||
- _Requirements: 2.1, 2.2, 5.1, 5.2, 5.3, 5.5_
|
||||
|
||||
- [ ] 6. Integrar sistema de cache com código existente
|
||||
- Atualizar `app.js` para inicializar CacheManager na inicialização
|
||||
- Modificar `carregarCantoneiras()` para usar DataService
|
||||
- Adicionar tratamento de erros com fallback para CSV
|
||||
- Manter compatibilidade com código existente
|
||||
- Testar carregamento de cantoneiras com cache
|
||||
- _Requirements: 2.1, 2.2, 2.4, 7.3, 7.4_
|
||||
|
||||
- [ ] 7. Criar interface de administração do cache
|
||||
- Adicionar seção "Cache Manager" no painel administrativo
|
||||
- Criar botão "🔄 Sincronizar Todos" com barra de progresso
|
||||
- Exibir estatísticas de cache (espaço usado, última sync, count)
|
||||
- Adicionar botões para sincronizar tipos individuais
|
||||
- Implementar botão "🗑️ Limpar Cache" com confirmação
|
||||
- Exibir timestamp da última sincronização por tipo
|
||||
- _Requirements: 3.1, 3.2, 3.3, 3.4, 6.1, 6.2, 6.3_
|
||||
|
||||
- [ ] 8. Implementar configuração de fontes de dados
|
||||
- Adicionar seção "Configurar Fontes CSV" no painel admin
|
||||
- Permitir editar caminho base dos CSVs
|
||||
- Permitir editar nome de arquivo para cada tipo
|
||||
- Validar se arquivos existem antes de salvar
|
||||
- Salvar configuração no localStorage
|
||||
- Fornecer botão "Restaurar Padrões"
|
||||
- _Requirements: 10.1, 10.2, 10.3, 10.4, 10.5_
|
||||
|
||||
- [ ] 9. Implementar detecção automática de atualizações
|
||||
- Calcular hash MD5 dos arquivos CSV na inicialização
|
||||
- Comparar com hash armazenado no cache
|
||||
- Exibir notificação quando dados estiverem desatualizados
|
||||
- Adicionar opção de atualização automática ou manual
|
||||
- Implementar configuração de intervalo de verificação
|
||||
- _Requirements: 4.1, 4.2, 4.3, 4.4, 4.5_
|
||||
|
||||
- [ ] 10. Adicionar ferramentas de diagnóstico e debug
|
||||
- Criar seção "Diagnóstico" no painel admin
|
||||
- Exibir estatísticas de hit/miss do cache
|
||||
- Implementar botão "Exportar Cache" (JSON)
|
||||
- Implementar botão "Importar Cache" (JSON)
|
||||
- Adicionar modo debug com logs detalhados no console
|
||||
- Exibir informações de saúde do IndexedDB
|
||||
- _Requirements: 8.1, 8.2, 8.3, 8.4, 8.5_
|
||||
|
||||
- [ ] 11. Implementar gerenciamento de espaço
|
||||
- Calcular espaço total usado pelo cache
|
||||
- Exibir espaço disponível no navegador
|
||||
- Implementar aviso quando espaço < 10MB
|
||||
- Adicionar botão para limpar tipos específicos
|
||||
- Implementar limpeza automática de dados antigos (opcional)
|
||||
- _Requirements: 6.1, 6.2, 6.3, 6.4_
|
||||
|
||||
- [ ] 12. Implementar fallback e compatibilidade
|
||||
- Detectar se IndexedDB está disponível
|
||||
- Implementar fallback completo para CSV quando IndexedDB não disponível
|
||||
- Adicionar opção para desabilitar cache via configuração
|
||||
- Garantir que aplicativo funciona sem cache
|
||||
- Testar em navegadores sem IndexedDB
|
||||
- _Requirements: 6.5, 7.4, 7.5_
|
||||
|
||||
- [ ] 13. Otimizações de performance
|
||||
- Implementar lazy loading para perfis não utilizados
|
||||
- Adicionar cache em memória para dados recentes
|
||||
- Otimizar queries com índices apropriados
|
||||
- Implementar batch insert para sincronização rápida
|
||||
- Medir e otimizar tempo de carregamento
|
||||
- _Requirements: 9.1, 9.2, 9.4, 9.5_
|
||||
|
||||
- [ ]* 14. Implementar Web Workers para parsing (opcional)
|
||||
- Criar Web Worker para parse de CSV em background
|
||||
- Mover processamento pesado para worker thread
|
||||
- Implementar comunicação via postMessage
|
||||
- Testar performance com arquivos grandes
|
||||
- _Requirements: 9.3_
|
||||
|
||||
- [ ]* 15. Implementar compressão de dados (opcional)
|
||||
- Adicionar biblioteca de compressão (pako.js ou similar)
|
||||
- Comprimir dados antes de armazenar se > 1MB
|
||||
- Descomprimir ao carregar
|
||||
- Medir ganho de espaço vs overhead de CPU
|
||||
- _Requirements: 9.5_
|
||||
|
||||
- [ ] 16. Criar documentação do sistema
|
||||
- Documentar API pública do DataService
|
||||
- Criar guia de uso para desenvolvedores
|
||||
- Documentar configurações disponíveis
|
||||
- Adicionar exemplos de uso
|
||||
- Documentar troubleshooting comum
|
||||
- _Requirements: Todos_
|
||||
|
||||
- [ ] 17. Aplicar sistema de cache a todos os tipos de perfis
|
||||
- Atualizar funções de carregamento de barras redondas
|
||||
- Atualizar funções de carregamento de tubos circulares
|
||||
- Atualizar funções de carregamento de perfis I
|
||||
- Atualizar funções de carregamento de perfis W
|
||||
- Atualizar funções de carregamento de tubos RHS
|
||||
- Atualizar funções de carregamento de chapas
|
||||
- Atualizar funções de carregamento de perfis HP
|
||||
- Atualizar funções de carregamento de barras roscadas
|
||||
- Atualizar funções de carregamento de barras chatas
|
||||
- _Requirements: 2.1, 2.2, 5.1_
|
||||
|
||||
- [ ] 18. Testes de integração e validação final
|
||||
- Testar carregamento inicial (primeira vez)
|
||||
- Testar carregamento do cache (segunda vez)
|
||||
- Testar sincronização manual
|
||||
- Testar detecção de atualizações
|
||||
- Testar fallback quando CSV não disponível
|
||||
- Testar limpeza de cache
|
||||
- Testar configuração de fontes
|
||||
- Validar performance (< 100ms para cache hit)
|
||||
- _Requirements: Todos_
|
||||
|
||||
## Notes
|
||||
|
||||
- Tarefas marcadas com * são opcionais e podem ser implementadas posteriormente
|
||||
- Cada tarefa deve ser testada individualmente antes de prosseguir
|
||||
- Manter compatibilidade com código existente durante toda implementação
|
||||
- Priorizar funcionalidade básica antes de otimizações avançadas
|
||||
24
.kiro/steering/product.md
Normal file
24
.kiro/steering/product.md
Normal file
@@ -0,0 +1,24 @@
|
||||
# Product Overview
|
||||
|
||||
**AÇO CALC PRO** is a professional structural steel engineering calculation platform designed for Brazilian engineers and construction professionals.
|
||||
|
||||
## Purpose
|
||||
|
||||
A comprehensive web-based tool for structural steel calculations, material selection, welding analysis, and cost estimation. The application provides technical calculations following Brazilian (NBR), American (ASTM/AWS), and European (EN) standards.
|
||||
|
||||
## Key Features
|
||||
|
||||
- **Materials Analysis**: CEV calculations, steel selection, international equivalencies, material comparisons
|
||||
- **Connections**: Bolted connections, drilling layouts, bolt vs weld comparisons
|
||||
- **Welding**: Preheat calculations, fillet weld design, heat input analysis, electrode consumption
|
||||
- **Testing**: Hardness conversion, Charpy analysis, certificate checklists, ultrasound interpretation
|
||||
- **Coating**: Paint area calculations, consumption estimates, galvanization analysis, cost estimation
|
||||
- **Budgeting**: Detailed cost estimation, weight and rigging calculations, technical references
|
||||
|
||||
## Target Users
|
||||
|
||||
Structural engineers, welding engineers, construction managers, and technical professionals working with steel structures in Brazil.
|
||||
|
||||
## Language
|
||||
|
||||
Portuguese (pt-BR) - All UI, calculations, and documentation are in Brazilian Portuguese.
|
||||
100
.kiro/steering/structure.md
Normal file
100
.kiro/steering/structure.md
Normal file
@@ -0,0 +1,100 @@
|
||||
# Project Structure
|
||||
|
||||
## File Organization
|
||||
|
||||
```
|
||||
/
|
||||
├── index.html # Main application entry point
|
||||
├── app.js # UI logic and navigation
|
||||
├── calculations.js # Calculation engine
|
||||
├── style.css # Complete design system
|
||||
├── BD/ # Material database (CSV)
|
||||
│ ├── perfis_w.csv
|
||||
│ ├── perfis_i.csv
|
||||
│ ├── cantoneiras.csv
|
||||
│ ├── tubos_circulares.csv
|
||||
│ ├── tubos_rhs.csv
|
||||
│ ├── chapas.csv
|
||||
│ ├── barras.csv
|
||||
│ ├── eletrodos.csv
|
||||
│ ├── parafusos.csv
|
||||
│ └── tintas.csv
|
||||
├── ORIGINAL/ # Backup of original files
|
||||
└── aco-calc-pro-v7-5.zip # Archive
|
||||
```
|
||||
|
||||
## Code Organization
|
||||
|
||||
### app.js
|
||||
- Application state management (`appState`, `adminConfig`)
|
||||
- Navigation and section switching
|
||||
- Modal management (history, favorites, admin, help)
|
||||
- Theme toggling (light/dark)
|
||||
- Expert mode functionality
|
||||
- CSV loading and parsing
|
||||
- Material database (in-memory fallback)
|
||||
- Content generation functions for each section
|
||||
|
||||
### calculations.js
|
||||
- Calculation functions for all engineering tools
|
||||
- Result formatting and display
|
||||
- Chart generation (Charpy curves)
|
||||
- History tracking
|
||||
- Input validation
|
||||
|
||||
### style.css
|
||||
- Design system with CSS variables
|
||||
- Theme support (light/dark modes)
|
||||
- Responsive layout
|
||||
- Component styles (buttons, forms, cards, modals)
|
||||
- Utility classes
|
||||
|
||||
## Key Patterns
|
||||
|
||||
### Section Loading
|
||||
Each tool section has a content generator function (e.g., `getCEVContent()`, `getParafusosContent()`) that returns HTML strings dynamically injected into the main content area.
|
||||
|
||||
### State Management
|
||||
Global objects store application state:
|
||||
- `appState`: Current section, theme, mode, history, favorites, budget items
|
||||
- `adminConfig`: Branding, tool visibility, preferences
|
||||
|
||||
### CSV Data Loading
|
||||
Materials are loaded from CSV files with fallback to in-memory database:
|
||||
1. Attempt to fetch CSV from `/BD/` directory
|
||||
2. Parse CSV into JavaScript objects
|
||||
3. Fall back to `materialsDatabase` if fetch fails
|
||||
|
||||
### Calculation Flow
|
||||
1. User inputs values in form
|
||||
2. Calculation function reads inputs
|
||||
3. Performs calculations following engineering standards
|
||||
4. Generates formatted result HTML
|
||||
5. Adds entry to history
|
||||
|
||||
## Naming Conventions
|
||||
|
||||
- **Functions**: camelCase (e.g., `calcularPreaquecimento`, `showSection`)
|
||||
- **Variables**: camelCase (e.g., `currentChart`, `appState`)
|
||||
- **CSS Classes**: kebab-case (e.g., `sidebar-item`, `result-box`)
|
||||
- **IDs**: kebab-case (e.g., `main-content`, `history-modal`)
|
||||
- **Constants**: camelCase for objects (e.g., `steelDatabase`, `regionalPricing`)
|
||||
|
||||
## Modular Sections
|
||||
|
||||
The application is organized into 6 main categories:
|
||||
1. **MATERIAIS** (Materials): CEV, steel selector, equivalencies, comparisons
|
||||
2. **CONEXÕES** (Connections): Bolted connections, drilling layouts, bolt vs weld
|
||||
3. **SOLDAGEM** (Welding): Preheat, fillet welds, heat input, electrode consumption
|
||||
4. **ENSAIOS** (Testing): Hardness, Charpy, certificates, ultrasound
|
||||
5. **PINTURA** (Coating): Area calculation, paint consumption, galvanization, costs
|
||||
6. **ORÇAMENTO** (Budget): Detailed budgets, weight/rigging, technical references
|
||||
|
||||
## Extension Points
|
||||
|
||||
To add a new calculation tool:
|
||||
1. Add sidebar item in `index.html`
|
||||
2. Create content generator function in `app.js` (e.g., `getNewToolContent()`)
|
||||
3. Add calculation function in `calculations.js`
|
||||
4. Add section case to `loadSectionContent()` switch
|
||||
5. Update `adminConfig.toolsVisibility` if needed
|
||||
71
.kiro/steering/tech.md
Normal file
71
.kiro/steering/tech.md
Normal file
@@ -0,0 +1,71 @@
|
||||
# Technical Stack
|
||||
|
||||
## Architecture
|
||||
|
||||
Single-page application (SPA) with vanilla JavaScript - no build system or framework dependencies.
|
||||
|
||||
## Core Technologies
|
||||
|
||||
- **HTML5**: Semantic markup, modern web standards
|
||||
- **CSS3**: Custom design system with CSS variables, dark/light theme support
|
||||
- **Vanilla JavaScript**: ES6+ features, no frameworks
|
||||
- **Chart.js**: Data visualization (loaded via CDN)
|
||||
|
||||
## External Dependencies
|
||||
|
||||
```html
|
||||
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
||||
```
|
||||
|
||||
## Data Storage
|
||||
|
||||
- **In-memory state**: All application state stored in JavaScript objects (`appState`, `adminConfig`)
|
||||
- **CSV files**: Material database stored in `/BD/*.csv` directory
|
||||
- **No backend**: Pure client-side application, no server required
|
||||
- **No localStorage**: Data is not persisted between sessions
|
||||
|
||||
## File Structure
|
||||
|
||||
```
|
||||
/
|
||||
├── index.html # Main HTML structure
|
||||
├── app.js # UI logic, navigation, modals
|
||||
├── calculations.js # Calculation functions
|
||||
├── style.css # Complete styling with design system
|
||||
└── BD/ # Material database (CSV files)
|
||||
├── perfis_w.csv
|
||||
├── perfis_i.csv
|
||||
├── cantoneiras.csv
|
||||
├── tubos_circulares.csv
|
||||
├── tubos_rhs.csv
|
||||
├── chapas.csv
|
||||
├── barras.csv
|
||||
├── eletrodos.csv
|
||||
├── parafusos.csv
|
||||
└── tintas.csv
|
||||
```
|
||||
|
||||
## Running the Application
|
||||
|
||||
**Development**: Open `index.html` directly in a browser or use a local web server:
|
||||
|
||||
```bash
|
||||
# Python 3
|
||||
python -m http.server 8000
|
||||
|
||||
# Node.js (http-server)
|
||||
npx http-server
|
||||
|
||||
# PHP
|
||||
php -S localhost:8000
|
||||
```
|
||||
|
||||
**Production**: Deploy to any static hosting service (GitHub Pages, Netlify, Vercel, etc.)
|
||||
|
||||
## Browser Compatibility
|
||||
|
||||
Modern browsers with ES6+ support required (Chrome 60+, Firefox 60+, Safari 12+, Edge 79+).
|
||||
|
||||
## No Build Process
|
||||
|
||||
The application runs directly in the browser without compilation, bundling, or transpilation.
|
||||
Reference in New Issue
Block a user