npm package: @horizon-apps/integration-toolkit
Description: Toolkit genérico para integração de APIs e sistemas - Profiling, Downloaders, Converters e Utilities
Author: Horizon Modules
Latest version: 1.3.0

# @horizon-modules/integration-toolkit

Toolkit genérico para integração de APIs e sistemas. Ferramentas reutilizáveis para profiling de dados, análise de datasets e utilitários de integração.

## 📦 Instalação

```bash
npm install @horizon-modules/integration-toolkit
# ou
pnpm add @horizon-modules/integration-toolkit
```

## 🛠️ Ferramentas Disponíveis

### 🚀 BatchApiUploader

Serviço para upload em lote de dados JSON para APIs. Processa arquivos JSON de uma pasta e envia para qualquer endpoint configurado.

### 🔄 BatchFileConverter

Serviço para conversão em lote de arquivos JSON. Lê arquivos de uma pasta, aplica função de conversão e salva os resultados convertidos em outra pasta.

### 🎯 ObjectTransformer

Serviço genérico para transformação de objetos JSON baseado em regras declarativas. Permite aplicar transformações complexas através de configurações em vez de código.

#### ✨ Características do BatchFileConverter

- **📁 Processamento em lote**: Converte todos os arquivos de uma pasta automaticamente
- **🔄 Função customizável**: Aceita qualquer função de conversão TypeScript
- **📊 Relatórios detalhados**: Estatísticas de conversão e tratamento de erros
- **🎯 Filtros flexíveis**: Filtra arquivos por padrões regex ou string
- **⚙️ Configurável**: Prefixos de saída, verbose mode e mais
- **🛡️ Type-safe**: Suporte completo a TypeScript com tipagem genérica

#### 🚀 Uso Básico do BatchFileConverter

```typescript
import { BatchFileConverter } from '@horizon-modules/integration-toolkit'
import { convertJetimobPropertyToHorizon } from './converter'

// Converter dados Jetimob para formato Horizon
const converter = new BatchFileConverter({
  inputDir: './data/downloads-do-crm',
  outputDir: './data/properties-converted',
  converter: convertJetimobPropertyToHorizon,
  filePattern: /page-\d+\.json$/,
  outputPrefix: 'converted-',
  verbose: true
})

const result = await converter.convert()

console.log(`✅ ${result.totalConvertedObjects}/${result.totalInputObjects} objetos convertidos`)
console.log(`📊 Taxa de sucesso: ${result.successRate.toFixed(1)}%`)
```

#### ⚙️ Configuração Avançada do BatchFileConverter

```typescript
import { BatchFileConverter } from '@horizon-modules/integration-toolkit'

// Converter produtos e-commerce
const converter = new BatchFileConverter({
  inputDir: '/data/raw-products',
  outputDir: '/data/normalized-products', 
  converter: (rawProduct) => ({
    id: rawProduct.codigo,
    name: rawProduct.nome,
    price: parseFloat(rawProduct.preco),
    category: rawProduct.categoria?.nome || 'Sem categoria'
  }),
  filePattern: 'product-', // String pattern
  outputPrefix: 'normalized-',
  verbose: true
})

const result = await converter.convert()

// Resultado detalhado
// {
//   success: true,
//   totalFiles: 5,
//   totalInputObjects: 1000,
//   totalConvertedObjects: 985,
//   totalErrors: 15,
//   successRate: 98.5,
//   errors: ['file1.json - Item 5: Missing required field'],
//   stats: {}
// }
```

#### 📋 Interface BatchFileConverterConfig

```typescript
interface BatchFileConverterConfig<TInput = any, TOutput = any> {
  inputDir: string                          // Pasta com arquivos de entrada
  outputDir: string                         // Pasta para arquivos convertidos  
  converter: (input: TInput) => TOutput     // Função de conversão
  filePattern?: RegExp | string             // Filtro de arquivos (padrão: /\.json$/)
  outputPrefix?: string                     // Prefixo de saída (padrão: 'converted-')
  verbose?: boolean                         // Logs detalhados (padrão: false)
}

interface ConvertResult {
  success: boolean                    // Se a operação foi bem-sucedida
  totalFiles: number                 // Arquivos processados
  totalInputObjects: number          // Objetos de entrada encontrados
  totalConvertedObjects: number      // Objetos convertidos com sucesso
  totalErrors: number               // Total de erros
  successRate: number               // Taxa de sucesso em %
  errors: string[]                  // Lista de erros detalhados
  stats: Record<string, number>     // Estatísticas customizadas
}
```

