Public Markdown Document
CMS V2 Implementacao Atual e Guia Tecnico
Atualizado em: 2026 02 26
CMS V2 - Implementacao Atual e Guia Tecnico
Atualizado em: 2026-02-26
Objetivo
Este documento consolida o estado real do CMS V2 no FastApp apos Sprint 1 e Sprint 1.5, com foco em:
- implementacoes entregues
- mapa de arquivos
- contratos de dados
- fluxo de edicao e runtime
- integracao com objetos do app
- limites atuais e proximos passos
Escopo Entregue (Sprint 1 + 1.5)
Status geral:
- Secoes verticais com reorder via drag and drop
- Fallback de reorder por botoes (up/down)
- Renderer CMS generico por registro de componentes
- Grid 12 colunas + rows (modelo compativel com Tailwind/Bootstrap)
- Binding de dados para objetos via
/api/v1/data/:object - Rich text editavel com toolbar + tokens de dados
- Secoes
object_listeobject_cards - Persistencia de draft no
localStoragecom versao v2 - Migracao automatica de chave legacy de
localStorage - Validacao/sanitizacao server-side no
PATCH /api/app/:id - Integracao do CMS no Schema Manager (
schema-v3) e no runtime de paginas custom
Ainda nao entregue (ja mapeado no contrato):
- renderer para
object_table - renderer para
kpi_strip - drag and drop espacial de grid (hoje e reorder vertical)
- fluxo publish com versao/historico de pagina
- permissao/auditoria por usuario no nivel de secao
Mapa de Arquivos (Implementacao CMS)
Contratos e utilitarios
app/types/schema.ts- Define
PageSchemaV2,CmsSection,CmsSectionLayout,CmsSectionBinding. CmsSectionTypeinclui:rich_text,object_list,object_cards,object_table,kpi_strip.- Layout com grid:
col_span,row_span,col_start,row_start,min_height.
- Define
app/utils/cms-page.ts- Fabrica e normaliza secoes (
createCmsSection,normalizeCmsSections). - Migra pagina legacy html para secao
rich_text. - Forca defaults de
layout_mode,theme_preset,sections(ensurePageSchemaV2). - Templates rapidos de secao (
createCmsTemplateSection) pararich_text,object_list,object_cards.
- Fabrica e normaliza secoes (
app/composables/useCmsBinding.ts- Resolve binding de dados de secao.
- Converte
filters,sort,limit,projectionpara query string. - Interpola contexto em filtros (
{{route.params.*}},{{route.query.*}}, etc). - Faz fetch generico em
/api/v1/data/:object.
Core CMS components
app/components/core/cms/CoreCmsRenderer.vue- Runtime principal de renderizacao.
- Registry atual:
rich_text->CoreCmsSectionRichTextobject_list->CoreCmsSectionObjectListobject_cards->CoreCmsSectionObjectCards
- Usa grid de 12 colunas com
gridColumn/gridRow. - Fallback visual para tipo de secao nao suportado.
app/components/core/cms/CoreCmsSectionPalette.vue- Catalogo de templates de secao.
- Adiciona secao nova com defaults de binding e props.
app/components/core/cms/CoreCmsSectionStack.vue- Lista vertical de secoes com drag and drop (
vuedraggable). - Exibe metadados de cada secao (tipo, grid, objeto).
- Fallback de reorder por botoes.
- Lista vertical de secoes com drag and drop (
app/components/core/cms/CoreCmsSectionInspector.vue- Editor da secao selecionada.
- Edita:
- base: label, type, enabled
- grid: span/start/min height
- binding: source, object, limit
- props especificas por tipo (
rich_text,object_list,object_cards)
app/components/core/cms/CoreCmsSectionRichText.vue- Bloco editavel (contenteditable) com toolbar.
- Suporte a tokens em modo leitura:
{{record.campo}}{{object.count}}{{object.name}}{{image:https://...}}
app/components/core/cms/CoreCmsSectionObjectList.vue- Lista de registros conectada ao objeto.
- Usa
CoreDynamicList. - Suporte a layout
list/gridecolumns.
app/components/core/cms/CoreCmsSectionObjectCards.vue- Cards visuais conectados ao objeto.
- Props:
image_field,title_field,description_field,cta_label,columns. - Heuristica para inferir campos quando nao configurados.
Integracao nas paginas
app/pages/fastapp/schema-v3.vue- Editor de pagina no Architect com:
CoreCmsSectionPaletteCoreCmsSectionStackCoreCmsSectionInspectorCoreCmsRenderer(preview)
pageFieldsincluilayout_modeetheme_preset.- Garante pagina em formato V2 via
ensurePageSchemaV2.
- Editor de pagina no Architect com:
app/pages/[app]/[module]/index.vue- Runtime de pagina custom com edicao local.
- Persistencia de draft em
localStorage:- v2:
fastapp:cms:v2:draft:{appSlug}:{pageToken} - legacy:
fastapp:cms:{appSlug}:{pageToken}
- v2:
- Migracao automatica do legado para V2.
Validacao de API
server/api/app/[id].patch.ts- Sanitiza
pages,sections,layout,binding. - Valida
layout_modepermitido. - Valida tipo/shape de
filters,sort,projection,limit. - Se payload CMS for invalido, retorna
400antes da tentativa SQL fallback.
- Sanitiza
Contrato de Dados (PageSchemaV2)
type CmsLayoutMode = 'flow_vertical' | 'split' | 'dashboard'
type CmsSectionType =
| 'rich_text'
| 'object_list'
| 'object_cards'
| 'object_table'
| 'kpi_strip'
interface CmsSectionLayout {
col_span?: number // 1..12
row_span?: number // 1..12
col_start?: number // 1..12
row_start?: number // 1..12
min_height?: string
gap?: string | number
width?: string
align?: 'left' | 'center' | 'right' | 'stretch'
}
interface CmsSectionBinding {
source_type?: 'none' | 'object' | 'static'
object_name?: string
filters?: Record<string, any>
sort?: Record<string, 1 | -1>
limit?: number
projection?: string[]
}
interface CmsSection {
id: string
type: CmsSectionType
label: string
order: number
enabled: boolean
layout?: CmsSectionLayout
style?: Record<string, any>
binding?: CmsSectionBinding
props?: Record<string, any>
actions?: Record<string, any>
}
interface PageSchemaV2 {
slug: string
layout_mode?: CmsLayoutMode
theme_preset?: string
sections?: CmsSection[]
}
Exemplo de Pagina CMS V2
{
"slug": "landing",
"layout_mode": "flow_vertical",
"theme_preset": "industrial_zen",
"sections": [
{
"id": "sec_intro",
"type": "rich_text",
"label": "Hero",
"order": 1,
"enabled": true,
"layout": { "col_span": 12, "row_span": 1, "min_height": "280px" },
"binding": { "source_type": "object", "object_name": "lead", "limit": 1, "sort": { "id": -1 } },
"props": {
"html": "<h1>Leads ativos: {{object.count}}</h1><p>Ultimo lead: {{record.name}}</p><p>{{image:https://cdn.site/banner.jpg}}</p>"
}
},
{
"id": "sec_cards",
"type": "object_cards",
"label": "Leads em destaque",
"order": 2,
"enabled": true,
"layout": { "col_span": 12, "row_span": 1 },
"binding": { "source_type": "object", "object_name": "lead", "limit": 6, "sort": { "id": -1 } },
"props": {
"title": "Top leads",
"columns": 3,
"image_field": "image",
"title_field": "name",
"description_field": "description",
"cta_label": "Abrir"
}
}
]
}
Fluxo de Runtime e Persistencia
Runtime em pagina custom
- Normaliza pagina base para V2 (
ensurePageSchemaV2). - Carrega draft do
localStorage(chave v2). - Se v2 nao existir, tenta chave legacy.
- Concatena base + draft para
cmsRuntimePage. - Renderiza com
CoreCmsRenderer. - Ao salvar draft:
- grava payload com
version: 2 - remove chave legacy
- grava payload com
Payload salvo no localStorage
{
"version": 2,
"updated_at": "2026-02-26T12:34:56.000Z",
"page": {
"layout_mode": "flow_vertical",
"theme_preset": "industrial_zen",
"sections": []
}
}
Binding com Objetos (Query Mapping)
Contrato de binding para source_type: object:
object_namedefine endpoint base.filtersvira query plana.sortvira$sort[field]=1|-1.limitvira$limit.projectionvira$select=campo1,campo2.
Exemplo:
binding = {
source_type: 'object',
object_name: 'lead',
filters: { status: 'open', owner_id: '{{route.params.id}}' },
sort: { created_at: -1 },
limit: 10,
projection: ['id', 'name', 'status']
}
Request gerada:
/api/v1/data/lead?status=open&owner_id=123&$sort[created_at]=-1&$limit=10&$select=id,name,status
Grid 12 Colunas + Rows (Sprint 1.5)
Implementacao atual:
CoreCmsRendererusa gridgrid-cols-12.- Cada secao aplica:
gridColumn: span X / span Xoustart / span XgridRow: span Y / span Youstart / span Y
- Inspector controla:
col_span,row_spancol_start,row_startmin_height
- Presets rapidos no inspector:
12/1,6/1,4/1,8/2.
Observacao:
- O posicionamento na grade ainda e configurado por formulario (nao por drag espacial).
- O reorder de secoes continua vertical.
Pontos Fortes Atuais
- Abstracao generica: a pagina e schema-driven, sem branch por app.
- Reuso de objetos: secoes conectam em qualquer objeto via metadados.
- Composicao visual: palette + stack + inspector + preview no mesmo fluxo.
- Migrao suave: legado html e convertido para secao
rich_text. - Seguranca de contrato: API valida shape de pages/secoes antes de persistir.
Gaps para ficar "CMS real" (mais faceis agora)
Prioridade P0/P1 de baixo custo tecnico:
- Sanitizacao de HTML no
rich_textantes de render (v-htmlhoje aceita html bruto). - Blocos mistos em rich text:
- insercao visual de "chips de objeto" (campo dinamico)
- seletor de imagem do app/asset object (alem de URL)
object_tablerenderer reaproveitando tabela dinamica.kpi_striprenderer com agregacoes simples (count,sum,avg).- Toolbar de rich text moderna (evitar dependencia total de
document.execCommand).
Diferencial FastApp (Abstracao + IA)
Direcao recomendada para agentes IA no CMS:
- "Pilot mode":
- agente cria/reordena secoes por prompt
- gera bindings com base em objetos e relacoes existentes
- "Data-aware content":
- agente sugere tokens (
{{record.*}},{{object.count}}) conforme schema - propoe card/list/table mais aderente ao tipo de objeto
- agente sugere tokens (
- "Layout copilot":
- agente ajusta
col_span/row_spanpara responsividade - aplica presets visuais por intencao (landing, dashboard, catalogo)
- agente ajusta
- "Safe patch":
- agente escreve patch em
sections[]validado por contrato server-side
- agente escreve patch em
Guia Rapido para Adicionar Novo Tipo de Secao
Exemplo: object_table
- Garantir o tipo em
app/types/schema.ts(ja existe). - Criar componente
app/components/core/cms/CoreCmsSectionObjectTable.vue. - Registrar no
SECTION_REGISTRYdeCoreCmsRenderer.vue. - Adicionar template em
CoreCmsSectionPalette.vue. - Expor props no
CoreCmsSectionInspector.vue. - Definir template default em
createCmsTemplateSection(app/utils/cms-page.ts). - Validar comportamento com binding via
useCmsBinding.
Checklist de Validacao
- Criar pagina nova no Architect e confirmar defaults
layout_mode/theme_preset/sections. - Adicionar secoes
rich_text,object_list,object_cards. - Reordenar por drag e por botoes.
- Alterar grid no inspector e validar preview.
- Conectar secao a objeto real e validar fetch.
- Salvar draft em pagina custom e recarregar browser.
- Testar migracao da chave legacy
fastapp:cms:*. - Enviar
PATCH /api/app/:idcom payload invalido e validar erro400.
Conclusao
O CMS V2 ja saiu do modo "html editavel simples" e entrou em um modelo composavel, orientado a schema, com binding de objetos, grid de 12 colunas e persistencia local versionada. A base para evolucao com IA ja esta pronta, especialmente no eixo de geracao/edicao automatica de sections[].