# 🔧 Search State Enricher - Guia de Correções

## 📋 Problemas Identificados

Com base nos testes na API real, identifiquei **descompassos críticos** entre o formato gerado pelo enricher e o esperado pela API.

## ❌ Problemas por Categoria

### **1. GEOM (Geometria) - CRÍTICO**

**❌ Enricher Gera:**
```json
{
  "geom": {
    "operation": "within",
    "geometry": {
      "type": "bbox",
      "bounds": {...}
    }
  }
}
```

**✅ API Espera:**
```json
{
  "geom": {
    "operator": "within", 
    "value": {
      "type": "bbox",
      "bounds": {...}
    }
  }
}
```

**🔧 CORREÇÃO NECESSÁRIA:**
- `operation` → `operator`
- `geometry` → `value`

### **2. Mapeamento de Campos - CRÍTICO**

**❌ Enricher Usa:**
```json
{
  "filters": {
    "quartos": { "gte": 2 }
  }
}
```

**✅ API Espera:**
```json
{
  "filters": {
    "dormitorios": { "gte": 2 }
  }
}
```

**🔧 MAPEAMENTO NECESSÁRIO:**
```typescript
const FIELD_MAPPING = {
  'quartos': 'dormitorios',
  // outros mapeamentos se necessário
}
```

### **3. Formato de Arrays - PARCIAL**

**✅ Arrays OR funcionam:**
```json
{
  "operacao": { "or": ["venda", "locacao"] }
}
```

**⚠️ Arrays AND precisam validação:**
```json
{
  "endereco_bairro": { "and": ["centro", "agua-verde"] }
}
```
*Nota: `endereco_bairro` é string na tabela, não array*

### **4. Sort Format - CRÍTICO**

**❌ Enricher poderia gerar:**
```json
{
  "list": {
    "order": "valor_venda_asc"
  }
}
```

**✅ API Espera:**
```json
{
  "list": {
    "sort": {
      "valor_venda": "asc"
    }
  }
}
```

## 🛠️ Plano de Correções

### **Correção 1: Ajustar GEOM no Enricher**

**Arquivo**: `/src/search-state-enricher/src/core/SearchStateEnricher.ts`

```typescript
// ❌ ATUAL
private enrichGeom(geom: any): any {
  const defaultOperation = 
    this.schema.geom?.operation || 
    this.options.defaults?.geom?.operation || 
    'within'

  return {
    operation: geom.operation || defaultOperation,
    geometry: geom.geometry || geom
  }
}

// ✅ CORRIGIDO
private enrichGeom(geom: any): any {
  const defaultOperator = 
    this.schema.geom?.operation || 
    this.options.defaults?.geom?.operation || 
    'within'

  return {
    operator: geom.operator || defaultOperator,  // operation → operator
    value: geom.value || geom.geometry || geom   // geometry → value
  }
}
```

### **Correção 2: Mapeamento de Campos**

**Adicionar no SearchStateEnricher:**

```typescript
// Mapeamento de campos do schema para API
private static readonly FIELD_MAPPING: Record<string, string> = {
  'quartos': 'dormitorios',
  // adicionar outros conforme necessário
}

private mapFieldName(fieldName: string): string {
  return SearchStateEnricher.FIELD_MAPPING[fieldName] || fieldName
}

// Usar no enrichFilters:
private enrichFilters(filters: Record<string, any>): Record<string, any> {
  const enriched: Record<string, any> = {}

  for (const [fieldName, value] of Object.entries(filters)) {
    const mappedFieldName = this.mapFieldName(fieldName)  // ← NOVO
    const fieldMetadata = this.getFieldSchema(fieldName)   // Schema usa nome original
    
    if (fieldMetadata) {
      enriched[mappedFieldName] = this.enrichField(value, fieldMetadata)  // ← API usa nome mapeado
    } else if (!this.options.strict) {
      enriched[mappedFieldName] = value  // ← API usa nome mapeado
    }
  }

  return enriched
}
```

### **Correção 3: Validar Arrays vs Strings**

**Adicionar validação por campo:**

```typescript
// Campos que devem ser tratados como string, não array
private static readonly STRING_FIELDS = new Set([
  'endereco_bairro',
  'endereco_cidade',
  'endereco_estado'
  // adicionar outros conforme necessário
])

private enrichArrayField(value: any[], fieldMetadata: FieldMetadata): any {
  const fieldName = fieldMetadata.key
  const operator = fieldMetadata.operator || this.options.defaults?.arrays?.operator || 'and'

  // Se campo deve ser string, usar apenas primeiro valor
  if (SearchStateEnricher.STRING_FIELDS.has(fieldName)) {
    return value.length > 0 ? value[0] : null
  }

  // Array normal
  if (value.length === 1) {
    return value[0]
  }

  return {
    [operator]: value
  }
}
```

## 📋 Checklist de Implementação

### **SearchStateEnricher.ts**
- [ ] Corrigir `enrichGeom()`: `operation → operator`, `geometry → value`  
- [ ] Adicionar `FIELD_MAPPING` e `mapFieldName()`
- [ ] Adicionar `STRING_FIELDS` validation em `enrichArrayField()`
- [ ] Usar nomes mapeados no output de `enrichFilters()`

### **Interfaces**
- [ ] Atualizar `GeomMetadata` interface se necessário
- [ ] Validar se `EnricherOptions` permite configurar mapeamentos

### **Tests**
- [ ] Atualizar test schemas para usar campos corretos
- [ ] Adicionar testes para mapeamento de campos
- [ ] Adicionar testes para formato GEOM correto  
- [ ] Testar cenários corrigidos na API real

### **Documentation**
- [ ] Atualizar README do enricher com correções
- [ ] Documentar FIELD_MAPPING configuration
- [ ] Adicionar exemplos com formato correto

## 🎯 Resultado Esperado

Após as correções, o enricher deve gerar **exatamente** o formato esperado pela API:

```typescript
// Input (URL state)
{
  fts: 'apartamento centro',
  filters: {
    quartos: { min: 2 },
    operacao: ['venda', 'locacao']
  },
  geom: {
    type: 'bbox', 
    bounds: {...}
  }
}

// Output (enriched for API)  
{
  fts: {
    value: 'apartamento centro',
    operator: 'websearch'
  },
  filters: {
    dormitorios: { gte: 2 },        // ← quartos mapeado para dormitorios
    operacao: { or: ['venda', 'locacao'] }
  },
  geom: {
    operator: 'within',             // ← operation → operator  
    value: {                        // ← geometry → value
      type: 'bbox',
      bounds: {...}
    }
  }
}
```

## 🚨 Próximos Passos

1. **Implementar correções** no SearchStateEnricher
2. **Atualizar test schemas** com campos corretos  
3. **Testar cenários corrigidos** na API
4. **Validar 100% compatibilidade** entre enricher e API