Menuabrir
EstávelAtualizado em 14 de mai. de 2026, 00:06

Este módulo depende de

0

Nenhuma dependência outbound.

Módulos que dependem deste

5
  • instagramConsulta ai_auto_reply_enabled (kill switch global)
  • councilcouncil_enabled, ai_auto_reply_enabled kill switches
  • connectionsAgrega status de providers configurados (Brevo, Daily, Bunny)
  • whatsappConsulta send_limits, signature_mode, kill switches globais
  • billingLê tenant_provider_credentials cifradas via bridge de integrations

Settings

Status: 🟢 Estável (identidade + branding + pixel + compliance + domínios) Code: backend/app/modules/settings UI: frontend/src/app/(admin)/[slug]/admin/settings Última revisão deste doc: 2026-05-13 por Felipe + Claude Dependências fortes: fonte de kill switches centrais (council, agents, ai_auto_reply); custom domains com Traefik


1. Identidade

O que faz (uma frase)

Configurações por tenant: identity (nome, logo, contato, kill switches Conselho/Agentes), branding (cores, fonts), pixels (Meta, GA4, GTM, TikTok, Hotjar, Clarity, LinkedIn), compliance (LGPD, DPO), custom domains (DNS verification + Traefik YAML), legal entities (CNPJs lado vendedor).

Por que existe (negócio)

Sem este módulo:

  • Branding hardcoded.
  • Pixels manuais em cada landing page.
  • Sem self-service de domínio próprio.
  • Compliance docs avulsos.

Com Settings:

  • Mais Consciente customiza visual completo (cores, logo).
  • Pixel Meta + GA4 + Hotjar setado uma vez → todas as páginas aplicam.
  • go.maisconsciente.com.br cadastrado → DNS verify → Traefik provisiona SSL automaticamente.
  • LGPD compliance documentada (DPO, controlador, base legal, retention).

Status atual

Em prod, tudo deployado. Kill switches separados (Conselho council_enabled vs Agentes ai_auto_reply_enabled) — memória [[conselho-e-agentes-kill-switches-separados]].


2. Cases de uso reais

Case 1: Felipe customiza branding

UI → cores primária/secundária/accent → save → PUT /branding upsert → tenant.branding propagado pra UI via GET /public-bundle (SSR Next).

Case 2: Custom domain go.maisconsciente.com.br

  1. UI /settings/domains → "Adicionar" → backend gera verification_token.
  2. Felipe coloca TXT _mandir-verify.go.maisconsciente.com.br=<token> no DNS.
  3. Beat check_pending_domains (10min) → DNS lookup → match → status=active + Redis update + Traefik YAML escrito + SSL provision.
  4. go.maisconsciente.com.br resolve pra Suite.

Case 3: Kill switch Conselho

Felipe vai pra /admin/council/advisors → toggle "Conselho" off → PATCH /api/council/settings {council_enabled: false} → próxima @conselho no grupo é silenciosamente ignorada.


3. Oportunidades de negócio

  • Whitelabel completo: branding + custom domain + pixel = produto sob marca própria do cliente.
  • DNS as a service: wizards step-by-step por registrar (Namecheap, GoDaddy, Registro.br) — UX killer.
  • Compliance pack vendido: LGPD docs prontos pra setores regulados.

4. Arquitetura interna

Arquivos

Tasks

TaskScheduleO que faz
settings.check_pending_domainsBeat 10minDNS lookup _mandir-verify.<domain> → escreve Traefik YAML + Redis

5. Tabelas (6)

settings_identity

ColunaNotas
tenant_idUNIQUE
display_name / logo_url / tagline / contact_email / contact_whatsapp
ai_auto_reply_enabledKill switch Agentes (default true)
council_enabledKill switch Conselho (default true) — independente

settings_branding

Cores (primary, secondary, accent), fonts, custom CSS. UNIQUE per tenant.

settings_pixel

ColunaNotas
providermeta / ga4 / gtm / tiktok / hotjar / clarity / linkedin
pixel_id
server_tokenNUNCA retornado em GET (só configurado, never fetched via API)
is_active

UNIQUE (tenant_id, provider).

settings_compliance

LGPD: privacy_policy_url, terms_url, dpo_name, dpo_email, controller, legal_basis, CNPJ company info. UNIQUE per tenant.

settings_domain

ColunaNotas
domainUNIQUE GLOBAL
verification_tokenTXT record
statuspending / verifying / active / failed
ssl_statuspending / issued / failed
service_typeall / student_area / links / landing_pages / forms / surveys / email_tracking / admin
is_primary

CNPJs do tenant (lado vendedor). UNIQUE (tenant_id, cnpj).

Relacionamentos cross-módulo

DireçãoOutro móduloComo
↘ Lêcouncil_council_enabled()council_enabled
↘ Lêagents_ai_auto_reply_enabled()ai_auto_reply_enabled
↘ EscreveTraefik filesystemCustom domains → YAML dinâmico
↘ EscreveRedisDomain → tenant_id mapping

6. API / Endpoints (22)

Prefixo /api/settings.

Identity / Branding / Compliance (6)

GET/PUT /identity, /branding, /compliance (upsert).

Pixels (3)

GET /pixels, PUT /pixels (upsert por provider), DELETE /pixels/{provider}.

Domains (5)

GET/POST /domains, PUT /domains/{id}, POST /domains/{id}/verify, GET /domains/{id}/dns-instructions (passo-a-passo por registrador), DELETE /domains/{id}.

GET/POST/PATCH/DELETE /legal-entities.

Public Bundle (1)

GET /public-bundle — chamado SSR Next, sem secrets.


7. Configuração

Env vars

VarPropósito
MANDIR_TRAEFIK_DYNAMIC_DIR/data/coolify/proxy/dynamic/mandir
MANDIR_TRAEFIK_CERT_RESOLVERletsencrypt-cf / letsencrypt-google
MANDIR_VASUDEVA_HOST / MANDIR_VASUDEVA_USERSSH remoto
MANDIR_API_INTERNAL_HOST / MANDIR_APP_INTERNAL_HOSTHostname interno

8. Operações + Troubleshooting

Sintoma: Domain stuck em pending

Diagnóstico: Verificar TXT record DNS — dig TXT _mandir-verify.<domain>. Fix: Garantir TXT registrado, aguardar propagação (até 24h), wait beat ou re-trigger POST /domains/{id}/verify.

Sintoma: SSL não emitiu

Causa: Let's Encrypt rate limit ou DNS propagation lag. Fix: Aguardar 5-10min após status=active.


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

#Item
1DNS verification race — alteração entre check cycles
2Traefik priority 8500 hardcoded
3SSL pending lag visível
4Redis domain TTL 2h — beat off-line > 2h quebra resolution
5Pixel server_token redaction

10. Histórico

Em prod desde Suite v2. Kill switch Conselho separado em mig 0111 (memória [[conselho-e-agentes-kill-switches-separados]]).