#### ✨ Características do BatchApiUploader

- **📁 Leitura automática**: Processa todos os `.json` de uma pasta
- **🌐 HTTP flexível**: Suporte a POST/PUT com headers customizáveis  
- **📊 Relatórios completos**: Estatísticas de sincronização (inseridos/atualizados/erros)
- **⚙️ Configurável**: Endpoint, método HTTP, campo de batch, delays
- **🔧 Genérico**: Funciona com qualquer tipo de dados (imóveis, produtos, etc.)
- **⏱️ Rate limiting**: Delay configurável entre requisições

#### 🚀 Uso Básico do BatchApiUploader

```typescript
import { BatchApiUploader } from '@horizon-modules/integration-toolkit'

// Upload de dados de uma pasta para API
const result = await BatchApiUploader.syncData({
  inputDir: '/data/downloads-do-crm',
  endpoint: 'http://localhost:3000/api/property/sync',
  batchField: 'properties',
  method: 'PUT',
  verbose: true
})

console.log(result)
// {
//   success: true,
//   totalFiles: 5,
//   totalObjects: 250,
//   totalSynced: 248,
//   totalErrors: 2,
//   successRate: 99.2,
//   errors: ['file1.json: HTTP 400: Bad Request']
// }
```

#### ⚙️ Configuração Avançada do BatchApiUploader

```typescript
import { BatchApiUploader } from '@horizon-modules/integration-toolkit'

const uploader = new BatchApiUploader({
  inputDir: '/integrations/jetimob/__dev__/data/downloads-do-crm',
  endpoint: 'https://api.example.com/sync',
  method: 'POST',
  headers: {
    'Authorization': 'Bearer token123',
    'Content-Type': 'application/json',
    'X-API-Version': '2.0'
  },
  batchField: 'data',        // Campo que vai conter o array
  delayMs: 500,              // 500ms entre requisições
  verbose: true
})

const result = await uploader.upload()
```

#### 🎯 Casos de Uso

```typescript
// Jetimob CRM → Property API
await BatchApiUploader.syncData({
  inputDir: '/integrations/jetimob/__dev__/data/downloads-do-crm',
  endpoint: 'http://localhost:3000/api/property/sync',
  batchField: 'properties',
  method: 'PUT'
})

// E-commerce → Inventory API  
await BatchApiUploader.syncData({
  inputDir: '/data/products',
  endpoint: 'https://inventory.example.com/api/bulk',
  batchField: 'products',
  method: 'POST',
  headers: { 'X-Store-ID': 'store123' }
})

// Logs → Analytics API
await BatchApiUploader.syncData({
  inputDir: '/logs/processed',
  endpoint: 'https://analytics.example.com/events',
  batchField: 'events',
  delayMs: 100
})
```

#### 📋 Interface BatchApiUploaderConfig

```typescript
interface BatchApiUploaderConfig {
  inputDir: string                    // Pasta com arquivos JSON
  endpoint: string                    // URL da API de destino
  method?: 'POST' | 'PUT'            // Método HTTP (padrão: PUT)
  headers?: Record<string, string>    // Headers customizados
  batchField?: string                 // Campo do payload (padrão: 'data')
  delayMs?: number                   // Delay entre requisições (padrão: 100ms)
  verbose?: boolean                  // Logs detalhados (padrão: false)
}

interface UploadResult {
  success: boolean         // Se a operação foi bem-sucedida
  totalFiles: number      // Total de arquivos processados  
  totalObjects: number    // Total de objetos encontrados
  totalSynced: number     // Total sincronizado com sucesso
  totalErrors: number     // Total de erros
  successRate: number     // Taxa de sucesso em %
  errors: string[]        // Lista de erros detalhados
}
```

### 📊 ProfilerService

Serviço genérico para análise e profiling de dados JSON. Analisa estruturas de dados, extrai exemplos de campos e gera relatórios estatísticos.

