Public Markdown Document
đïž Arquitetura de Componentes â PadrĂŁo DinĂąmico vs Concreto
A estrutura de componentes do Fastapp segue a Escada de Abstração definida em ANTIGRAVITY GUIDELINES.md. A divisĂŁo de pastas reflete a intenção de separação entre o motor universal e as necessidades especĂficas:
đïž Arquitetura de Componentes â PadrĂŁo DinĂąmico vs Concreto
đ PrincĂpio: Abstração Soberana
A estrutura de componentes do Fastapp segue a Escada de Abstração definida em ANTIGRAVITY_GUIDELINES.md. A divisĂŁo de pastas reflete a intenção de separação entre o motor universal e as necessidades especĂficas:
components/
âââ core/ â DINĂMICOS (genĂ©ricos, reutilizĂĄveis em qualquer contexto)
â âââ (Navigation) BuilderHub.vue, AppMenu.vue
â âââ (Data) DynamicCRUD, DynamicForm, DynamicTable, DynamicList...
âââ fastapp/ â CONCRETOS (Ferramentas do Arquiteto)
âââ crm/ â CONCRETOS (especĂficos do CRM)
âââ sosplantao/ â CONCRETOS (especĂficos do SosPlantĂŁo)
âââ central-filtros/ â CONCRETOS (especĂficos do Central Filtros)
âââ lead/ â CONCRETOS (especĂficos do Lead)
â
Componentes DinĂąmicos em core/
CaracterĂsticas:
- â GenĂ©ricos e abstratos
- â NĂŁo dependem de domĂnio especĂfico
- â ReutilizĂĄveis em mĂșltiplos contextos
- â Aceitam dados via props/slots
- â Emitem eventos genĂ©ricos
Exemplos Atuais:
1. DynamicList.vue â
- Propósito: Renderizar listas de dados com opcional Drag & Drop e Seleção
- Props:
schema,data,sortable,selectable,selectableMode('single' | 'multiple'),layout('list' | 'grid') - Slots:
#item(para renderização customizada por linha) - Eventos:
reorder,edit,delete,update,select - Uso: Qualquer coleção que precise de visualização em lista/grid ou seleção
- Contextos:
- Listas de CRUD
- Seletores de registros
- Dashboards
- Editors com slots customizados ("DIY" Pattern)
PadrĂŁo de Uso:
<DynamicList
:schema="leadSchema"
:data="leads"
:sortable="true"
:selectable="true"
selectableMode="multiple"
@select="handleSelection"
@reorder="handleReorder"
/>
Pattern Avançado (Slots):
<DynamicList :data="items">
<template #item="{ item }">
<MyCustomCard :data="item" />
</template>
</DynamicList>
2. DynamicCRUD.vue â [EVOLVED]
- Propósito: Orquestrador soberano de coleçÔes de dados (List + Table + Form + Tabs).
- Orquestração de Interface:
- Wizard Mode: Suporta renderização de formulårios em passos (
group_render_mode: 'wizard') em modo full-page. - Nested CRUD: Gerencia automaticamente abas de relaçÔes HasMany com suporte a:
initialViewMode: Define se a aba abre como Tabela, Kanban, etc.mode="modal": Garante que o CRUD filho use modais para evitar conflitos de sidebar.
- Wizard Mode: Suporta renderização de formulårios em passos (
- Capacidades:
- Auto-limpeza de propriedades (ex: oculta
locationem tabelas viashow_in_list). - Suporte a
crud_mode: 'split' | 'page' | 'modal'.
- Auto-limpeza de propriedades (ex: oculta
3. DynamicForm.vue â
- PropĂłsito: Renderizar formulĂĄrios dinamicamente baseado em schema
- Props:
properties,initialValues,compact,showActions,loading - Eventos:
submit,change,cancel - Uso: Standard Forms, Sidebars, Modais
4. RelationList.vue â
- PropĂłsito: Gerenciar relacionamentos 1:N Embedded (JSONB)
- Pattern:
storage: 'document_embed' - Props:
schema,modelValue,disabled - Uso: Listas de itens simples dentro de um objeto pai (ex: emails, telefones)
5. DynamicTable.vue â
- PropĂłsito: Renderizar tabelas dinamicamente
- Props:
schema,data - Eventos: similares ao DynamicList
6. BiWidget.vue â [NEW]
- Propósito: Componente "Plug-and-Play" para visualização de métricas BI.
- Capacidades:
- Auto-inferĂȘncia de tipo de grĂĄfico (Donut, Line, KPI, Leaderboard).
- Suporte a séries temporais ponderadas (Financial Weighting).
- Seleção dinĂąmica de granularidade (Dia, Semana, MĂȘs, Ano).
- Interatividade "Click-to-Filter" integrada.
- Props:
metric(blueprint gerado pela API),total.
7. DynamicFilter.vue â [EVOLVED]
- PropĂłsito: Painel de filtros reativo que governa a URL do sistema.
- Capacidades:
- Geração dinùmica de campos baseado no Schema.
- Suporte a operadores complexos (between, in, like).
- SaĂda em formato Flattened (field[op]=val).
- Sincronização automåtica com
route.query.
đŻ Componentes Concretos em Subpastas
CaracterĂsticas:
- â EspecĂficos de um domĂnio/feature
- â Podem depender de stores, APIs do domĂnio
- â Implementam lĂłgica customizada
- â Encapsulam regras de negĂłcio
- â Podem usar componentes dinĂąmicos
components/fastapp/PropertyListEditor.vue â
- PropĂłsito: Editor especializado para reordenar propriedades de objetos do Schema
- Props:
properties(array de PropSchema) - Eventos:
update,reorder - DependĂȘncias: draggable, PropSchema type
- Contexto: Exclusivamente no Schema Manager
- Responsabilidades:
- Gerir edição inline de propriedades
- Drag & Drop de propriedades
- Adição/remoção de propriedades
- Validação de metadados
PadrĂŁo de Uso:
<!-- Apenas em schema.vue -->
<PropertyListEditor
:properties="editingObject.properties"
@update="onPropertyUpdate"
@reorder="onPropertyReorder"
/>
components/crm/Kanban.vue â
- PropĂłsito: Kanban board especĂfico do CRM
- DependĂȘncias: leadStore, LeadCard
- Contexto: CRM leads pipeline
components/crm/LeadCard.vue â
- PropĂłsito: Card especĂfico para exibir um lead no Kanban
- Contexto: CRM
đïž PadrĂŁo de DecisĂŁo
Quando criar componente em core/?
â Pode ser usado em 2+ contextos?
â NĂŁo depende de domĂnio especĂfico?
â Funciona com dados genĂ©ricos via props?
â Emite eventos genĂ©ricos?
SE SIM â core/
Quando criar componente em subfolder especĂfica?
â Ă especĂfico de um feature/domĂnio?
â Encapsula lĂłgica de negĂłcio?
â Pode usar stores do domĂnio?
â Ă interna daquele feature?
SE SIM â fastapp/, crm/, lead/, etc.
đ Estrutura Proposta (PĂłs-Refactor)
app/
âââ components/
â âââ core/ â DINĂMICOS
â â âââ BuilderHub.vue â
Sovereign Navigation (top bar contextual)
â â âââ AppMenu.vue â
Sidebar colapsĂĄvel (route-driven)
â â âââ DynamicList.vue â
genérico, reutilizåvel
â â âââ DynamicForm.vue â
genérico, reutilizåvel
â â âââ DynamicTable.vue â
genérico, reutilizåvel
â â âââ DynamicFields.vue â
genérico, Ontology v3
â â âââ PrimitiveEditor.vue â
genérico, reutilizåvel
â â âââ RelationList.vue â
Pattern: Embedded (JSONB)
â â âââ DynamicIntegratedList.vue â
Pattern: Physical (Relation tables)
â â âââ RelationLookup.vue â
Pattern: Physical (Foreign Key)
â â âââ AssetUpload.vue â
Pattern: semantic=asset
â â âââ MapRenderer.vue â
Pattern: spatial_type=point
â â âââ BiWidget.vue â
Engine de Visualização BI (Chart.js)
â â âââ DynamicFilter.vue â
Filtro Universal Soberano (URL-driven)
â â
â âââ fastapp/ â ARCHITECT TOOLS
â â âââ AgentChat.vue â
Chat AI streaming com contexto
â â âââ FastNode.vue â
Node customizado Vue Flow
â â âââ PropertyListEditor.vue â
especĂfico (Schema Manager)
â â âââ SchemaPropertyManager.vue â
especĂfico (v3 Schema Editor)
â â âââ ...
â â
â âââ crm/ â CONCRETOS DO CRM
â â âââ Kanban.vue â
especĂfico (CRM)
â â âââ LeadCard.vue â
especĂfico (CRM)
â â âââ ...
â â
â âââ lead/ â CONCRETOS DO LEAD
â âââ ...
â
âââ pages/
âââ fastapp/
âââ example-dynamic-components.vue â KITCHEN SINK (Playground Oficial)
đ PadrĂŁo de Integração
Fluxo Correto
Schema Manager:
schema.vue (pĂĄgina)
â usa
[PropertyListEditor] (concreto em fastapp/)
â que encapsula
DynamicList (dinĂąmico em core/) â para futura reutilização
CRM:
leads.vue (pĂĄgina)
â usa
[Kanban] (concreto em crm/)
â que contĂ©m
[LeadCard] (concreto em crm/)
â que poderia usar
DynamicList (dinĂąmico em core/) com :sortable="true"
Forma Correta:
<!-- Dentro de components/fastapp/PropertyListEditor.vue -->
<script setup>
import draggable from 'vuedraggable';
// LĂłgica especializada do Schema Manager aqui
</script>
<!-- Dentro de pages/fastapp/schema.vue -->
<template>
<PropertyListEditor :properties="..." @reorder="..." />
</template>
â Anti-Patterns
â Evitar
<!-- â NĂO faça isso em components/core/ -->
<PropertyListEditor /> <!-- muito concreto -->
<SchemaObjectEditor /> <!-- muito concreto -->
<CrmLeadForm /> <!-- muito concreto -->
â Evitar Duplicação
// â NĂO faça:
// components/core/PropertyListEditor.vue (genérico)
// components/fastapp/PropertyListEditor.vue (concreto)
// â Conflita! Use apenas este: components/fastapp/
â Evitar LĂłgica EspecĂfica em Core
<!-- â components/core/SomeComponent.vue -->
<script setup>
import { useLeadStore } from '~/stores/lead'; // â EspecĂfico!
import { useSystemStore } from '~/stores/system'; // â EspecĂfico!
</script>
â Boas PrĂĄticas
1ïžâŁ Componente GenĂ©rico em Core
<!-- components/core/DynamicList.vue -->
<script setup>
const props = defineProps<{
schema: ObjectSchema; // genérico
data: any[]; // genérico
sortable?: boolean; // booleano simples
}>();
const emit = defineEmits(['reorder', 'edit', 'delete']);
// Sem dependĂȘncias especĂficas!
</script>
2ïžâŁ Componente Concreto em Feature
<!-- components/fastapp/PropertyListEditor.vue -->
<script setup>
import type { PropSchema } from '~/types/schema'; // tipo compartilhado OK
const props = defineProps<{
properties: PropSchema[]; // especĂfico da feature
}>();
const emit = defineEmits(['update', 'reorder']);
// Encapsula lĂłgica especializada
</script>
3ïžâŁ Usar Concreto Dentro de PĂĄgina
<!-- pages/fastapp/schema.vue -->
<template>
<PropertyListEditor
:properties="editingObject.properties"
@reorder="onPropertyReorder"
/>
</template>
<script setup>
import PropertyListEditor from '~/components/fastapp/PropertyListEditor.vue';
// Importar concreto em sua pĂĄgina
</script>
đ PrĂłximo Passo
Seguindo esse padrĂŁo, vocĂȘ pode:
- â
Usar DynamicList em mĂșltiplos contextos com
sortableprop - â Criar specializations (como PropertyListEditor) quando precisar
- â Manter core/ limpo e genĂ©rico
- â Reutilizar lĂłgica de reordenação via DynamicList
- â Encapsular domĂnio em pastas especĂficas (fastapp/, crm/, lead/)
đ ReferĂȘncia RĂĄpida
| Lugar | Tipo | Exemplo | ReutilizĂĄvel |
|---|---|---|---|
components/core/ |
DinĂąmico | DynamicList, BuilderHub, AppMenu | â Sim, em vĂĄrios lugares |
components/fastapp/ |
Concreto | PropertyListEditor, AgentChat, FastNode | â Apenas Ferramentas do Arquiteto |
components/crm/ |
Concreto | Kanban | â Apenas CRM |
pages/fastapp/ |
PĂĄgina | schema-v3.vue, diagram.vue, agent.vue | â Apenas essas rotas |
[!NOTE]
OBuilderHub.vueeAppMenu.vuevivem emcore/porque sĂŁo genĂ©ricos: nĂŁo conhecem nenhum domĂnio especĂfico. Eles consomemsystemStorepara navegação, nĂŁo para lĂłgica de negĂłcio. OAgentChat.vueeFastNode.vuevivem emfastapp/porque sĂŁo especĂficos das ferramentas do arquiteto.
Data: 22/02/2026
Status: â
Atualizado com Sovereign Navigation & Architect Tool Chain