@horizon-apps/domain-schema-core
Version:
Core domain schema utilities for Horizon Platform - Schema generators, data enrichers, converters and specifications
275 lines (225 loc) • 6.05 kB
Markdown
# 🔧 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