#### ✨ Características

- **📁 Análise de arquivos**: Processa arquivos JSON em diretórios
- **💾 Análise em memória**: Trabalha com dados carregados em memória
- **🔍 Profiling profundo**: Analisa objetos aninhados e arrays
- **📊 Deduplicação**: Remove duplicatas baseado em campo chave
- **⚙️ Configurável**: Controle de exemplos por campo
- **📈 Relatórios JSON**: Saída em formato JSON estruturado

### 🔧 JsonToZodGenerator

Gerador automático de schemas Zod a partir de dados JSON. Analisa estruturas de dados e cria validações TypeScript type-safe.

#### ✨ Características

- **🔍 Análise automática**: Detecta tipos de dados automaticamente
- **🛡️ Type-safe**: Gera schemas Zod com tipagem forte
- **🎯 Configurável**: Opções de geração personalizáveis
- **📝 Documentação**: Adiciona comentários aos schemas gerados
- **🔄 Reutilizável**: Detecta e reutiliza interfaces comuns

#### 🚀 Uso Básico

```typescript
import { JsonToZodGenerator } from '@horizon-modules/integration-toolkit'

const generator = new JsonToZodGenerator({
  outputPath: './src/schemas/generated.ts',
  interfaceName: 'UserData'
})

const userData = {
  id: 1,
  name: 'João',
  email: 'joao@example.com',
  profile: {
    age: 30,
    city: 'São Paulo'
  }
}

await generator.generateFromData(userData)

// Gera arquivo com:
// export const UserDataSchema = z.object({
//   id: z.number(),
//   name: z.string(),
//   email: z.string().email(),
//   profile: z.object({
//     age: z.number(),
//     city: z.string()
//   })
// })
```

#### 🚀 Uso do ProfilerService

```typescript
import { ProfilerService } from '@horizon-modules/integration-toolkit'

// Análise de arquivos
const profiler = new ProfilerService({
  inputDir: './data/json-files',
  outputDir: './output',
  dataLabel: 'produtos',
  serviceLabel: 'API E-commerce'
})

const result = await profiler.profile()
console.log(result)
// {
//   "id": [1, 2, 3],
//   "name": ["Produto A", "Produto B"],
//   "category.name": ["Eletrônicos", "Casa"]
// }
```

#### 💾 Análise em Memória

```typescript
import { ProfilerService } from '@horizon-modules/integration-toolkit'

// Dados diretos em memória
const data = [
  { id: 1, name: 'João', city: 'São Paulo' },
  { id: 2, name: 'Maria', city: 'Rio de Janeiro' }
]

const profiler = new ProfilerService({
  inputData: data,
  dataLabel: 'usuários'
})

const result = await profiler.profile()

// Método estático para uso rápido
const quickResult = await ProfilerService.profileData(data, {
  defaultMaxExamples: 5
})
```

#### ⚙️ Configuração Avançada

```typescript
const profiler = new ProfilerService({
  inputDir: './data',
  outputDir: './reports',
  outputFileName: 'custom-profile.json',
  verbose: true,
  dataLabel: 'imóveis',
  serviceLabel: 'CRM Imobiliário',
  uniqueField: 'codigo', // Campo para deduplicação
  defaultMaxExamples: 20,
  fieldConfigs: {
    'endereco.cidade': { maxExamples: 50 },
    'caracteristicas': { maxExamples: 100 }
  }
})

// Análise com deduplicação
const uniqueResult = await profiler.profileUnique()
```

#### 📋 Interface ProfilerConfig

```typescript
interface ProfilerConfig {
  inputDir?: string              // Diretório com arquivos JSON
  inputData?: any[]             // Dados em memória (alternativa)
  outputDir?: string            // Onde salvar resultado (opcional)
  outputFileName?: string       // Nome do arquivo de saída
  fieldConfigs?: Record<string, FieldConfig>  // Config por campo
  defaultMaxExamples?: number   // Padrão de exemplos (10)
  verbose?: boolean             // Logs detalhados
  uniqueField?: string          // Campo para deduplicação
  dataLabel?: string            // Label dos dados
  serviceLabel?: string         // Label do serviço
}

interface FieldConfig {
  maxExamples?: number          // Quantos exemplos guardar
}
```

