UNPKG

@horizon-apps/domain-schema-core

Version:

Core domain schema utilities for Horizon Platform - Schema generators, data enrichers, converters and specifications

674 lines (550 loc) 15.3 kB
# 🎨 Horizon Domain Data Display Enricher > Enriquecedor genérico de dados de domínios para display - Transforma dados brutos de entidades em objetos enriquecidos para UI ## 📋 Índice 1. [Visão Geral](#visão-geral) 2. [Instalação](#instalação) 3. [Uso Básico](#uso-básico) 4. [API Completa](#api-completa) 5. [Formatadores](#formatadores) 6. [Templates](#templates) 7. [Exemplos Práticos](#exemplos-práticos) 8. [Migração](#migração) 9. [Estrutura do Pacote](#estrutura-do-pacote) --- ## 🎯 Visão Geral O **Horizon Domain Data Display Enricher** é uma biblioteca genérica para transformar dados brutos de qualquer domínio (Property, Broker, User, etc.) em objetos enriquecidos com metadados, formatação e informações adicionais para facilitar a exibição no frontend. ### Principais Características - **Genérico**: Funciona com qualquer tipo de domínio - **Formatação Automática**: Suporta currency, date, area, distance, percent, count - **Templates Inteligentes**: Processamento de pluralização e substituições - **Type-Safe**: Escrito em TypeScript com tipos completos - **Extensível**: Permite customização via opções - **Retrocompatível**: Mantém compatibilidade com API antiga ### Transformação Exemplo ```typescript // ENTRADA (dados brutos) { valor: 1500000, dormitorios: 3 } // SAÍDA (dados enriquecidos) { valor: { value: 1500000, label: "Valor", type: "Number", format: "currency", valueLabel: "R$ 1.500.000,00", composedLabel: "R$ 1.500.000,00" }, dormitorios: { value: 3, label: "Dormitórios", type: "Number", format: "count", valueLabel: "3", composedLabel: "3 dormitórios" } } ``` --- ## 📦 Instalação ### Como Pacote NPM (Futuro) ```bash npm install @horizon/domain-data-display-enricher # ou yarn add @horizon/domain-data-display-enricher # ou pnpm add @horizon/domain-data-display-enricher ``` ### Uso Local (Atual) ```typescript import { enrichDomainDataForDisplay } from '@/modules/horizon-platform-toolkit'; ``` --- ## 🚀 Uso Básico ### 1. Exemplo Simples ```typescript import { enrichDomainDataForDisplay } from '@horizon/domain-data-display-enricher'; // Dados brutos do domínio const propertyData = { title: "Apartamento 3 quartos", price: 750000, area: 120, rooms: 3 }; // Metadados do schema const metadata = [ { key: "title", label: "Título", type: "String" }, { key: "price", label: "Preço", type: "Number", format: "currency", unit: "BRL" }, { key: "area", label: "Área", type: "Number", format: "area", unit: "m2" }, { key: "rooms", label: "Quartos", type: "Number", format: "count", composedLabel: "{{value}} quarto{{p:s}}" } ]; // Enriquecer dados const enrichedData = enrichDomainDataForDisplay({ data: propertyData, metadata: metadata }); console.log(enrichedData.price.valueLabel); // "R$ 750.000,00" console.log(enrichedData.area.valueLabel); // "120 m²" console.log(enrichedData.rooms.composedLabel); // "3 quartos" ``` ### 2. Com Opções Avançadas ```typescript const enrichedData = enrichDomainDataForDisplay({ data: myData, metadata: myMetadata, locale: 'en-US', currency: 'USD', getIcon: (iconName) => IconLibrary.get(iconName) }); ``` --- ## 📚 API Completa ### Função Principal #### `enrichDomainDataForDisplay(options: EnrichmentOptions)` Enriquece dados de domínio com metadados para display. **Parâmetros:** ```typescript interface EnrichmentOptions { data: Record<string, any>; // Dados brutos metadata: FieldMetadata[]; // Metadados dos campos locale?: string; // Locale (default: 'pt-BR') currency?: string; // Moeda padrão (default: 'BRL') getIcon?: (name: string) => any; // Função para obter ícones } ``` **Retorno:** ```typescript Record<string, EnrichedField | any> ``` ### Tipos #### `FieldMetadata` ```typescript interface FieldMetadata { key: string; // Chave do campo label?: string; // Label para UI type?: string; // Tipo do dado format?: string; // Formato de exibição unit?: string; // Unidade de medida categories?: string[]; // Categorias composedLabel?: string; // Template de composição icon?: string; // Ícone direto iconName?: string; // Nome do ícone validation?: any; // Regras de validação [key: string]: any; // Campos adicionais } ``` #### `EnrichedField` ```typescript interface EnrichedField extends FieldMetadata { value: any; // Valor original valueLabel?: string; // Valor formatado composedLabel?: string; // Label composto processado icon?: any; // Ícone resolvido } ``` --- ## 🎨 Formatadores ### Formatadores Disponíveis | Format | Descrição | Exemplo | |--------|-----------|---------| | `currency` | Valores monetários | 1500 "R$ 1.500,00" | | `date` | Datas | "2025-08-07" "7 de agosto de 2025" | | `area` | Áreas | 100 "100 m²" | | `distance` | Distâncias | 150 "150m" | | `percent` | Porcentagens | 15 "15%" | | `count` | Contagem | 3 "3" | | `year` | Anos | 2025 "2025" | ### Uso Direto dos Formatadores ```typescript import { formatters } from '@horizon/domain-data-display-enricher'; // Moeda formatters.currency(1500.50, 'BRL', 'pt-BR'); // "R$ 1.500,50" formatters.currency(1500.50, 'USD', 'en-US'); // "$1,500.50" // Data formatters.date(new Date('2025-08-07'), 'pt-BR'); // "7 de agosto de 2025" // Área formatters.area(120, 'm2'); // "120 m²" formatters.area(50, 'hectares'); // "50 hectares" // Distância formatters.distance(150, 'm'); // "150m" formatters.distance(5, 'km'); // "5km" // Porcentagem formatters.percent(15); // "15%" formatters.percent(0.15); // "15.00%" ``` --- ## 📝 Templates ### Sistema de Templates O sistema suporta templates com substituições dinâmicas: | Placeholder | Descrição | Exemplo | |-------------|-----------|---------| | `{{value}}` | Valor bruto | 3 "3" | | `{{valueLabel}}` | Valor formatado | 3 "3" | | `{{p:texto}}` | Texto no plural | 1 "", 2 "texto" | | `{{s:texto}}` | Texto no singular | 1 "texto", 2 "" | ### Exemplos de Templates ```typescript // Pluralização "{{value}} quarto{{p:s}}" // 1 "1 quarto" // 3 "3 quartos" // Singular condicional "{{s:Apenas }}{{value}} vaga{{p:s}}" // 1 "Apenas 1 vaga" // 2 "2 vagas" // Com valor formatado "Total: {{valueLabel}}" // 1500 com format: currency "Total: R$ 1.500,00" ``` ### Uso do Processador de Templates ```typescript import { templateProcessor } from '@horizon/domain-data-display-enricher'; const result = templateProcessor( "{{value}} item{{p:s}} - {{valueLabel}}", 3, "R$ 30,00" ); // "3 items - R$ 30,00" ``` --- ## 💡 Exemplos Práticos ### Exemplo 1: Sistema de Imóveis ```typescript const propertyData = { reference: "APT-001", type: "Apartamento", price: 850000, rent: 3500, area: 150, rooms: 3, bathrooms: 2, garage: 2, condo_fee: 800, distance_beach: 200, furnished: true, features: ["Piscina", "Academia", "Playground"] }; const propertyMetadata = [ { key: "reference", label: "Referência", type: "String" }, { key: "type", label: "Tipo", type: "String" }, { key: "price", label: "Valor de Venda", type: "Number", format: "currency", unit: "BRL", categories: ["valores", "principais"] }, { key: "rent", label: "Valor de Aluguel", type: "Number", format: "currency", unit: "BRL", composedLabel: "{{valueLabel}}/mês" }, { key: "area", label: "Área", type: "Number", format: "area", unit: "m2", iconName: "area" }, { key: "rooms", label: "Dormitórios", type: "Number", format: "count", composedLabel: "{{value}} dormitório{{p:s}}", iconName: "bedroom" }, { key: "bathrooms", label: "Banheiros", type: "Number", format: "count", composedLabel: "{{value}} banheiro{{p:s}}", iconName: "bathroom" }, { key: "garage", label: "Vagas", type: "Number", format: "count", composedLabel: "{{value}} vaga{{p:s}}", iconName: "garage" }, { key: "distance_beach", label: "Distância da Praia", type: "Number", format: "distance", unit: "m", composedLabel: "{{valueLabel}} da praia" }, { key: "furnished", label: "Mobiliado", type: "Boolean" }, { key: "features", label: "Características", type: "Array" } ]; const enriched = enrichDomainDataForDisplay({ data: propertyData, metadata: propertyMetadata, getIcon: (name) => `icon-${name}` // Mock icon function }); // Resultados console.log(enriched.price.valueLabel); // "R$ 850.000,00" console.log(enriched.rent.composedLabel); // "R$ 3.500,00/mês" console.log(enriched.area.valueLabel); // "150 m²" console.log(enriched.rooms.composedLabel); // "3 dormitórios" console.log(enriched.bathrooms.composedLabel); // "2 banheiros" console.log(enriched.garage.composedLabel); // "2 vagas" console.log(enriched.distance_beach.composedLabel); // "200m da praia" console.log(enriched.furnished.valueLabel); // "Sim" ``` ### Exemplo 2: Sistema de Usuários ```typescript const userData = { name: "João Silva", age: 28, salary: 5500, hire_date: "2023-03-15", performance: 0.92, active: true, skills: ["JavaScript", "TypeScript", "React"] }; const userMetadata = [ { key: "name", label: "Nome", type: "String" }, { key: "age", label: "Idade", type: "Number", format: "count" }, { key: "salary", label: "Salário", type: "Number", format: "currency", unit: "BRL" }, { key: "hire_date", label: "Data de Contratação", type: "String", format: "date" }, { key: "performance", label: "Performance", type: "Number", format: "percent" }, { key: "active", label: "Ativo", type: "Boolean" }, { key: "skills", label: "Habilidades", type: "Array" } ]; const enrichedUser = enrichDomainDataForDisplay({ data: userData, metadata: userMetadata }); console.log(enrichedUser.salary.valueLabel); // "R$ 5.500,00" console.log(enrichedUser.hire_date.valueLabel); // "15 de março de 2023" console.log(enrichedUser.performance.valueLabel); // "92.00%" console.log(enrichedUser.active.valueLabel); // "Sim" ``` --- ## 🔄 Migração ### Da API Antiga para a Nova ```typescript // ANTES (API antiga) import { EnrichFieldsWithMetadata } from 'caminho/antigo'; const result = EnrichFieldsWithMetadata({ data: myData, metadata: myMetadata }); // DEPOIS (API nova) import { enrichDomainDataForDisplay } from '@horizon/domain-data-display-enricher'; const result = enrichDomainDataForDisplay({ data: myData, metadata: myMetadata }); ``` ### Compatibilidade A função `EnrichFieldsWithMetadata` ainda está disponível para retrocompatibilidade: ```typescript import { EnrichFieldsWithMetadata } from '@horizon/domain-data-display-enricher'; // Funciona como antes (mas está deprecated) const result = EnrichFieldsWithMetadata({ data, metadata }); ``` --- ## 📂 Estrutura do Pacote ``` horizon-domain-data-display-enricher/ ├── src/ ├── index.ts # Arquivo principal ├── types.ts # Definições de tipos ├── formatters.ts # Funções de formatação ├── templates.ts # Processador de templates └── enricher.ts # Lógica de enriquecimento ├── tests/ ├── index.test.ts # Testes principais ├── formatters.test.ts # Testes dos formatadores └── templates.test.ts # Testes de templates ├── docs/ └── README.md # Esta documentação ├── package.json ├── tsconfig.json └── README.md ``` --- ## 🔧 Configuração para NPM ### package.json Sugerido ```json { "name": "@horizon/domain-data-display-enricher", "version": "1.0.0", "description": "Generic domain data enricher for display - Transform raw entity data into enriched UI objects", "main": "dist/index.js", "module": "dist/index.mjs", "types": "dist/index.d.ts", "files": [ "dist", "README.md" ], "scripts": { "build": "tsup src/index.ts --format cjs,esm --dts", "test": "vitest", "test:coverage": "vitest run --coverage" }, "keywords": [ "horizon", "enricher", "formatter", "display", "ui", "metadata", "transform" ], "author": "Horizon Platform", "license": "MIT", "dependencies": { "date-fns": "^2.30.0" }, "devDependencies": { "@types/node": "^20.0.0", "tsup": "^8.0.0", "typescript": "^5.0.0", "vitest": "^1.0.0" }, "peerDependencies": { "date-fns": ">=2.0.0" }, "repository": { "type": "git", "url": "https://github.com/horizon-platform/domain-data-display-enricher" } } ``` ### tsconfig.json Sugerido ```json { "compilerOptions": { "target": "ES2020", "module": "ESNext", "lib": ["ES2020"], "declaration": true, "outDir": "./dist", "rootDir": "./src", "strict": true, "esModuleInterop": true, "skipLibCheck": true, "forceConsistentCasingInFileNames": true, "resolveJsonModule": true, "moduleResolution": "node" }, "include": ["src/**/*"], "exclude": ["node_modules", "dist", "tests"] } ``` --- ## 🚀 Publicação no NPM ### Passos para Publicar 1. **Criar repositório separado** ```bash git init horizon-domain-data-display-enricher cd horizon-domain-data-display-enricher ``` 2. **Copiar arquivos necessários** - Copiar o código de `/src/_modules/horizon-platform-toolkit/packages/horizon-domain-data-display-enricher/` - Adaptar imports (remover dependências locais) - Adicionar package.json e tsconfig.json 3. **Instalar dependências** ```bash pnpm install ``` 4. **Rodar testes** ```bash pnpm test ``` 5. **Build** ```bash pnpm build ``` 6. **Publicar** ```bash npm login npm publish --access public ``` --- ## 📝 Notas de Implementação ### Dependências Externas Atualmente o código tem algumas dependências que precisam ser resolvidas: 1. **getIcon**: Função para obter ícones - Solução: Tornar opcional via options 2. **date-fns**: Formatação de datas - Solução: está como dependência 3. **horizon-fields-metadata.json**: Metadados centralizados - Solução: Remover dependência, tornar configurável ### Ajustes Necessários Para tornar o pacote totalmente independente: 1. Remover import de `src/core/ui/icons` 2. Remover import de `horizon-fields-metadata.json` 3. Tornar unitListModel configurável 4. Adicionar mais opções de configuração --- ## 📄 Licença MIT --- ## 🤝 Contribuindo Contribuições são bem-vindas! Por favor, abra uma issue ou pull request. --- ## 📧 Suporte Para suporte, abra uma issue no GitHub ou entre em contato com a equipe Horizon. --- *Desenvolvido com ❤️ pela equipe Horizon Platform*