@horizon-integrations/si9-crm 1.1.6 → 1.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,547 @@
1
+ # SI9 — Ficha Técnica de Integração
2
+
3
+ > Diretrizes para IAs e desenvolvedores integrarem os dados do CRM SI9 em qualquer site imobiliário.
4
+ > Contém o que o CRM oferece, o que não oferece, limitações, e como tirar o melhor proveito.
5
+
6
+ **Versão:** 1.0
7
+ **CRM:** SI9 Sistemas
8
+ **Pacote:** @horizon-integrations/si9-crm
9
+ **API:** REST JSON (OAuth 2.0)
10
+ **Base URL:** https://api.si9sistemas.com.br/imobilsi9-api
11
+
12
+ ---
13
+
14
+ ## 1. VISÃO GERAL
15
+
16
+ O SI9 é um CRM regional focado em imobiliárias de pequeno e médio porte. A API retorna dados de imóveis em JSON com objetos aninhados (generalData, values, features, security, recreation, rural, location, website, destination, company, images, fields).
17
+
18
+ ### Pontos fortes:
19
+ - Campos personalizados (`fields[]`) com chave-valor livre — permite criar campos que a API não tem nativamente
20
+ - 10 situações comerciais documentadas (AVALIABLE, SOLD, RENTED, RESERVED, etc.)
21
+ - Booleans separados por grupo (features, security, recreation, rural) — bom pra categorizar
22
+ - Lat/lng disponíveis (embora não documentados oficialmente)
23
+
24
+ ### Limitações:
25
+ - Sem timestamps da API (sem created_at nem updated_at do imóvel)
26
+ - Sem fotos em múltiplos tamanhos (só URL única)
27
+ - Sem paginação — retorna TODOS os imóveis de uma vez
28
+ - Sem vínculo corretor↔imóvel nativo (precisa de campo personalizado)
29
+ - Sem campos de SEO na API (existem no CRM mas não são expostos)
30
+ - Sem subtipo nativo
31
+ - Sem campo de aceita pet, aceita financiamento, exclusividade na API
32
+
33
+ ---
34
+
35
+ ## 2. CAMPOS HORIZON BASE (45 campos)
36
+
37
+ Como o SI9 alimenta cada campo base universal:
38
+
39
+ | Campo base | Fonte SI9 | Tipo | Observação |
40
+ |---|---|---|---|
41
+ | reference | `id` | number→string | Converter pra string |
42
+ | title | `generalData.title` | string | — |
43
+ | description | `generalData.description` | string | — |
44
+ | source_updated_at | — | — | Gerar com `new Date().toISOString()` (API não fornece) |
45
+ | source_published_at | — | — | Não disponível na API |
46
+ | currency | — | — | Fixo "BRL" |
47
+ | unit_area | — | — | Fixo "m2" |
48
+ | unit_distance | — | — | Fixo "meters" |
49
+ | operacao | `destination.sale/rent/season` | booleans→array | sale→"venda", rent→"locacao", season→"temporada" |
50
+ | tipo | `generalData.category.name` | string | 11 tipos encontrados nos dados |
51
+ | valor_venda | `values.saleValue` | number | REAIS (não centavos). Só se destination.sale=true |
52
+ | valor_locacao | `values.rentValue` | number | REAIS. Só se destination.rent=true |
53
+ | valor_condominio | `values.condominiumFee` | number | REAIS |
54
+ | valor_iptu | `values.iptuValue` | number | REAIS. Valor ANUAL |
55
+ | dormitorios | `features.bedroom` | integer | — |
56
+ | suites | `features.suite` | integer | — |
57
+ | banheiros | `features.bathroom` | integer | Só bathroom (toilet/lavabo é campo extra separado) |
58
+ | vagas_garagem | `features.coveredGarage + features.outdoorGarage` | integer | Soma cobertas + descobertas |
59
+ | area_total | `dimensions.totalArea` | number | m² |
60
+ | area_privativa | `dimensions.privateArea` | number | m² |
61
+ | area_util | `dimensions.usefulArea` | number | m² |
62
+ | destaque | `website.highlight \|\| website.superHighlight` | boolean | true se qualquer um true |
63
+ | endereco_cep | `location.zipCode` | string | Vem sem formatação (8 dígitos). Formatar 00000-000 |
64
+ | endereco_estado | `location.city.state` | string | UF |
65
+ | endereco_cidade | `location.city.name` | string | — |
66
+ | endereco_bairro | `location.district.name` | string | — |
67
+ | endereco_logradouro | `location.address` | string | — |
68
+ | endereco_numero | `location.number` | string | — |
69
+ | endereco_complemento | `location.complement` | string | — |
70
+ | endereco_referencia | `location.referencePoint` | string | — |
71
+ | endereco_zona | — | — | Não disponível |
72
+ | lat | `location.latitude` | string→number | Vem como string, converter pra number |
73
+ | lng | `location.longitude` | string→number | Vem como string, converter pra number |
74
+ | corretor_key | — | — | Não disponível nativamente. Usar campo personalizado "Corretor" |
75
+ | corretor_nome | — | — | Idem — campo personalizado "Corretor" com o nome |
76
+ | condominio_key | — | — | Não disponível |
77
+ | condominio_nome | `generalData.allotment` | string | Nome do empreendimento/loteamento/edifício |
78
+ | seo_slug | — | — | Não disponível na API |
79
+ | seo_title | — | — | Não disponível na API |
80
+ | seo_description | — | — | Não disponível na API |
81
+ | seo_keywords | — | — | Não disponível na API |
82
+ | main_image | `images[0]` | object | Filtrar displaySite=true. Primeira imagem |
83
+ | images | `images[]` | array | Filtrar displaySite=true |
84
+ | videos | `generalData.urlVideo` | string→array | Array com 1 item se existir |
85
+ | virtual_tours | `generalData.urlTour` | string→array | Array com 1 item se existir |
86
+
87
+ ---
88
+
89
+ ## 3. CAMPOS EXTRAS DO CRM
90
+
91
+ Campos adicionais que o SI9 fornece além dos 45 base. Normalizados em snake_case com prefixo do grupo de origem.
92
+
93
+ ### Valores extras
94
+
95
+ | Campo normalizado | Fonte SI9 | Tipo | SQL |
96
+ |---|---|---|---|
97
+ | values_discount_value | values.discountValue | number | DOUBLE PRECISION |
98
+ | values_fci_value | values.fciValue | number | DOUBLE PRECISION |
99
+ | values_assigned_value | values.assignedValue | number | DOUBLE PRECISION |
100
+ | values_trash_fee | values.trashFee | number | DOUBLE PRECISION |
101
+ | values_disaster_fee | values.disasterFee | number | DOUBLE PRECISION |
102
+
103
+ ### Dados gerais extras
104
+
105
+ | Campo normalizado | Fonte SI9 | Tipo | SQL |
106
+ |---|---|---|---|
107
+ | general_data_situation | generalData.situation | string (enum) | TEXT |
108
+ | general_data_board | generalData.board | string | TEXT |
109
+
110
+ ### Website extras
111
+
112
+ Mapeamento dos campos do painel SI9 "Integração com o Site":
113
+
114
+ | Campo no painel SI9 | Campo na API | Campo normalizado | SQL |
115
+ |---|---|---|---|
116
+ | **Exibe Web** | **NÃO EXPOSTO NA API** | — | — |
117
+ | **Núcleo** | `website.showInCore` | `website_show_in_core` | BOOLEAN |
118
+ | **Minha Casa Minha Vida** | `website.mcmv` | `website_mcmv` | BOOLEAN |
119
+ | **Destaque** | `website.highlight` | (usado no campo base `destaque`) | BOOLEAN |
120
+ | **Super Destaque** | `website.superHighlight` | `website_super_highlight` | BOOLEAN |
121
+ | **Destaque Premium** | **NÃO EXPOSTO NA API** | — | — |
122
+
123
+ **Limitação:** O campo "Exibe Web" (que controla se o imóvel aparece no site) e "Destaque Premium" NÃO são expostos pela API da SI9. A API provavelmente já filtra internamente e só retorna imóveis com "Exibe Web = Sim".
124
+
125
+ | Campo normalizado | Fonte SI9 | Tipo | SQL |
126
+ |---|---|---|---|
127
+ | website_super_highlight | website.superHighlight | boolean | BOOLEAN |
128
+ | website_show_in_core | website.showInCore | boolean | BOOLEAN |
129
+ | website_mcmv | website.mcmv | boolean | BOOLEAN |
130
+
131
+ ### Destination extras
132
+
133
+ | Campo normalizado | Fonte SI9 | Tipo | SQL |
134
+ |---|---|---|---|
135
+ | destination_exchange | destination.exchange | boolean | BOOLEAN |
136
+
137
+ ### Localização complementar
138
+
139
+ | Campo normalizado | Fonte SI9 | Tipo | SQL |
140
+ |---|---|---|---|
141
+ | location_apartment | location.apartment | string | TEXT |
142
+ | location_block | location.block | string | TEXT |
143
+ | location_floor | location.floor | string | TEXT |
144
+ | location_quatrain | location.quatrain | string | TEXT |
145
+ | location_lot | location.lot | string | TEXT |
146
+
147
+ ### Dimensões extras
148
+
149
+ | Campo normalizado | Fonte SI9 | Tipo | SQL |
150
+ |---|---|---|---|
151
+ | dimensions_building_area | dimensions.buildingArea | number | DOUBLE PRECISION |
152
+ | dimensions_land_area | dimensions.landArea | number | DOUBLE PRECISION |
153
+ | dimensions_internal_area | dimensions.internalArea | number | DOUBLE PRECISION |
154
+ | dimensions_registered_area | dimensions.registeredArea | number | DOUBLE PRECISION |
155
+ | dimensions_common_area | dimensions.commonArea | number | DOUBLE PRECISION |
156
+ | dimensions_garage_area | dimensions.garageArea | number | DOUBLE PRECISION |
157
+ | dimensions_front_size | dimensions.frontSize | number | DOUBLE PRECISION |
158
+ | dimensions_funds_size | dimensions.fundsSize | number | DOUBLE PRECISION |
159
+ | dimensions_left_size | dimensions.leftSize | number | DOUBLE PRECISION |
160
+ | dimensions_right_size | dimensions.rightSize | number | DOUBLE PRECISION |
161
+
162
+ ### Features (booleans agrupados + numéricos/strings individuais)
163
+
164
+ | Campo normalizado | Fonte SI9 | Tipo | SQL |
165
+ |---|---|---|---|
166
+ | features | booleans features→labels PT-BR | string[] | TEXT[] |
167
+ | features_room | features.room | integer | INTEGER |
168
+ | features_kitchen | features.kitchen | integer | INTEGER |
169
+ | features_closet | features.closet | integer | INTEGER |
170
+ | features_balcony | features.balcony | integer | INTEGER |
171
+ | features_ar_condicionado | features.arCondicionado | integer | INTEGER |
172
+ | features_toilet | features.toilet | integer | INTEGER |
173
+ | features_floor | features.floor | string | TEXT |
174
+ | features_roof | features.roof | string | TEXT |
175
+ | features_ceiling | features.ceiling | string | TEXT |
176
+ | features_paving | features.paving | string | TEXT |
177
+ | features_pavement | features.pavement | string (enum) | TEXT |
178
+
179
+ ### Security (booleans agrupados)
180
+
181
+ | Campo normalizado | Fonte SI9 | Tipo | SQL |
182
+ |---|---|---|---|
183
+ | security | booleans security→labels PT-BR | string[] | TEXT[] |
184
+
185
+ ### Recreation (booleans agrupados + enums)
186
+
187
+ | Campo normalizado | Fonte SI9 | Tipo | SQL |
188
+ |---|---|---|---|
189
+ | recreation | booleans recreation→labels PT-BR | string[] | TEXT[] |
190
+ | recreation_heating | recreation.heating | string (enum) | TEXT |
191
+ | recreation_position_sun | recreation.positionSun | string (enum) | TEXT |
192
+ | recreation_position_court | recreation.positionCourt | string (enum) | TEXT |
193
+
194
+ ### Rural (booleans agrupados + numéricos/strings)
195
+
196
+ | Campo normalizado | Fonte SI9 | Tipo | SQL |
197
+ |---|---|---|---|
198
+ | rural | booleans rural→labels PT-BR | string[] | TEXT[] |
199
+ | rural_bushels | rural.bushels | number | DOUBLE PRECISION |
200
+ | rural_acre | rural.acre | number | DOUBLE PRECISION |
201
+ | rural_pasture | rural.pasture | string | TEXT |
202
+ | rural_mechanized | rural.mechanized | string | TEXT |
203
+ | rural_reserve | rural.reserve | number | DOUBLE PRECISION |
204
+ | rural_pigsty | rural.pigsty | integer | INTEGER |
205
+ | rural_aviary | rural.aviary | integer | INTEGER |
206
+ | rural_weir | rural.weir | integer | INTEGER |
207
+ | rural_wood_house | rural.woodHouse | integer | INTEGER |
208
+ | rural_brick_house | rural.brickHouse | integer | INTEGER |
209
+ | rural_mixed_house | rural.mixedHouse | integer | INTEGER |
210
+
211
+ ### Campos personalizados
212
+
213
+ | Campo normalizado | Fonte SI9 | Tipo | SQL |
214
+ |---|---|---|---|
215
+ | fields | fields[] | array {field, value} | JSONB |
216
+
217
+ **Limitação:** O campo `fields` é JSONB com objetos aninhados `{field, value}`. NÃO é filtrável via facets/busca no sistema genérico de listagem. Serve apenas para:
218
+ - Exibição na página do imóvel (renderizar os campos extras)
219
+ - Busca textual via FTS (se incluído no fts_vector, os textos são indexados)
220
+ - NÃO suporta facet tipo "mostre todos que têm campo X" sem query JSONB customizada
221
+
222
+ ---
223
+
224
+ ## 4. SITUAÇÕES DO SITE — O QUE O SI9 CONSEGUE RESOLVER
225
+
226
+ ### Badges no card
227
+ | Badge | Disponível? | Como resolver |
228
+ |---|---|---|
229
+ | Lançamento | SIM | `features.release` (boolean, dentro do array features) |
230
+ | Exclusivo | NÃO | Campo personalizado ou não exibir |
231
+ | Permuta | SIM | `destination_exchange` |
232
+ | Financiamento | NÃO | Campo personalizado ou não exibir |
233
+ | MCMV | SIM | `website_mcmv` |
234
+ | Mobiliado | SIM | Dentro do array `features` ("Mobiliado") |
235
+ | Destaque | SIM | Campo base `destaque` |
236
+ | Condomínio fechado | SIM | Dentro do array `features` ("Condomínio") |
237
+
238
+ ### Tarjas (imóvel indisponível)
239
+ | Tarja | Como resolver |
240
+ |---|---|
241
+ | Vendido | `general_data_situation = "SOLD"` |
242
+ | Alugado | `general_data_situation = "RENTED"` |
243
+ | Reservado | `general_data_situation = "RESERVED"` |
244
+
245
+ Enum completo: AVALIABLE, INACTIVE, RENTED, RESERVED, SOLD, INVOICE, TODOCUMENT, DELETE, TERMINATION, RENOVATION
246
+
247
+ ### Flags de layout
248
+ | Flag | Como resolver |
249
+ |---|---|
250
+ | Tem vídeo | `videos` não vazio |
251
+ | Tem tour 360 | `virtual_tours` não vazio |
252
+ | Geo exato | `lat` e `lng` preenchidos |
253
+ | Geo aproximado | Campo personalizado "Geolocalização aproximada" (sem valor) nos fields |
254
+ | Street View | Campo personalizado "permite-streetview" nos fields (tag) |
255
+ | Solicitar vídeo | `videos` vazio + tag "solicite-video" nos fields |
256
+ | Solicitar tour | `virtual_tours` vazio + tag "solicite-tour" nos fields |
257
+ | Solicitar endereço | Tag "solicite-endereco" nos fields |
258
+
259
+ ### Filtros de busca sugeridos (16 campos)
260
+
261
+ A busca deve usar campos inteligentes que agrupam múltiplos sub-campos em modais ou menus. Isso mantém a interface limpa (~16 filtros visíveis) enquanto dá acesso a 50+ opções internas. A implementação vai precisar de componentes de filtro especiais tipo "multiselect com grupos internos" ou "modal de checkboxes agrupados".
262
+
263
+ | # | Filtro | Campo(s) | Tipo | Observação |
264
+ |---|---|---|---|---|
265
+ | 1 | Operação | operacao | multiselect | venda, locação, temporada |
266
+ | 2 | Tipo | tipo | select | Apartamento, Casa, Terreno, etc. |
267
+ | 3 | Cidade | endereco_cidade | multiselect | — |
268
+ | 4 | Bairro | endereco_bairro | multiselect | parent: cidade |
269
+ | 5 | Condomínio | condominio_nome | multiselect | — |
270
+ | 6 | Valor | valor_venda / valor_locacao | range | Adapta conforme operação selecionada |
271
+ | 7 | Dormitórios | dormitorios | range | 1-5+ |
272
+ | 8 | Suítes | suites | range | 1-5+ |
273
+ | 9 | Banheiros | banheiros | range | 1-5+ |
274
+ | 10 | Vagas | vagas_garagem | range | 1-5+ |
275
+ | 11 | Área | area_total / area_privativa | range | Usa o que estiver disponível |
276
+ | 12 | Características | features + security + recreation + rural | **modal agrupado** | 4 grupos internos de checkboxes: Características, Segurança, Lazer, Rural. Cada grupo mostra os itens do respectivo array |
277
+ | 13 | Situação comercial | destaque + website_mcmv + destination_exchange + website_super_highlight + general_data_situation | **modal agrupado** | Checkboxes + select de situação. Agrupa tudo que é decisão comercial/legal num único campo |
278
+ | 14 | Mídia | (computado: tem_video, tem_tour) | multiselect | "Possui vídeo", "Possui tour 360" — derivados da existência de videos[] e virtual_tours[] |
279
+ | 15 | Campos extras | fields | multiselect | Itens dos campos personalizados da imobiliária. Permite buscar por tags e características customizadas |
280
+ | 16 | Busca textual | fts | fulltext | Busca livre em título, descrição, endereço, tipo, etc. |
281
+
282
+ ### Campos para full-text search
283
+ Campos recomendados para indexação de busca textual:
284
+ - title, description, reference
285
+ - endereco_cidade, endereco_bairro, endereco_logradouro, endereco_numero, endereco_complemento, endereco_referencia, endereco_zona, endereco_estado, endereco_cep
286
+ - tipo, condominio_nome, corretor_nome
287
+ - general_data_situation
288
+ - features (array), security (array), recreation (array)
289
+ - recreation_position_sun, recreation_position_court
290
+ - features_floor, features_roof, features_ceiling, features_pavement
291
+
292
+ ---
293
+
294
+ ## 5. TRANSFORMAÇÕES RECOMENDADAS
295
+
296
+ ### Subtipo
297
+ O SI9 não tem subtipo. Pode ser gerado a partir do `tipo` com regras de split:
298
+ ```
299
+ Casa → tipo: "Casa", subtipo: null
300
+ Sobrado → tipo: "Casa", subtipo: "Sobrado"
301
+ Apartamento → tipo: "Apartamento", subtipo: null
302
+ Edifício/Prédio → tipo: "Apartamento", subtipo: "Edifício/Prédio"
303
+ Terreno Comercial → tipo: "Terreno", subtipo: "Terreno Comercial"
304
+ ```
305
+
306
+ ### Valor por m²
307
+ Pode ser calculado: `(valor_venda || valor_locacao) / (area_total || area_privativa)`. Arredondar 2 casas.
308
+
309
+ ### Campos personalizados como flags de layout
310
+ O SI9 tem `fields[]` (chave-valor). Como a API não expõe campos nativos pra controlar certas funcionalidades do site (street view, solicitar vídeo, etc.), os campos customizados servem como flags.
311
+
312
+ **Campos reconhecidos pelo conversor:**
313
+ - `"Corretor"` (com valor) → alimenta `corretor_nome` (legado — agora vem do broker nativo)
314
+ - `"Corretor ID"` (com valor) → alimenta `corretor_key` (legado — agora vem do broker nativo)
315
+ - `"Geolocalização aproximada"` (sem valor) → ativa geo aproximado
316
+
317
+ **Campos customizados usados como flags de layout:**
318
+ - `"permite-streetview"` (sem valor) → habilita Street View na página do imóvel
319
+ - `"solicite-video"` (sem valor) → mostra botão "Solicite Vídeo" quando imóvel não tem vídeo
320
+ - `"solicite-tour"` (sem valor) → mostra botão "Solicite Tour" quando imóvel não tem tour
321
+ - `"solicite-endereco"` (sem valor) → mostra botão "Solicitar Endereço" quando não tem geo exato
322
+
323
+ **Regra:** Campos sem valor = flag ativa. A existência do campo já é suficiente pra ativar a funcionalidade. Campos com valor = exibidos como características extras na página.
324
+
325
+ ---
326
+
327
+ ## 6. MAPEAMENTO DE LABELS PARA EXIBIÇÃO
328
+
329
+ Muitos campos do SI9 usam enums em inglês. Qualquer site que exiba esses valores pro usuário precisa traduzir pra português.
330
+
331
+ ### Situação do imóvel → tarjas / stripes / indicadores visuais
332
+
333
+ O campo `general_data_situation` indica o estado do imóvel. Tradução recomendada:
334
+
335
+ | Valor da API | Label PT-BR | Uso visual recomendado |
336
+ |---|---|---|
337
+ | SOLD | Vendido | Tarja diagonal sobre o card/imagem |
338
+ | RENTED | Alugado | Tarja diagonal sobre o card/imagem |
339
+ | RESERVED | Reservado | Tarja diagonal sobre o card/imagem |
340
+ | INVOICE | Em faturamento | Tarja ou badge |
341
+ | RENOVATION | Em reforma | Tarja ou badge |
342
+ | AVALIABLE | — | Não exibir (é o estado normal) |
343
+ | INACTIVE | — | Não exibir (imóvel oculto) |
344
+ | TODOCUMENT | — | Não exibir |
345
+ | DELETE | — | Não exibir |
346
+ | TERMINATION | — | Não exibir |
347
+
348
+ ### Enums que precisam de tradução
349
+
350
+ | Campo | Valor API → Label PT-BR |
351
+ |---|---|
352
+ | recreation_heating | GAS → "Gás", SOLAR → "Solar", ELETRIC → "Elétrico" |
353
+ | recreation_position_sun | NORTH → "Norte", SOUTH → "Sul", EAST → "Leste", WEST → "Oeste" |
354
+ | recreation_position_court | MIDDLE_COURT → "Meio de quadra", CORNER → "Esquina", SUB_CORNER → "Sub-esquina" |
355
+ | features_pavement | COBBLESTONE → "Paralelepípedo", ASPHALT → "Asfalto", GRAVEL → "Cascalho" |
356
+
357
+ ### Campos que JÁ vêm traduzidos (sem necessidade de mapear)
358
+
359
+ Os arrays `features`, `security`, `recreation`, `rural` já contêm labels em PT-BR direto do conversor. Exemplo: `features: ["Churrasqueira", "Elevador", "Mobiliado"]`.
360
+
361
+ ### Regra geral
362
+
363
+ | Tipo de campo | Precisa traduzir? |
364
+ |---|---|
365
+ | Enum em inglês (string) | SIM — sempre criar mapa de tradução |
366
+ | Array de labels (string[]) | NÃO — já vem traduzido do conversor |
367
+ | Boolean | NÃO |
368
+ | Number | NÃO |
369
+
370
+ ---
371
+
372
+ ## 7. PRESET DE EXIBIÇÃO RECOMENDADO
373
+
374
+ Organização sugerida de como apresentar os dados deste CRM em interfaces de listagem e detalhe. Agnóstico de tecnologia — aplicável a qualquer site ou app.
375
+
376
+ ### Card de listagem (resumo do imóvel)
377
+
378
+ **Tarjas de indisponibilidade** (indicador visual sobre a imagem):
379
+ - `general_data_situation`: SOLD → "Vendido", RENTED → "Alugado", RESERVED → "Reservado", INVOICE → "Em faturamento", RENOVATION → "Em reforma"
380
+ - Não exibir tarja pra AVALIABLE, INACTIVE, TODOCUMENT, DELETE, TERMINATION
381
+
382
+ **Badges de destaque** (labels sobre a imagem, raramente mais de 2-3 aparecem ao mesmo tempo):
383
+ - `website_mcmv` → "MCMV"
384
+ - `destination_exchange` → "Permuta"
385
+ - `website_super_highlight` → "Super Destaque"
386
+ - Opcionais (dentro do array features): "Mobiliado", "Condomínio", "Alto padrão"
387
+
388
+ **Atributos principais com ícone** (resumo da ficha):
389
+ - dormitorios, suites, banheiros, vagas_garagem, area_privativa, area_total
390
+
391
+ ### Página de detalhe — Ficha do imóvel
392
+
393
+ **Seção 1: Principal (ficha técnica)**
394
+ - Contadores: dormitorios, suites, banheiros, vagas_garagem, features_room (salas), features_kitchen (cozinhas), features_closet (closets), features_balcony (varandas), features_ar_condicionado, features_toilet (lavabos)
395
+ - Áreas: area_total, area_privativa, area_util
396
+ - Classificação: tipo, operacao
397
+ - Situação comercial: general_data_situation, website_mcmv, destination_exchange
398
+
399
+ **Seção 2: Características e acabamentos** (juntos — acabamentos são poucos campos)
400
+ - Array `features[]` expandido como checkmarks (Churrasqueira, Elevador, etc.)
401
+ - Acabamentos: features_floor (piso), features_roof (teto), features_ceiling (forro), features_paving (pavimentação), features_pavement (calçamento)
402
+
403
+ **Seção 3: Segurança**
404
+ - Array `security[]` expandido como checkmarks (Interfone, Murado, Portão, etc.)
405
+
406
+ **Seção 4: Lazer** (incluir enums junto com booleans)
407
+ - Array `recreation[]` expandido como checkmarks (Piscina, Academia, etc.)
408
+ - Enums: recreation_heating (aquecimento), recreation_position_sun (posição solar), recreation_position_court (posição quadra)
409
+
410
+ **Seção 5: Dimensões**
411
+ - dimensions_building_area, dimensions_land_area, dimensions_internal_area, dimensions_registered_area, dimensions_common_area, dimensions_garage_area
412
+ - dimensions_front_size, dimensions_funds_size, dimensions_left_size, dimensions_right_size
413
+
414
+ **Seção 6: Localização complementar**
415
+ - location_apartment, location_block, location_floor, location_quatrain, location_lot
416
+
417
+ **Seção 7: Rural** (só exibir se imóvel tiver dados rurais)
418
+ - Array `rural[]` expandido como checkmarks
419
+ - Numéricos: rural_bushels, rural_acre, rural_pasture, rural_mechanized, rural_reserve, rural_pigsty, rural_aviary, rural_weir, rural_wood_house, rural_brick_house, rural_mixed_house
420
+
421
+ **Seção 8: Campos extras** (fields[] customizados)
422
+ - Exibir como lista key-value os campos que não foram consumidos pelo conversor
423
+
424
+ ### Página de detalhe — Caixa de valores (lateral)
425
+
426
+ **Bloco Venda** (se operação inclui venda):
427
+ - Valor principal: valor_venda
428
+ - Flags: website_mcmv, destination_exchange
429
+
430
+ **Bloco Locação** (se operação inclui locação):
431
+ - Valor principal: valor_locacao
432
+ - Taxas: valor_condominio, valor_iptu, values_trash_fee, values_disaster_fee
433
+ - Outros: values_discount_value, values_fci_value, values_assigned_value
434
+
435
+ ---
436
+
437
+ ## 8. ENUMS E VALORES POSSÍVEIS (referência completa)
438
+
439
+ ### generalData.situation
440
+ AVALIABLE (disponível), INACTIVE (inativo), RENTED (alugado), RESERVED (reservado), SOLD (vendido), INVOICE (em faturamento), TODOCUMENT (em documentação), DELETE (excluído), TERMINATION (rescisão), RENOVATION (em reforma)
441
+
442
+ **Nota:** "AVALIABLE" é typo oficial da API (falta um L).
443
+
444
+ ### generalData.category.name (tipos encontrados nos dados)
445
+ Apartamento, Casa, Terreno, Sobrado, Sala Comercial, Chácara, Ponto Comercial, Terreno Comercial, Edifício/Prédio, Rural, Sítio
446
+
447
+ ### recreation.heating
448
+ GAS, SOLAR, ELETRIC
449
+
450
+ ### recreation.positionSun
451
+ NORTH, SOUTH, EAST, WEST
452
+
453
+ ### recreation.positionCourt
454
+ MIDDLE_COURT, CORNER, SUB_CORNER
455
+
456
+ ### features.pavement
457
+ COBBLESTONE (paralelepípedo), ASPHALT (asfalto), GRAVEL (cascalho)
458
+
459
+ ---
460
+
461
+ ## 7. ORIENTAÇÕES PARA BANCO DE DADOS
462
+
463
+ Diretrizes genéricas de como implementar os campos extras deste CRM em qualquer banco de dados relacional.
464
+
465
+ ### Tipos de coluna recomendados
466
+
467
+ | Tipo do campo | Tipo SQL recomendado | Exemplo |
468
+ |---|---|---|
469
+ | string | TEXT | general_data_situation, features_floor |
470
+ | string (curta, enum) | VARCHAR(50) | recreation_heating, features_pavement |
471
+ | number (monetário) | DOUBLE PRECISION | values_discount_value, values_trash_fee |
472
+ | number (inteiro/contagem) | INTEGER | features_room, rural_pigsty |
473
+ | number (medida/área) | DOUBLE PRECISION | dimensions_building_area, dimensions_front_size |
474
+ | boolean | BOOLEAN | website_mcmv, destination_exchange |
475
+ | string[] (array de labels) | TEXT[] | features, security, recreation, rural |
476
+ | object (chave-valor) | JSONB | fields |
477
+
478
+ ### Índices recomendados
479
+
480
+ | Campo | Tipo de índice | Motivo |
481
+ |---|---|---|
482
+ | general_data_situation | B-tree | Filtro frequente por situação (SOLD, RENTED, etc.) |
483
+ | features | GIN | Busca por itens dentro do array (ex: WHERE 'Piscina' = ANY(features)) |
484
+ | security | GIN | Idem |
485
+ | recreation | GIN | Idem |
486
+ | rural | GIN | Idem |
487
+ | website_mcmv | B-tree | Filtro boolean |
488
+ | destination_exchange | B-tree | Filtro boolean |
489
+ | dimensions_building_area | B-tree | Range queries |
490
+ | dimensions_land_area | B-tree | Range queries |
491
+
492
+ ### Campos recomendados para Full-Text Search
493
+
494
+ Além dos campos base (title, description, endereço, tipo), incluir estes extras do CRM no índice de busca textual:
495
+
496
+ ```
497
+ general_data_situation
498
+ features (array → converter cada item pra texto)
499
+ security (array)
500
+ recreation (array)
501
+ rural (array)
502
+ condominio_nome (já no base)
503
+ corretor_nome (já no base)
504
+ recreation_position_sun
505
+ recreation_position_court
506
+ features_floor
507
+ features_roof
508
+ features_ceiling
509
+ features_pavement
510
+ recreation_heating
511
+ location_apartment
512
+ location_block
513
+ location_floor
514
+ ```
515
+
516
+ ### Campos que NÃO precisam de índice
517
+
518
+ Campos raramente usados em filtros ou com baixa cardinalidade:
519
+ - general_data_board (placa)
520
+ - values_fci_value, values_assigned_value, values_disaster_fee (quase sempre 0)
521
+ - dimensions_internal_area, dimensions_registered_area, dimensions_common_area, dimensions_garage_area (quase sempre null)
522
+ - rural_* (só relevante pra imóveis rurais, minoria)
523
+ - location_quatrain, location_lot (raramente preenchidos)
524
+
525
+ ### Campos computados sugeridos (gerar no backend antes de salvar)
526
+
527
+ | Campo computado | Fórmula | Tipo SQL |
528
+ |---|---|---|
529
+ | valor_m2 | (valor_venda \|\| valor_locacao) / (area_total \|\| area_privativa) | DECIMAL(10,2) |
530
+ | subtipo | Derivado de `tipo` com regras de split | TEXT |
531
+ | endereco_completo | Concatenação formatada dos campos de endereço | TEXT |
532
+ | seo_slug | Slug gerado do título + referência | VARCHAR(255) |
533
+ | thumbnails | Extraído de images[].full (primeiras N URLs) | TEXT[] ou JSONB |
534
+
535
+ ---
536
+
537
+ ## 8. OBSERVAÇÕES TÉCNICAS
538
+
539
+ - Valores monetários em REAIS — nunca dividir por 100
540
+ - IPTU é valor ANUAL
541
+ - lat/lng vêm como STRING — converter pra number
542
+ - `recreation.playgroud` tem typo (falta o "n") — manter como vem
543
+ - Token expira em 1h (3599s) — suporta refresh_token
544
+ - Sem paginação na API — GET /property retorna tudo de uma vez
545
+ - Imagens têm campo `displaySite` (boolean) — filtrar só as que são true
546
+ - `pic360` nas imagens é boolean (indica foto panorâmica), não URL de tour
547
+ - Endpoint `GET /user` lista corretores mas SEM vínculo ao imóvel
package/package.json CHANGED
@@ -1,13 +1,14 @@
1
1
  {
2
2
  "name": "@horizon-integrations/si9-crm",
3
- "version": "1.1.6",
3
+ "version": "1.1.7",
4
4
  "description": "Integração da Imobland Horizon com a SI9 CRM",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
7
7
  "types": "dist/index.d.ts",
8
8
  "files": [
9
9
  "dist",
10
- "examples"
10
+ "examples",
11
+ "FICHA_TECNICA_INTEGRACAO.md"
11
12
  ],
12
13
  "scripts": {
13
14
  "build": "tsup",