## 🎯 Exemplos de Uso

### 📋 PropertyCustomerRules - Regras de Transformação para Imóveis

Exemplo completo de regras de transformação para padronização de dados imobiliários, localizado em [`examples/object-transformer/property-customer-rules.ts`](./examples/object-transformer/property-customer-rules.ts).

#### 🚀 Uso

```typescript
import { ObjectTransformer } from '@horizon-integrations/dev-toolkit'
// Copie o arquivo examples/object-transformer/property-customer-rules.ts para seu projeto
import { PropertyCustomerRules } from './path/to/property-customer-rules'

// Usar regras do exemplo para transformação de imóveis
const transformer = new ObjectTransformer({ rules: PropertyCustomerRules })

const propriedade = {
  tipo: 'Casa de Condomínio',
  vagas: 2,
  caracteristicas: ['Sem mobília', 'Churrasqueira'],
  corretor_id: 'elvis-ghisi'
}

const transformada = transformer.transform(propriedade)
// Resultado:
// {
//   tipo: 'Casa/Sobrado',
//   subtipo: 'Casa', 
//   vagas_garagem: 2,
//   caracteristicas: ['Churrasqueira'],
//   mobilia: 'Sem mobília',
//   tags: ['em-condominio'],
//   corretor_slug: 'elvis-ghisi',
//   corretor_nome: 'Elvis Ghisi'
// }
```

#### 📋 Transformações Incluídas

**🏠 Tipos de Imóveis:**
- **Residenciais**: Apartamento → Apartamento, Casa → Casa/Sobrado, Sobrado → Casa/Sobrado
- **Apartamentos**: Duplex, Triplex, Cobertura, Loft, Studio, Flat, Garden
- **Casas Especiais**: Quitinete, Bangalô, Edícula, Chalé, Casa de Condomínio
- **Terrenos**: Terreno → Terreno/Lote, Lote → Terreno/Lote
- **Comerciais**: Sala, Loja, Ponto, Conjunto → Comercial (com subtipos)
- **Rurais**: Fazenda, Sítio, Chácara, Granja → Rural (com tag "rural")
- **Industriais**: Galpão/Barracão → normalização

**🔧 Mapeamentos de Campos:**
- `vagas` → `vagas_garagem` (renomeação)
- `caracteristicas` → processamento de "Sem mobília" → campo `mobilia`
- `corretor_id` → `corretor_slug` + `corretor_nome` (exemplo)
- `tags` → mapeamento de agentes para corretores

#### 🎯 Casos de Uso

```typescript
// Pipeline completo de transformação
import { BatchFileConverter, ObjectTransformer } from '@horizon-integrations/dev-toolkit'
// Copie o arquivo de exemplo para seu projeto
import { PropertyCustomerRules } from './config/property-customer-rules'

const converter = new BatchFileConverter({
  inputDir: './data/raw-properties',
  outputDir: './data/normalized-properties',
  converter: (rawProperty) => {
    const transformer = new ObjectTransformer({ rules: PropertyCustomerRules })
    return transformer.transform(rawProperty)
  },
  verbose: true
})

const result = await converter.convert()
console.log(`${result.totalConvertedObjects} imóveis normalizados`)
```

## 📊 Exemplos Práticos

### 🔄 Sincronização Jetimob → Property API

```typescript
import { DataSyncService } from '@horizon-modules/integration-toolkit'

// Sincronizar downloads do CRM Jetimob
const result = await DataSyncService.syncData({
  inputDir: '/integrations/jetimob/__dev__/data/downloads-do-crm',
  endpoint: 'http://localhost:3000/api/property/sync',
  batchField: 'properties',
  method: 'PUT',
  headers: {
    'X-Source': 'jetimob-crm'
  },
  verbose: true
})

console.log(`✅ ${result.totalSynced}/${result.totalObjects} imóveis sincronizados`)
console.log(`📊 Taxa de sucesso: ${result.successRate}%`)
```

### 🏠 Análise de Dados Imobiliários

