CMS_V2_ROADMAP.md

CMS V2 Implementacao Atual e Guia Tecnico

Public Markdown Document

CMS V2 Implementacao Atual e Guia Tecnico

Atualizado em: 2026 02 26

980 palavras21 headingsrepository root

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_list e object_cards
  • Persistencia de draft no localStorage com 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.
    • CmsSectionType inclui: rich_text, object_list, object_cards, object_table, kpi_strip.
    • Layout com grid: col_span, row_span, col_start, row_start, min_height.
  • 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) para rich_text, object_list, object_cards.
  • app/composables/useCmsBinding.ts

    • Resolve binding de dados de secao.
    • Converte filters, sort, limit, projection para 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 -> CoreCmsSectionRichText
      • object_list -> CoreCmsSectionObjectList
      • object_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.
  • 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/grid e columns.
  • 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:
      • CoreCmsSectionPalette
      • CoreCmsSectionStack
      • CoreCmsSectionInspector
      • CoreCmsRenderer (preview)
    • pageFields inclui layout_mode e theme_preset.
    • Garante pagina em formato V2 via ensurePageSchemaV2.
  • 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}
    • Migracao automatica do legado para V2.

Validacao de API

  • server/api/app/[id].patch.ts
    • Sanitiza pages, sections, layout, binding.
    • Valida layout_mode permitido.
    • Valida tipo/shape de filters, sort, projection, limit.
    • Se payload CMS for invalido, retorna 400 antes da tentativa SQL fallback.

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

  1. Normaliza pagina base para V2 (ensurePageSchemaV2).
  2. Carrega draft do localStorage (chave v2).
  3. Se v2 nao existir, tenta chave legacy.
  4. Concatena base + draft para cmsRuntimePage.
  5. Renderiza com CoreCmsRenderer.
  6. Ao salvar draft:
    • grava payload com version: 2
    • remove chave legacy

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_name define endpoint base.
  • filters vira query plana.
  • sort vira $sort[field]=1|-1.
  • limit vira $limit.
  • projection vira $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:

  • CoreCmsRenderer usa grid grid-cols-12.
  • Cada secao aplica:
    • gridColumn: span X / span X ou start / span X
    • gridRow: span Y / span Y ou start / span Y
  • Inspector controla:
    • col_span, row_span
    • col_start, row_start
    • min_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:

  1. Sanitizacao de HTML no rich_text antes de render (v-html hoje aceita html bruto).
  2. Blocos mistos em rich text:
    • insercao visual de "chips de objeto" (campo dinamico)
    • seletor de imagem do app/asset object (alem de URL)
  3. object_table renderer reaproveitando tabela dinamica.
  4. kpi_strip renderer com agregacoes simples (count, sum, avg).
  5. Toolbar de rich text moderna (evitar dependencia total de document.execCommand).

Diferencial FastApp (Abstracao + IA)

Direcao recomendada para agentes IA no CMS:

  1. "Pilot mode":
    • agente cria/reordena secoes por prompt
    • gera bindings com base em objetos e relacoes existentes
  2. "Data-aware content":
    • agente sugere tokens ({{record.*}}, {{object.count}}) conforme schema
    • propoe card/list/table mais aderente ao tipo de objeto
  3. "Layout copilot":
    • agente ajusta col_span/row_span para responsividade
    • aplica presets visuais por intencao (landing, dashboard, catalogo)
  4. "Safe patch":
    • agente escreve patch em sections[] validado por contrato server-side

Guia Rapido para Adicionar Novo Tipo de Secao

Exemplo: object_table

  1. Garantir o tipo em app/types/schema.ts (ja existe).
  2. Criar componente app/components/core/cms/CoreCmsSectionObjectTable.vue.
  3. Registrar no SECTION_REGISTRY de CoreCmsRenderer.vue.
  4. Adicionar template em CoreCmsSectionPalette.vue.
  5. Expor props no CoreCmsSectionInspector.vue.
  6. Definir template default em createCmsTemplateSection (app/utils/cms-page.ts).
  7. 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/:id com payload invalido e validar erro 400.

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[].