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
| Coluna | Notas |
|---|---|
tenant_id | idx |
name / description / category | |
type | landing / email / form |
body_design (JSONB) | GrapeJS project JSON (opaque) |
body_html / body_css | Renderizados |
slug | UNIQUE 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étodo | Rota | O que faz |
|---|---|---|
| GET | /templates | Lista (filter type, include_inactive) |
| POST | /templates | Criar (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}/publish | Validações: type=landing, body_html, slug → set is_published=true |
| POST | /templates/{id}/duplicate | Clone (sem slug — precisa renomear) |
| GET | /public/{slug} | Público — landing publicada (sem auth) |
6. Limitações e débitos técnicos
| # | Item |
|---|---|
| 1 | Slug uniqueness só dentro do tenant |
| 2 | GrapeJS JSON não validado |
| 3 | Sem preview/thumbnail auto |
| 4 | Sem versionamento |
| 5 | Public URL sem auth |
7. Histórico
Em prod desde Suite v2. GrapeJS integration estável.