Forms
Status: 🔵 MVP (formulários públicos com submissão; sem tools no Conselho ainda) Code: backend/app/modules/forms UI: frontend/src/app/(admin)/[slug]/admin/forms + frontend/src/app/(public)/f Última revisão deste doc: 2026-05-13 por Felipe + Claude
1. Identidade
O que faz (uma frase)
Formulários públicos (lead capture, auto-avaliação, feedback aulas) com submissões persistidas — versão simples (não-LGPD-pesada como Surveys/NR-01) que cria contato CRM automaticamente.
Por que existe (negócio)
Lead capture na landing page → form Mandir → CRM contato resolve UTM → attribution. Sem este módulo, Felipe usaria Tally/Typeform externo sem cruzamento.
Comparação:
- Forms (este módulo): simples, lead capture, sem instrumentos psicométricos.
- Surveys: complexo, modo anônimo, biblioteca instrumentos, devolutivas IA.
- NR-01: anti-PII radical, schema enforce.
Status atual
MVP em prod. Funcional pra lead capture básico.
Lacuna conhecida: sem tools no Conselho — forms está no scope de vários conselheiros (CEO, Strategy, Operations, etc.), mas cross_module.py não tem read_forms_*. Conselheiro tem permissão mas não tem instrumento → responde "vou checar" mas não pode (memória do session: Felipe perguntou "@conselho analise os formulários" e CEO respondeu honestamente que não tem como).
Próxima mudança: implementar tools no Conselho — read_forms_list, read_form_responses, aggregate_form_question.
2. Cases de uso reais
Case 1: Lead form na landing
Landing chama <iframe src="https://app.mandir.com.br/f/lead-mentoria"> → user submete (email, name, phone) → backend cria forms_submission → resolve UTM → cria crm_contact (lifecycle=lead) → email confirmação.
Case 2: Auto-avaliação pré-aula
Aluno responde form pré-yoga → submission persistida → não cria CRM contato (member já existe) → resposta pode alimentar prep do facilitator.
3. Oportunidades de negócio
- Forms premium com lógica condicional (skip-logic).
- Forms + email automático (sequence trigger via webhook).
- Forms + signup form Email Module unificar.
- Tools no Conselho — primeira coisa a fazer pra fechar lacuna.
4. Arquitetura interna
Arquivos
models.py— 2 tabelas.routes.py— 5 endpoints.service.py— submission handler.
Tasks
Sem Celery.
5. Tabelas (2)
forms_form
| Coluna | Notas |
|---|---|
tenant_id | |
slug | UNIQUE per tenant — public URL |
name / description | |
fields (JSONB) | Schema dos campos |
is_active | |
submit_count | Cache |
forms_submission
| Coluna | Notas |
|---|---|
form_id | FK CASCADE |
data (JSONB) | Respostas |
crm_contact_id | Vinculado se contato criado |
submitted_at | |
ip / user_agent |
Relacionamentos cross-módulo
| Direção | Outro módulo | Como |
|---|---|---|
| ↘ Escreve | crm_contact | Cria contato se email não existe |
| ↗ Lê | attribution | UTM resolution on-create |
6. API / Endpoints (5)
Prefixo /api/forms.
Admin
| Método | Rota | O que faz |
|---|---|---|
| GET | /forms | Lista |
| POST | /forms | Criar |
| GET | /forms/{id} | Detalhe |
| PATCH | /forms/{id} | Update |
| DELETE | /forms/{id} | Soft-delete |
Público
| Método | Rota | Auth | O que faz |
|---|---|---|---|
| POST | /forms/{slug}/submit | Público | Cria submission + CRM contact |
7. Limitações e débitos técnicos
| # | Item | Plano |
|---|---|---|
| 1 | Sem tools no Conselho | Prioridade alta — implementar read_forms_* |
| 2 | Sem skip-logic | Roadmap |
| 3 | Sem analytics dedicado | Beat sumarização (TBD) |
| 4 | Sem integração com email sequence | Webhook opcional (TBD) |
8. Histórico
MVP em prod. Lacuna no Conselho é débito conhecido (descoberto em sessão 2026-05-13).