Editor de Layouts Dinâmicos (Web App)
Pilar: 02 — Funcionalidades Core / Web App
Status: 🟢 Implementado
Última Revisão Técnica: 2026-08-03
Módulos Conectados:gatein-web(src/screens/AppointmentLayouts,src/screens/TicketLayouts,src/screens/TripLayouts),gatein-server(app/api/web/appointments_layout.py,app/api/web/tickets_layout.py,app/api/web/trips_layout.py),gatein-app(Motor de Renderização Dinâmica de Cards e Tickets)
1. Visão Geral e Conectividade com o App Mobile
O módulo de Editor de Layouts Dinâmicos no Web App permite que Administradores e Operadores de Terminais customizem a aparência e a estrutura de dados exibidos nos componentes visuais do aplicativo mobile.
Existem 3 tipos de editores especializados no Web App:
- Appointment Card Layout Editor: Define a disposição de informações nos cards de agendamento da tela principal (Home/Activities) do motorista.
- Ticket Layout Editor: Define a estrutura do Ticket Digital de Liberação (código QR, doca, gate, peso, avisos).
- Trip Card Layout Editor: Customiza o card de acompanhamento de viagens do motorista.
O aplicativo mobile lê o JSON de estrutura retornado pela API e renderiza os campos em tempo real, sem necessidade de atualizar o aplicativo nas lojas (App Store / Google Play).
1.1 Diagrama de Sequência de Edição e Renderização no Mobile
sequenceDiagram
autonumber
actor A as Admin do Terminal (Web App)
participant W as Web App (Layout Editor)
participant S as Gatein Server (FastAPI)
participant DB as PostgreSQL
actor M as Motorista (App Mobile)
A->>W: Edita Layout no Visual Editor / Aba JSON (define layout_ref: "v2_custom_card")
W->>W: Sincronização bidirecional entre aba Visual e aba JSON
W->>S: POST /web/appointments-layout (layout_ref, layout_title, structure)
S->>DB: Salva na tabela appointments_layouts (por terminal_id)
S-->>W: HTTP 200 (Layout publicado com sucesso)
M->>S: GET /mobile/activities
S->>DB: Fetch Appointments + Dictionary de Layouts ativos
S-->>M: Retorna Agendamentos + Dicionário de Layouts em JSON
M->>M: Dynamic Layout Engine desenha o card conforme os campos ordenados
2. Estrutura do JSON de Layout e Tipos de Campo
2.1 Modelo do JSON de Estrutura (structure)
O JSON armazenado no banco contém a definição única de referência, título legível e o array ordenado de elementos:
{
"layout_ref": "v2_custom_card",
"layout_title": "Card de Agendamento de Grãos - Safra 2026",
"fields": [
{
"key": "ref",
"label": "Ordem de Carga",
"type": "text",
"visible": true,
"order": 1
},
{
"key": "window_start",
"label": "Janela Agendada",
"type": "datetime",
"visible": true,
"order": 2
},
{
"key": "custom_data.peso_estimado",
"label": "Peso Autorizado",
"type": "text",
"visible": true,
"order": 3
},
{
"key": "custom_data.codigo_qr",
"label": "Código QR de Gate",
"type": "qr_code",
"visible": true,
"order": 4
}
]
}
2.2 Tipos de Elementos Suportados na Renderização Mobile
Tipo (type) | Descrição | Renderização no React Native App |
|---|---|---|
text | Texto alfa-numérico simples | Componente <Text> estilizado |
datetime | Data e hora formatadas | Formatação UTC local (ex: 04/08/2026 às 14:30) |
date | Apenas data formatada | Formatação (ex: 04/08/2026) |
number | Valores numéricos | Formatação decimal/unidade (ex: 45.000 kg) |
badge | Etiqueta destacada com cor de status | Tag colorida de status (ex: AGUARDANDO DOCA) |
qr_code | Gerador óptico de código QR | Matriz gráfica QR Code para leitura por scanners em gates |
3. Sincronização Bidirecional e Interface Visual do Web App
O Web App oferece uma experiência de edição avançada com duas visões sincronizadas em tempo real:
- Editor Visual (Drag-and-Drop): Permite adicionar campos, alterar rótulos (labels), alternar a visibilidade (toggle visible) e reordenar itens arrastando cartões.
- Editor de Código (Aba JSON): Permite visualizar e editar diretamente a sintaxe crua do payload JSON.
Regra de Sincronização Bidirecional:
- Qualquer alteração no Editor Visual atualiza instantaneamente o texto da Aba JSON.
- Qualquer digitação válida na Aba JSON re-analisa o Schema e atualiza a pré-visualização do Editor Visual.
- Os campos
layout_refelayout_titlesão sincronizados com o cabeçalho (LayoutEditorHeader.jsx).
4. Regras de Negócio Explícitas (RN-LAY-XXX)
RN-LAY-001: Unicidade do layout_ref por Terminal e Tipo
Dentro de uma mesma empresa Terminal, a chave layout_ref deve ser única para cada tipo de layout (appointment, ticket, trip). Tentar salvar uma referência duplicada para o mesmo terminal retornará HTTP 400 (LAYOUT_REF_ALREADY_EXISTS).
RN-LAY-002: Imutabilidade de Layouts em Tickets Já Emitidos
Quando um Ticket Digital é gerado no banco de dados, o campo layout_ref e a cópia dos dados em content são gravados em snapshot. Atualizações subsequentes na tabela tickets_layouts não alteram a exibição visual de tickets gerados no passado.
RN-LAY-003: Resolução Fallback de Layout Ausente
Se o aplicativo mobile receber um agendamento com um layout_ref que foi removido ou que não existe no dicionário do terminal, o motor de renderização mobile utiliza obrigatoriamente o layout default da plataforma (StandardFallbackLayout).
RN-LAY-004: Limpeza de Dados Exemplo (example_data)
O payload persistido no PostgreSQL armazena estritamente a estrutura e metadados operacionais do layout (layout_ref, layout_title, fields). Dados mockados de exemplo (example_data) são utilizados apenas temporariamente na UI do Web App para pré-visualização e são expurgados antes da gravação no banco.
5. Detalhamento de Endpoints
5.1 GET /web/appointments-layout / POST /web/appointments-layout
Consulta e publica layouts de cards de agendamento para o terminal.
5.2 GET /web/tickets-layout / POST /web/tickets-layout
Consulta e publica layouts de tickets digitais de liberação.
5.3 GET /web/trips-layout / POST /web/trips-layout
Consulta e publica layouts de cards de acompanhamento de viagem.
6. Regras de Segurança e Tabela de Erros
| Código HTTP | Código Interno | Causa Raiz | Ação no Web App |
|---|---|---|---|
400 Bad Request | LAYOUT_REF_ALREADY_EXISTS | Referência de layout já cadastrada no terminal | Alterar o identificador layout_ref no cabeçalho |
400 Bad Request | INVALID_JSON_STRUCTURE | Erro de sintaxe na Aba JSON | Destacar a linha do erro no editor de código |
400 Bad Request | EMPTY_LAYOUT_FIELDS | Tentativa de salvar layout sem nenhum campo visível | Exibir alerta exigindo pelo menos 1 campo |