```typescript
import { ProfilerService } from '@horizon-modules/integration-toolkit'

const profiler = new ProfilerService({
  inputDir: './data/imoveis',
  outputDir: './profiling',
  outputFileName: 'imoveis-profile.json',
  dataLabel: 'imóveis',
  serviceLabel: 'CRM Jetimob',
  uniqueField: 'codigo',
  fieldConfigs: {
    'endereco_cidade': { maxExamples: 30 },
    'tipo': { maxExamples: 10 },
    'caracteristicas': { maxExamples: 50 }
  }
})

const result = await profiler.profileUnique()
console.log(`Campos analisados: ${Object.keys(result).length}`)
```

### 📦 Análise de Produtos E-commerce

```typescript
import { ProfilerService } from '@horizon-modules/integration-toolkit'

const produtos = [
  {
    id: 1,
    nome: 'Smartphone',
    categoria: { id: 10, nome: 'Eletrônicos' },
    preco: 899.99,
    tags: ['oferta', 'destaque']
  },
  // ... mais produtos
]

const result = await ProfilerService.profileData(produtos, {
  dataLabel: 'produtos',
  serviceLabel: 'API Loja',
  defaultMaxExamples: 15
})

// Resultado:
// {
//   "id": [1, 2, 3],
//   "nome": ["Smartphone", "Laptop", "Tablet"],
//   "categoria.id": [10, 20, 30],
//   "categoria.nome": ["Eletrônicos", "Informática"],
//   "tags": ["oferta", "destaque", "novo"]
// }
```

### 📈 Análise de Logs de API

```typescript
import { ProfilerService } from '@horizon-modules/integration-toolkit'

const profiler = new ProfilerService({
  inputDir: './logs/api-calls',
  outputDir: './analytics',
  dataLabel: 'requisições',
  serviceLabel: 'API Gateway',
  fieldConfigs: {
    'endpoint': { maxExamples: 20 },
    'method': { maxExamples: 10 },
    'status_code': { maxExamples: 15 }
  }
})

const result = await profiler.profile()
```

## 🎯 ObjectTransformer - Transformação Baseada em Regras

O ObjectTransformer permite transformar objetos JSON através de regras declarativas, eliminando a necessidade de escrever código de transformação customizado para cada caso.

### ✨ Características

- **🎯 Baseado em regras**: Configure transformações via JSON, não código
- **🔄 Transformações complexas**: Suporte a condições, arrays, campos aninhados
- **🛡️ Type-safe**: Tipagem TypeScript com generics
- **📝 Tags na description**: Processa tags especiais em campos de texto
- **🔧 Actions flexíveis**: upsertField, removeField, addToArray, removeFromArray

### 🚀 Uso Básico

```typescript
import { ObjectTransformer } from '@horizon-modules/integration-toolkit'

// Configurar regras de transformação
const rules = {
  fieldRules: [
    {
      key: 'tipo',
      condition: { eq: 'Casa' },
      rules: [
        { fn: 'upsertField', key: 'categoria', value: 'Residencial' },
        { fn: 'upsertField', key: 'subtipo', value: 'Casa' }
      ]
    },
    {
      key: 'caracteristicas',
      condition: { has_any: ['Piscina'] },
      rules: [
        { fn: 'removeFromArray', key: 'caracteristicas', value: 'Piscina' },
        { fn: 'upsertField', key: 'tem_piscina', value: true }
      ]
    }
  ]
}

// Criar transformer
const transformer = new ObjectTransformer({ rules })

// Transformar objeto
const propriedade = {
  reference: 'PROP001',
  tipo: 'Casa',
  caracteristicas: ['Piscina', 'Churrasqueira']
}

const transformed = transformer.transform(propriedade)
// Resultado:
// {
//   reference: 'PROP001',
//   tipo: 'Casa',
//   categoria: 'Residencial',
//   subtipo: 'Casa', 
//   caracteristicas: ['Churrasqueira'],
//   tem_piscina: true
// }
```

### 🔄 Combinando com BatchFileConverter

