Menuabrir
Em fluxoAtualizado em 14 de mai. de 2026, 00:06
Módulo sem dependências cross-módulo declaradas.

Design (Templates + Builder)

Status: 🟡 Em fluxo (drag-and-drop builder GrapeJS) Code: backend/app/modules/design UI: frontend/src/app/(admin)/[slug]/admin/design Última revisão deste doc: 2026-05-13 por Felipe + Claude


1. Identidade

O que faz (uma frase)

CRUD de templates de design (landing pages + emails + forms) com builder drag-and-drop GrapeJS — body_design JSONB do projeto + body_html/body_css renderizados, publicação em URL pública por slug, duplicação e thumbnails.

Por que existe

Cliente cria landing/email sem saber HTML. Sem este módulo:

  • Templates externos (Mailchimp/MJML) sem cruzamento com Mandir.
  • Sem published URL nativa (precisa hospedar fora).

Com Design:

  • Builder no painel.
  • Publish landing → app.mandir.com.br/p/{slug}.
  • Duplicar template (workflow A/B).

Status atual

Em fluxo. Builder funcional. Sem versionamento yet.


2. Cases de uso reais

Case 1: Landing "Mentoria Premium"

UI /admin/design/builder/{id} → arrasta blocos → save → POST /publish → landing pública em /p/mentoria-premium.

Case 2: Email duplicado

Felipe duplica template existente → backend cria novo sem slug → renomeia → published.


3. Arquitetura interna


4. Tabelas (1)

design_template

ColunaNotas
tenant_ididx
name / description / category
typelanding / email / form
body_design (JSONB)GrapeJS project JSON (opaque)
body_html / body_cssRenderizados
slugUNIQUE per tenant — public URL suffix
is_published (default false)
tags (JSONB) / thumbnail_url
is_active (soft-delete)

5. API / Endpoints (7 + 1 público)

Prefixo /api/design.

MétodoRotaO que faz
GET/templatesLista (filter type, include_inactive)
POST/templatesCriar (valida slug uniqueness) → 201
GET/templates/{id}Detail completo
PATCH/templates/{id}Update partial
DELETE/templates/{id}Soft (is_active=false + is_published=false)
POST/templates/{id}/publishValidações: type=landing, body_html, slug → set is_published=true
POST/templates/{id}/duplicateClone (sem slug — precisa renomear)
GET/public/{slug}Público — landing publicada (sem auth)

6. Limitações e débitos técnicos

#Item
1Slug uniqueness só dentro do tenant
2GrapeJS JSON não validado
3Sem preview/thumbnail auto
4Sem versionamento
5Public URL sem auth

7. Histórico

Em prod desde Suite v2. GrapeJS integration estável.