@horizon-framework/website-dev-docs 2.3.0
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.
- package/agents/AGENTE_FULLSTACK.md +209 -0
- package/agents/AGENTE_LAYOUT_DESIGNER.md +930 -0
- package/checklists/ADICIONAR_CAMPO.md +95 -0
- package/checklists/CRIAR_SITE_NOVO.md +163 -0
- package/checklists/PUBLICAR_SITE.md +75 -0
- package/checklists/TROCAR_CRM.md +96 -0
- package/commercial/PACOTES_PAGINAS.md +86 -0
- package/commercial/POSSIBILIDADES_VENDA.md +52 -0
- package/index.md +54 -0
- package/knowledge/API_PROPERTY.md +566 -0
- package/knowledge/ARQUITETURA_GERAL.md +169 -0
- package/knowledge/ARQUITETURA_MODULOS_WEB.md +241 -0
- package/knowledge/BATCH_TOTALS_API.md +200 -0
- package/knowledge/CAPABILITIES.md +190 -0
- package/knowledge/COMPONENTES_GLOBAIS_UI.md +407 -0
- package/knowledge/CRMS_INTEGRACOES.md +151 -0
- package/knowledge/DESIGN_AVANCADO.md +403 -0
- package/knowledge/DESIGN_SYSTEM_CATALOG.md +349 -0
- package/knowledge/DESIGN_TEMPLATES_CATALOG.md +61 -0
- package/knowledge/DOMINIO_ENTIDADES.md +328 -0
- package/knowledge/HOOKS_REGISTRY.md +127 -0
- package/knowledge/MODULE_CREATION_PATTERN.md +624 -0
- package/knowledge/NAVEGACAO_DINAMICA.md +233 -0
- package/knowledge/PAGINAS_BASICAS.md +63 -0
- package/knowledge/SEARCH_ENGINE_API.md +1038 -0
- package/knowledge/SISTEMA_MODULAR.md +109 -0
- package/knowledge/SISTEMA_SCHEMAS.md +126 -0
- package/knowledge/SSOT_SPECIFICATION_V2.md +333 -0
- package/knowledge/UI_KIT_COMPLETO.md +125 -0
- package/modules/property/MODULO_IMOBILIARIO.md +356 -0
- package/package.json +17 -0
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# Sistema Modular — Como Funcionam Modulos no Horizon
|
|
2
|
+
|
|
3
|
+
> Cada entidade de dados (imovel, corretor, condominio) e um modulo independente.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Conceito
|
|
8
|
+
|
|
9
|
+
Um modulo Horizon e uma unidade completa que cobre uma entidade de ponta a ponta:
|
|
10
|
+
- Pacote NPM com schema base (dominio)
|
|
11
|
+
- Banco de dados (tabela, indices, FTS)
|
|
12
|
+
- API backend (controllers, services, schemas)
|
|
13
|
+
- Frontend (core, features, customs)
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Modulos Existentes
|
|
18
|
+
|
|
19
|
+
| Modulo | Backend | Frontend | NPM Domain | Status |
|
|
20
|
+
|---|---|---|---|---|
|
|
21
|
+
| **Property** (Imoveis) | Completo | Completo (10+ subprojetos) | @horizon-domains/property-model | Producao |
|
|
22
|
+
| **Broker** (Corretores) | Completo | Completo (2 subprojetos) | @horizon-domains/broker-model | Producao |
|
|
23
|
+
| **Institucional** | N/A | Parcial (so localizacao) | N/A | Parcial |
|
|
24
|
+
| **Financiamento** | N/A | Parcial (componentes) | N/A | Parcial |
|
|
25
|
+
|
|
26
|
+
### Modulos Futuros (pacotes criados mas vazios)
|
|
27
|
+
- Blog
|
|
28
|
+
- Cidade e Bairros
|
|
29
|
+
- Condominio/Empreendimentos
|
|
30
|
+
- Instagram Advanced
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## Estrutura de um Modulo Completo
|
|
35
|
+
|
|
36
|
+
### Backend (apps/api/src/modules/{entity}/)
|
|
37
|
+
```
|
|
38
|
+
modules/{entity}/
|
|
39
|
+
├── schemas/
|
|
40
|
+
│ ├── entity-schema.ts # SSOT local (~1000 linhas)
|
|
41
|
+
│ ├── entity-schema.zod.ts # Validacao Zod
|
|
42
|
+
│ └── search-schema.ts # Schema de busca
|
|
43
|
+
├── controllers/
|
|
44
|
+
│ ├── search.controller.ts # POST busca
|
|
45
|
+
│ ├── find.controller.ts # POST busca unica
|
|
46
|
+
│ ├── sync.controller.ts # PUT/DELETE sincronizacao
|
|
47
|
+
│ └── schemas.controller.ts # GET schemas
|
|
48
|
+
├── services/
|
|
49
|
+
│ ├── search.service.ts
|
|
50
|
+
│ ├── find.service.ts
|
|
51
|
+
│ └── sync.service.ts
|
|
52
|
+
└── mappers/
|
|
53
|
+
├── computedFields/ # Campos derivados
|
|
54
|
+
└── dataModifier/ # Regras de negocio
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Frontend (apps/web/src/modules/{entity}/)
|
|
58
|
+
```
|
|
59
|
+
modules/{entity}/
|
|
60
|
+
├── core/
|
|
61
|
+
│ ├── item/ # Configuracao de 1 item
|
|
62
|
+
│ │ ├── schemas/ # TypeScript + JSON schemas
|
|
63
|
+
│ │ ├── computed-fields/ # Campos computados runtime
|
|
64
|
+
│ │ ├── enrichMapper.ts # Mapper de enriquecimento
|
|
65
|
+
│ │ └── {entity}-url-builder.ts
|
|
66
|
+
│ ├── list/ # Configuracao de lista
|
|
67
|
+
│ ├── services/ # Servicos de API
|
|
68
|
+
│ └── libs/ # Libs especificas
|
|
69
|
+
├── features/ # Features/paginas
|
|
70
|
+
│ ├── item-display/ # Pagina individual
|
|
71
|
+
│ ├── search-list/ # Listagem com busca
|
|
72
|
+
│ ├── favorites/ # Favoritos
|
|
73
|
+
│ └── item-print/ # Impressao
|
|
74
|
+
└── customs/ # Componentes customizados
|
|
75
|
+
├── home-search-bar/
|
|
76
|
+
└── {entity}-showcase/
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## Registro de Modulos
|
|
82
|
+
|
|
83
|
+
O frontend tem um `MODULES_REGISTRY` que conecta modulos com:
|
|
84
|
+
- Sitemap providers
|
|
85
|
+
- Rotas dinamicas
|
|
86
|
+
- Resolvers de dados
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## Como Criar Modulo Novo
|
|
91
|
+
|
|
92
|
+
Ver knowledge `MODULE_CREATION_PATTERN.md` para o passo-a-passo completo:
|
|
93
|
+
1. Criar pacote NPM com schema base
|
|
94
|
+
2. Criar tabela SQL + indices + FTS
|
|
95
|
+
3. Criar modulo na API (schemas, controllers, services)
|
|
96
|
+
4. Criar modulo no frontend (core, features)
|
|
97
|
+
5. Registrar no MODULES_REGISTRY
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## Integracao com CRM
|
|
102
|
+
|
|
103
|
+
Modulos de entidade podem receber dados de CRMs externos:
|
|
104
|
+
- Property ← Jetimob, SI9, Publisher, Arbo
|
|
105
|
+
- Broker ← (futuro)
|
|
106
|
+
- Condominio ← (futuro)
|
|
107
|
+
|
|
108
|
+
Cada CRM tem um pacote conversor que transforma dados para o formato Horizon.
|
|
109
|
+
Ver knowledge `CRMS_INTEGRACOES.md` e `SISTEMA_SCHEMAS.md`.
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
# Sistema de Schemas — Domain Models e Conversores
|
|
2
|
+
|
|
3
|
+
> Como schemas base, conversores CRM e entity-schema se conectam.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Cadeia de Schemas
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
1. PACOTE DOMINIO BASE (@horizon-domains/{entity}-model)
|
|
11
|
+
→ 45 campos base padronizados
|
|
12
|
+
→ TypeScript + Zod
|
|
13
|
+
↓
|
|
14
|
+
2. PACOTE CONVERSOR CRM (@horizon-integrations/{crm}-crm)
|
|
15
|
+
→ Converte formato CRM → formato Horizon
|
|
16
|
+
→ Adiciona campos extras do CRM (80+ campos)
|
|
17
|
+
→ Schema Zod de validacao
|
|
18
|
+
→ FICHA_TECNICA_INTEGRACAO.md
|
|
19
|
+
↓
|
|
20
|
+
3. ENTITY-SCHEMA no Backend (apps/api/src/modules/{entity}/schemas/)
|
|
21
|
+
→ Importa schema do pacote CRM
|
|
22
|
+
→ Adiciona overrides locais
|
|
23
|
+
→ Adiciona campos computed
|
|
24
|
+
→ Adiciona campos customizados do cliente
|
|
25
|
+
→ SSOT v2.0 (~1000 linhas)
|
|
26
|
+
↓
|
|
27
|
+
4. TABELA no Banco de Dados
|
|
28
|
+
→ Colunas baseadas no entity-schema
|
|
29
|
+
→ Indices, FTS tsvector, PostGIS geometry
|
|
30
|
+
↓
|
|
31
|
+
5. SCHEMA GERADO no Frontend
|
|
32
|
+
→ npx tsx scripts/generate-schema.ts
|
|
33
|
+
→ schema.generated.json
|
|
34
|
+
→ Usado por enrichMapper, fields-lists, display
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## Pacote Dominio Base
|
|
40
|
+
|
|
41
|
+
**Localização NPM:** `@horizon-domains/{entity}-model`
|
|
42
|
+
**Repo:** `/root/github/horizon-npm-packages/horizon-modules/{entity}/domain-data/`
|
|
43
|
+
|
|
44
|
+
### Property Domain (45 campos base)
|
|
45
|
+
|
|
46
|
+
Campos que TODO imovel tem, independente do CRM:
|
|
47
|
+
- Identificacao: reference, title, description
|
|
48
|
+
- Comercial: operacao, valor_venda, valor_locacao, valor_diaria
|
|
49
|
+
- Estrutura: area_total, dormitorios, banheiros, vagas_garagem, tipo, subtipo
|
|
50
|
+
- Localizacao: endereco_cidade, endereco_bairro, lat, lng
|
|
51
|
+
- Caracteristicas: caracteristicas[], tags[]
|
|
52
|
+
- Midia: images[], videos[]
|
|
53
|
+
- Sistema: created_at, updated_at
|
|
54
|
+
|
|
55
|
+
### Outros Dominios
|
|
56
|
+
- `@horizon-domains/broker-model` — Campos base de corretores
|
|
57
|
+
- Blog, Condominio, etc. — Pacotes criados mas vazios
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## Pacotes Conversores CRM
|
|
62
|
+
|
|
63
|
+
**Localização NPM:** `@horizon-integrations/{crm}-crm`
|
|
64
|
+
**Repo:** `/root/github/horizon-npm-packages/horizon-integrations/lista-crms/{crm}/`
|
|
65
|
+
|
|
66
|
+
### CRMs Disponíveis
|
|
67
|
+
|
|
68
|
+
| CRM | Pacote | Campos | Status |
|
|
69
|
+
|---|---|---|---|
|
|
70
|
+
| SI9 | @horizon-integrations/si9-crm | ~60 campos | Publicado |
|
|
71
|
+
| Jetimob | @horizon-integrations/jetimob-crm | ~80 campos | Publicado |
|
|
72
|
+
| Publisher | @horizon-integrations/publisher-crm | ~70 campos | Publicado |
|
|
73
|
+
| Arbo | @horizon-integrations/arbo-crm | ~65 campos | Publicado |
|
|
74
|
+
|
|
75
|
+
### O que cada pacote CRM exporta
|
|
76
|
+
- `horizon-property-schema-by-{crm}.ts` — Schema com key, label, type, enum
|
|
77
|
+
- `horizon-property-schema-by-{crm}.zod.ts` — Validacao Zod
|
|
78
|
+
- `FICHA_TECNICA_INTEGRACAO.md` — Documentacao completa do CRM
|
|
79
|
+
- Funcao de conversao: dados CRM → formato Horizon
|
|
80
|
+
|
|
81
|
+
### Integration Toolkit
|
|
82
|
+
**Pacote:** `@horizon-integrations/integration-toolkit`
|
|
83
|
+
Base reutilizavel para criar novos conversores (batch converter, helpers).
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## SSOT v2.0 (Entity Schema)
|
|
88
|
+
|
|
89
|
+
Cada modulo no backend tem um entity-schema.ts que e o SSOT:
|
|
90
|
+
|
|
91
|
+
```typescript
|
|
92
|
+
{
|
|
93
|
+
key: "campo_exemplo",
|
|
94
|
+
type: "String",
|
|
95
|
+
categories: ["valores"],
|
|
96
|
+
enum: { "key": "Label" },
|
|
97
|
+
format: "currency",
|
|
98
|
+
unit: "BRL",
|
|
99
|
+
rules: { conditions: ["operacao:venda"] },
|
|
100
|
+
validation: { required: true, min: 0 },
|
|
101
|
+
ui: {
|
|
102
|
+
label: "Campo Exemplo",
|
|
103
|
+
searchable: true,
|
|
104
|
+
filterable: true,
|
|
105
|
+
sortable: true
|
|
106
|
+
},
|
|
107
|
+
audit: { origin: "horizon-base" }
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Ver knowledge `SSOT_SPECIFICATION_V2.md` para especificacao completa.
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
## Fluxo ao Trocar CRM
|
|
116
|
+
|
|
117
|
+
1. Instalar novo pacote CRM no backend
|
|
118
|
+
2. Atualizar imports no entity-schema.ts
|
|
119
|
+
3. Recriar tabela no banco (DROP + CREATE baseado no novo schema)
|
|
120
|
+
4. Gerar Prisma client
|
|
121
|
+
5. Reiniciar API
|
|
122
|
+
6. Re-sincronizar dados
|
|
123
|
+
7. Regenerar schema no frontend
|
|
124
|
+
8. Ajustar campos na busca, cards, pagina
|
|
125
|
+
|
|
126
|
+
Ver checklist `TROCAR_CRM.md` para o passo-a-passo completo.
|
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
# SSOT (Single Source of Truth) - Especificação v2.0
|
|
2
|
+
|
|
3
|
+
## Visão Geral
|
|
4
|
+
|
|
5
|
+
O novo formato SSOT v2.0 organiza metadados de campos em **contextos específicos**, permitindo separação clara de responsabilidades e melhor organização dos dados.
|
|
6
|
+
|
|
7
|
+
### Filosofia do Formato
|
|
8
|
+
- **Contextos Separados**: Cada tipo de metadado tem seu lugar específico
|
|
9
|
+
- **Estrutura Hierárquica**: Agrupamento lógico das propriedades
|
|
10
|
+
- **Flexibilidade**: Campos podem ser vazios e preenchidos conforme necessário
|
|
11
|
+
- **Evolução Gradual**: Estrutura permite crescimento sem quebrar compatibilidade
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Estrutura dos Contextos
|
|
16
|
+
|
|
17
|
+
### 1. **RAIZ** - Identificação Básica
|
|
18
|
+
```typescript
|
|
19
|
+
{
|
|
20
|
+
"key": "campo_exemplo", // Identificador único (snake_case)
|
|
21
|
+
"type": "String", // Tipo de dado (String, Number, Boolean, String[], Json)
|
|
22
|
+
"enum": {"key": "Label"}, // Valores possíveis (quando aplicável)
|
|
23
|
+
"format": "currency", // Formatação de exibição
|
|
24
|
+
"unit": "BRL", // Unidade de medida
|
|
25
|
+
"categories": ["valores"] // Tags/categorias para filtros
|
|
26
|
+
}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### 2. **RULES** - Regras e Relações
|
|
30
|
+
```typescript
|
|
31
|
+
"rules": {
|
|
32
|
+
"parent": "tipo", // Campo pai hierárquico
|
|
33
|
+
"conditions": ["operacao:venda"] // Condições de visibilidade
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### 3. **VALIDATION** - Validação Backend/Zod
|
|
38
|
+
```typescript
|
|
39
|
+
"validation": {
|
|
40
|
+
"required": true, // Campo obrigatório
|
|
41
|
+
"min": 0, // Valor mínimo (números)
|
|
42
|
+
"max": 999999.99, // Valor máximo (números)
|
|
43
|
+
"minLength": 3, // Tamanho mínimo (strings)
|
|
44
|
+
"maxLength": 200, // Tamanho máximo (strings)
|
|
45
|
+
"precision": 2 // Casas decimais
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### 4. **DB** - Configurações de Banco
|
|
50
|
+
```typescript
|
|
51
|
+
"db": {
|
|
52
|
+
// VAZIO por enquanto - será preenchido conforme necessário
|
|
53
|
+
// Futuro: index, unique, default, etc.
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### 5. **UI** - Interface e Experiência
|
|
58
|
+
```typescript
|
|
59
|
+
"ui": {
|
|
60
|
+
"label": "Campo Exemplo", // Rótulo para exibição
|
|
61
|
+
"description": "Texto de ajuda", // Helper text para formulários
|
|
62
|
+
"placeholder": "Digite...", // Placeholder para inputs
|
|
63
|
+
"icon": "home", // Ícone semântico
|
|
64
|
+
"displayTemplate": "{{value}} m²", // Template de exibição
|
|
65
|
+
"mask": "cpf", // Máscara de input (cpf, cnpj, cep, phone, email)
|
|
66
|
+
"searchable": true, // Pesquisável por texto
|
|
67
|
+
"filterable": true, // Aparece nos filtros
|
|
68
|
+
"sortable": true // Permite ordenação
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### 6. **AUDIT** - Auditoria e Rastreamento
|
|
73
|
+
```typescript
|
|
74
|
+
"audit": {
|
|
75
|
+
"origin": "horizon-base/imovel", // Origem do campo
|
|
76
|
+
"modifiedBy": ["system"] // Histórico de modificações
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## Tipos de Dados Suportados
|
|
83
|
+
|
|
84
|
+
| Tipo | Descrição | Exemplo |
|
|
85
|
+
|------|-----------|---------|
|
|
86
|
+
| `String` | Texto simples | "Casa no Centro" |
|
|
87
|
+
| `Number` | Números inteiros e decimais | 150000.50 |
|
|
88
|
+
| `Boolean` | Verdadeiro/Falso | true, false |
|
|
89
|
+
| `String[]` | Array de strings | ["piscina", "churrasqueira"] |
|
|
90
|
+
| `Json` | Objeto JSON | {"lat": -27.5, "lng": -48.5} |
|
|
91
|
+
| `Json[]` | Array de objetos | [{"url": "...", "caption": "..."}] |
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## Formatos de Exibição
|
|
96
|
+
|
|
97
|
+
| Format | Unit | Exemplo Entrada | Exemplo Saída |
|
|
98
|
+
|--------|------|----------------|---------------|
|
|
99
|
+
| `currency` | `BRL` | 150000 | R$ 150.000,00 |
|
|
100
|
+
| `currency` | `USD` | 150000 | $ 150,000.00 |
|
|
101
|
+
| `area` | `m2` | 150 | 150 m² |
|
|
102
|
+
| `distance` | `km` | 1.5 | 1,5 km |
|
|
103
|
+
| `percent` | - | 0.15 | 15% |
|
|
104
|
+
| `count` | - | 3 | 3 itens |
|
|
105
|
+
| `date` | - | "2024-01-01" | 01/01/2024 |
|
|
106
|
+
| `datetime` | - | "2024-01-01T10:30:00Z" | 01/01/2024 10:30 |
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## Categorias Recomendadas
|
|
111
|
+
|
|
112
|
+
| Categoria | Descrição | Campos Típicos |
|
|
113
|
+
|-----------|-----------|----------------|
|
|
114
|
+
| `valores` | Campos monetários | valor_venda, valor_locacao |
|
|
115
|
+
| `localizacao` | Endereço e geolocalização | endereco_cidade, latitude, longitude |
|
|
116
|
+
| `estrutura` | Características físicas | quartos, banheiros, area_total |
|
|
117
|
+
| `identificacao` | Títulos e referências | title, reference |
|
|
118
|
+
| `comercial` | Informações comerciais | operacao, status |
|
|
119
|
+
| `caracteristicas` | Amenidades e comodidades | piscina, churrasqueira |
|
|
120
|
+
| `sistema` | Campos internos | id, created_at, updated_at |
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## Máscaras Disponíveis
|
|
125
|
+
|
|
126
|
+
### Automáticas (inferidas do format + unit)
|
|
127
|
+
- `currency-brl` → R$ 1.000,00 (format: currency + unit: BRL)
|
|
128
|
+
- `currency-usd` → $ 1,000.00 (format: currency + unit: USD)
|
|
129
|
+
- `area` → 100 m² (format: area + unit: m2)
|
|
130
|
+
- `distance` → 1,5 km (format: distance + unit: km)
|
|
131
|
+
- `percent` → 15% (format: percent)
|
|
132
|
+
- `date` → DD/MM/AAAA (format: date)
|
|
133
|
+
|
|
134
|
+
### Explícitas (para casos específicos)
|
|
135
|
+
- `cpf` → 000.000.000-00
|
|
136
|
+
- `cnpj` → 00.000.000/0000-00
|
|
137
|
+
- `cep` → 00000-000
|
|
138
|
+
- `phone` → (00) 00000-0000
|
|
139
|
+
- `email` → Validação de email
|
|
140
|
+
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
## Condições de Visibilidade
|
|
144
|
+
|
|
145
|
+
### Operadores Disponíveis
|
|
146
|
+
|
|
147
|
+
| Operador | Descrição | Exemplo |
|
|
148
|
+
|----------|-----------|---------|
|
|
149
|
+
| `:` (padrão) | Contém | `"operacao:venda"` |
|
|
150
|
+
| `.equals` | Igual a | `"tipo.equals:apartamento"` |
|
|
151
|
+
| `.not` | Diferente de | `"status.not:vendido"` |
|
|
152
|
+
| `.in` | Está na lista | `"tipo.in:casa,apartamento"` |
|
|
153
|
+
| `.gt` | Maior que | `"valor.gt:100000"` |
|
|
154
|
+
| `.gte` | Maior ou igual | `"valor.gte:100000"` |
|
|
155
|
+
| `.lt` | Menor que | `"quartos.lt:5"` |
|
|
156
|
+
| `.lte` | Menor ou igual | `"area.lte:200"` |
|
|
157
|
+
| `.exists` | Campo preenchido | `"condominio.exists:true"` |
|
|
158
|
+
|
|
159
|
+
### Exemplos de Uso
|
|
160
|
+
```typescript
|
|
161
|
+
"rules": {
|
|
162
|
+
"conditions": [
|
|
163
|
+
"operacao:venda", // operacao contém "venda"
|
|
164
|
+
"tipo.equals:apartamento", // tipo é exatamente "apartamento"
|
|
165
|
+
"valor.gte:100000", // valor >= 100000
|
|
166
|
+
"quartos.in:2,3,4" // quartos é 2, 3 ou 4
|
|
167
|
+
]
|
|
168
|
+
}
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
## Exemplos Práticos
|
|
174
|
+
|
|
175
|
+
### Campo Simples
|
|
176
|
+
```json
|
|
177
|
+
{
|
|
178
|
+
"key": "title",
|
|
179
|
+
"type": "String",
|
|
180
|
+
"categories": ["identificacao"],
|
|
181
|
+
"validation": {
|
|
182
|
+
"required": true,
|
|
183
|
+
"minLength": 3,
|
|
184
|
+
"maxLength": 200
|
|
185
|
+
},
|
|
186
|
+
"ui": {
|
|
187
|
+
"label": "Título",
|
|
188
|
+
"description": "Título do imóvel",
|
|
189
|
+
"placeholder": "Ex: Casa no Centro",
|
|
190
|
+
"searchable": true
|
|
191
|
+
},
|
|
192
|
+
"audit": {
|
|
193
|
+
"origin": "horizon-base/imovel"
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### Campo com Enum
|
|
199
|
+
```json
|
|
200
|
+
{
|
|
201
|
+
"key": "tipo",
|
|
202
|
+
"type": "String",
|
|
203
|
+
"enum": {
|
|
204
|
+
"casa": "Casa",
|
|
205
|
+
"apartamento": "Apartamento",
|
|
206
|
+
"terreno": "Terreno"
|
|
207
|
+
},
|
|
208
|
+
"categories": ["estrutura"],
|
|
209
|
+
"validation": {
|
|
210
|
+
"required": true
|
|
211
|
+
},
|
|
212
|
+
"ui": {
|
|
213
|
+
"label": "Tipo",
|
|
214
|
+
"filterable": true,
|
|
215
|
+
"sortable": true
|
|
216
|
+
},
|
|
217
|
+
"audit": {
|
|
218
|
+
"origin": "horizon-base/imovel"
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
### Campo Monetário
|
|
224
|
+
```json
|
|
225
|
+
{
|
|
226
|
+
"key": "valor_venda",
|
|
227
|
+
"type": "Number",
|
|
228
|
+
"format": "currency",
|
|
229
|
+
"unit": "BRL",
|
|
230
|
+
"categories": ["valores"],
|
|
231
|
+
"validation": {
|
|
232
|
+
"min": 0,
|
|
233
|
+
"max": 999999999.99,
|
|
234
|
+
"precision": 2
|
|
235
|
+
},
|
|
236
|
+
"ui": {
|
|
237
|
+
"label": "Valor de Venda",
|
|
238
|
+
"displayTemplate": "{{value}}",
|
|
239
|
+
"filterable": true,
|
|
240
|
+
"sortable": true
|
|
241
|
+
},
|
|
242
|
+
"audit": {
|
|
243
|
+
"origin": "horizon-base/imovel"
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
### Campo com Condição
|
|
249
|
+
```json
|
|
250
|
+
{
|
|
251
|
+
"key": "valor_locacao",
|
|
252
|
+
"type": "Number",
|
|
253
|
+
"format": "currency",
|
|
254
|
+
"unit": "BRL",
|
|
255
|
+
"categories": ["valores"],
|
|
256
|
+
"rules": {
|
|
257
|
+
"conditions": ["operacao:locacao"]
|
|
258
|
+
},
|
|
259
|
+
"validation": {
|
|
260
|
+
"min": 0,
|
|
261
|
+
"precision": 2
|
|
262
|
+
},
|
|
263
|
+
"ui": {
|
|
264
|
+
"label": "Valor de Locação",
|
|
265
|
+
"filterable": true,
|
|
266
|
+
"sortable": true
|
|
267
|
+
},
|
|
268
|
+
"audit": {
|
|
269
|
+
"origin": "horizon-base/imovel"
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
---
|
|
275
|
+
|
|
276
|
+
## Geração Automática
|
|
277
|
+
|
|
278
|
+
### Zod Schema
|
|
279
|
+
A partir do SSOT, é gerado automaticamente:
|
|
280
|
+
- Schema Zod para validação
|
|
281
|
+
- Tipos TypeScript inferidos
|
|
282
|
+
- Funções de validação (parse, safeParse, partial)
|
|
283
|
+
|
|
284
|
+
### Exemplo de Geração
|
|
285
|
+
```typescript
|
|
286
|
+
// Gerado automaticamente a partir do SSOT
|
|
287
|
+
export const ImovelZod = z.object({
|
|
288
|
+
id: z.number().optional(),
|
|
289
|
+
reference: z.string().min(1).max(50),
|
|
290
|
+
title: z.string().min(3).max(200),
|
|
291
|
+
tipo: z.enum(["casa", "apartamento", "terreno"]),
|
|
292
|
+
valor_venda: z.number().min(0).multipleOf(0.01).optional()
|
|
293
|
+
})
|
|
294
|
+
|
|
295
|
+
export type ImovelType = z.infer<typeof ImovelZod>
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
---
|
|
299
|
+
|
|
300
|
+
## Vantagens do Novo Formato
|
|
301
|
+
|
|
302
|
+
1. **Organização Clara**: Cada contexto tem seu espaço definido
|
|
303
|
+
2. **Flexibilidade**: Campos podem ser vazios e evoluir gradualmente
|
|
304
|
+
3. **Separação de Responsabilidades**: UI, validação, DB em contextos isolados
|
|
305
|
+
4. **Manutenibilidade**: Fácil identificar onde cada metadado pertence
|
|
306
|
+
5. **Evolução**: Adicionar novos contextos sem quebrar existentes
|
|
307
|
+
6. **Reuso**: Mesmo campo pode ter comportamentos diferentes por contexto
|
|
308
|
+
|
|
309
|
+
---
|
|
310
|
+
|
|
311
|
+
## Checklist de Criação
|
|
312
|
+
|
|
313
|
+
### Campo Mínimo Obrigatório
|
|
314
|
+
- [ ] `key` - Identificador único
|
|
315
|
+
- [ ] `type` - Tipo de dado
|
|
316
|
+
- [ ] `ui.label` - Rótulo para exibição
|
|
317
|
+
- [ ] `audit.origin` - Origem do campo
|
|
318
|
+
|
|
319
|
+
### Campo Típico (recomendado)
|
|
320
|
+
- [ ] Validação básica (`required`, limites)
|
|
321
|
+
- [ ] Categoria para organização
|
|
322
|
+
- [ ] Formatação quando aplicável
|
|
323
|
+
- [ ] Configurações de UI (searchable, filterable)
|
|
324
|
+
|
|
325
|
+
### Campo Complexo
|
|
326
|
+
- [ ] Enum quando valores limitados
|
|
327
|
+
- [ ] Condições de visibilidade
|
|
328
|
+
- [ ] Display template customizado
|
|
329
|
+
- [ ] Relacionamentos hierárquicos
|
|
330
|
+
|
|
331
|
+
---
|
|
332
|
+
|
|
333
|
+
Esta especificação serve como **base definitiva** para criação de schemas SSOT v2.0 no sistema, garantindo consistência, flexibilidade e evolução controlada dos metadados.
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# UI Kit Completo — Componentes do Horizon Web
|
|
2
|
+
|
|
3
|
+
> shadcn/ui + componentes custom Horizon + componentes globais
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## shadcn/ui Base (49 componentes)
|
|
8
|
+
|
|
9
|
+
Componentes padrao do shadcn instalados em `src/components/ui/`:
|
|
10
|
+
|
|
11
|
+
accordion, alert, alert-dialog, aspect-ratio, avatar, badge, breadcrumb, button, calendar, card, carousel, checkbox, collapsible, command, context-menu, dialog, drawer, dropdown-menu, form, hover-card, input, input-otp, label, menubar, navigation-menu, pagination, popover, progress, radio-group, resizable, scroll-area, select, separator, sheet, sidebar, skeleton, slider, switch, table, tabs, textarea, toggle, toggle-group, tooltip
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Componentes Custom Horizon (src/components/ui/horizon-ui/)
|
|
16
|
+
|
|
17
|
+
### Filtros e Pickers
|
|
18
|
+
|
|
19
|
+
**HistogramRangeSlider** — Range slider com barras de histograma
|
|
20
|
+
- Props: `buckets[], value, onChangeEnd, onClear, formatLabel, totalCount, isActive`
|
|
21
|
+
- Dual slider com tooltip mostrando contagem por faixa
|
|
22
|
+
- Usado na busca de imoveis para filtro de preco/area
|
|
23
|
+
|
|
24
|
+
**HistogramRangeSelect** — Popover com histograma interativo
|
|
25
|
+
- Props: `buckets[], value, onChangeEnd, onClear, formatLabel, placeholder, rangeHint`
|
|
26
|
+
- Popover + histograma + exibicao de range selecionado
|
|
27
|
+
|
|
28
|
+
**MultiSelect** — Select multiplo customizado
|
|
29
|
+
- Selecao multipla com chips/tags
|
|
30
|
+
|
|
31
|
+
**NumberSelector** — Seletor numerico
|
|
32
|
+
- Incremento/decremento com botoes
|
|
33
|
+
|
|
34
|
+
**Select** — Select customizado Horizon
|
|
35
|
+
- Estilizacao e comportamento alem do shadcn base
|
|
36
|
+
|
|
37
|
+
### Carousel e Animacao
|
|
38
|
+
|
|
39
|
+
**Dots** — Indicador de slides (carousel)
|
|
40
|
+
- Usado com Embla Carousel + useCarouselController
|
|
41
|
+
|
|
42
|
+
**FadeSlider** — Slider com efeito fade
|
|
43
|
+
- Transicao suave entre slides
|
|
44
|
+
|
|
45
|
+
**TabsFloating** — Tabs flutuante
|
|
46
|
+
- Tabs que flutua sobre o conteudo
|
|
47
|
+
|
|
48
|
+
### Tipografia e Display
|
|
49
|
+
|
|
50
|
+
**Overline** — Texto overline estilizado
|
|
51
|
+
- Tipografia decorativa acima de titulos
|
|
52
|
+
|
|
53
|
+
**VideoPlayerModal** — Modal para player de video
|
|
54
|
+
- Modal fullscreen para reproducao de video
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## Componentes Globais (src/components/global/)
|
|
59
|
+
|
|
60
|
+
| Componente | O que faz |
|
|
61
|
+
|---|---|
|
|
62
|
+
| `FormAlertModal` | Modal de alerta para formularios (sucesso/erro) |
|
|
63
|
+
| `GlobalLoading` | Loading global animado |
|
|
64
|
+
| `PageLoading` | Loading especifico de pagina |
|
|
65
|
+
| `ProseTypography` | Tipografia Prose avancada para conteudo longo |
|
|
66
|
+
| `SplashScreen` | Tela de splash ao carregar |
|
|
67
|
+
| `ExitIntentDialog` | Dialog quando usuario tenta sair |
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## Outros Componentes
|
|
72
|
+
|
|
73
|
+
| Componente | Pasta | O que faz |
|
|
74
|
+
|---|---|---|
|
|
75
|
+
| `WhatsAppFloatButton` | `components/whatsapp-float-button/` | Botao flutuante de WhatsApp |
|
|
76
|
+
| `CookieConsent` | `components/` | Banner de consentimento de cookies |
|
|
77
|
+
| `Confetti` | `components/ui/` | Efeito de confete (canvas-confetti) |
|
|
78
|
+
| `Sonner` | `components/ui/` | Toast notifications (wrapper) |
|
|
79
|
+
| `ThemeToggle` | `components/ui/` | Botao toggle tema light/dark |
|
|
80
|
+
| `Logo` | `components/ui/` | Logo do projeto |
|
|
81
|
+
| `NavigationLoadingOverlay` | `components/navigation/` | Overlay de loading na navegacao |
|
|
82
|
+
| `FacebookWidget` | `components/widgets/` | Widget do Facebook |
|
|
83
|
+
| `DebugJsonViewer` | `components/` | Viewer de JSON para debug |
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## Icons
|
|
88
|
+
|
|
89
|
+
**Pasta:** `components/ui/icons/`
|
|
90
|
+
- `icon.tsx` — Componente wrapper de icone
|
|
91
|
+
- `icon-registry.ts` — Registry centralizado de icones
|
|
92
|
+
|
|
93
|
+
Icones sao referenciados por STRING (ex: "house", "phone"), nunca por import direto.
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
## Design System (src/design/)
|
|
98
|
+
|
|
99
|
+
### Cards Decorativos
|
|
100
|
+
- `CardIconTop` — Card com icone no topo
|
|
101
|
+
- `CardStat` — Card de estatistica
|
|
102
|
+
- `CardTestimonialPhoto` — Card de depoimento com foto
|
|
103
|
+
|
|
104
|
+
### Creative Components
|
|
105
|
+
- 5 Frame Decoratives (molduras decorativas)
|
|
106
|
+
- 2 Person Frame Decoratives (molduras para fotos de pessoas)
|
|
107
|
+
- 10 Randomized Compositions (composicoes aleatorias)
|
|
108
|
+
|
|
109
|
+
### Assets
|
|
110
|
+
- Frames, filters, shapes, patterns, grids (11 categorias)
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## Storybook
|
|
115
|
+
|
|
116
|
+
**Total:** 293 arquivos .stories espalhados pelo projeto
|
|
117
|
+
**Comando:** `cd apps/web && pnpm storybook` (porta 6006)
|
|
118
|
+
|
|
119
|
+
Distribuicao:
|
|
120
|
+
- `/components/ui/` — ~49 stories (shadcn)
|
|
121
|
+
- `/components/ui/horizon-ui/` — ~5 stories (custom)
|
|
122
|
+
- `/components/global/` — ~5 stories
|
|
123
|
+
- `/hooks/` — ~7 stories
|
|
124
|
+
- `/design/general/creative/` — ~25+ stories
|
|
125
|
+
- Restante em modulos (property, etc.)
|