```typescript
import { BatchFileConverter, ObjectTransformer } from '@horizon-modules/integration-toolkit'
import transformRules from './config/transform-rules'

// Criar transformer com regras
const transformer = new ObjectTransformer({ rules: transformRules })

// Usar com BatchFileConverter
const batchConverter = new BatchFileConverter({
  inputDir: './data/input',
  outputDir: './data/output',
  converter: (obj) => transformer.transform(obj), // Closure com transformer
  verbose: true
})

const result = await batchConverter.convert()
```

### 📋 Condições Suportadas

```typescript
// Igualdade
condition: { eq: 'Apartamento' }
condition: { not_eq: 'Casa' }

// Arrays
condition: { has: ['churrasqueira'] }          // Tem todos os valores
condition: { has_any: ['piscina', 'sauna'] }   // Tem qualquer um dos valores
condition: { not_has: ['mobiliado'] }          // Não tem o valor

// Numéricos
condition: { gt: 100 }    // Maior que
condition: { gte: 100 }   // Maior ou igual
condition: { lt: 1000 }   // Menor que
condition: { lte: 1000 }  // Menor ou igual

// Texto
condition: { contains: 'apartamento' }
condition: { starts_with: 'Casa' }
condition: { ends_with: 'Comercial' }

// Booleanos
condition: { is_true: true }
condition: { is_false: true }

// Existência
condition: { exists: true }     // Campo existe
condition: { not_exists: true } // Campo não existe
```

### 🛠️ Actions Disponíveis

```typescript
// Criar/atualizar campo
{ fn: 'upsertField', key: 'novo_campo', value: 'valor' }

// Remover campo
{ fn: 'removeField', key: 'campo_antigo' }

// Adicionar valores a array
{ fn: 'addToArray', key: 'tags', value: ['nova-tag'] }

// Remover valores de array
{ fn: 'removeFromArray', key: 'caracteristicas', value: 'Sem mobília' }
```

### 📝 Processamento de Tags na Description

O ObjectTransformer processa automaticamente tags especiais em campos de texto:

```typescript
const objeto = {
  description: `Casa linda [[description-en]]Beautiful house[[/description-en]] 
  [[custom-attributes]]
  {
    "energia_solar": true,
    "classificacao": "A+"
  }
  [[/custom-attributes]]
  Com vista para o mar`
}

const transformer = new ObjectTransformer({
  rules: {},
  processDescriptionTags: true // Padrão: true
})

const resultado = transformer.transform(objeto)
// Resultado:
// {
//   description: 'Casa linda Com vista para o mar',
//   description_en: 'Beautiful house',
//   energia_solar: true,
//   classificacao: 'A+'
// }
```

### ⚙️ Interface Completa

```typescript
interface TransformRules<T = any> {
  referenceRules?: Record<string, TransformAction[]>  // Regras por reference
  fieldRules?: FieldRule<T>[]                         // Regras por field
}

interface FieldRule<T = any> {
  key: keyof T | string                    // Campo a verificar
  condition?: Record<string, any>          // Condição para aplicar regras
  rules: TransformAction[]                 // Actions a executar
}

interface TransformAction {
  fn: 'upsertField' | 'removeField' | 'addToArray' | 'removeFromArray'
  key: string        // Campo alvo da action
  value?: any        // Valor para a action
  type?: string      // Tipo do campo (informativo)
  label?: string     // Label do campo (informativo)  
}
```

## 🧪 Testes

```bash
# Executar testes
npm run test

# Testes com cobertura
npm run test:coverage

# Verificar tipos
npm run typecheck
```

## 🔧 Build

```bash
# Build para produção
npm run build

# Build com watch
npm run dev
```

## 📈 Roadmap

- **✅ DataSyncService**: Sincronização genérica de dados JSON com APIs
- **✅ ProfilerService**: Profiling e análise de estruturas de dados
- **✅ JsonToZodGenerator**: Geração automática de schemas Zod
- **BaseDownloader**: Classe base para downloaders de API
- **BaseConverter**: Utilitários para conversão de dados
- **ApiClient**: Cliente HTTP genérico com retry e rate limiting
- **DataTransformer**: Transformações de dados baseadas em regras
- **ValidationUtils**: Utilitários de validação genéricos

---

## 📄 Licença

MIT - veja [LICENSE](LICENSE) para detalhes.

**Desenvolvido pela Horizon Modules** 🏗️