EcomSmart Hub · especificação para desenvolvimento

Hub por módulos: landing pages, onboarding com Stripe e assistente MCP

Revisão da arquitetura Django e Angular atual, modelo de domínio, endpoints, fluxo de onboarding, gating, nova estrutura do frontend e fases de entrega. Companion do protótipo navegável.

Versão 1 · 11/09/2026Repos: ecomsmart-hub-django · ecomsmart-hub-angular

Versão 1 · 11/09/2026 · acompanha o protótipo navegável (artefato "EcomSmart Hub Módulos")

1. Modelo comercial

MódulokeyO que entregaBase existente no Hub
Recuperação de CarrinhocarrinhoCaptura híbrida (webhook + sync), régua de até 3 mensagens, receita confirmada por vínculo com pedido. Inclui recuperação de cancelados.models/carrinho.py, pedido_cancelado.py, api_admin/carrinho*.py, tela recuperacao-carrinho/ e recuperacao-cancelados/
Disparo para Base (RFV)disparoSegmentação Ozcan automática, campanhas one-shot (reativação, sazonais, informativos, novidades, giftback, manuais), template por segmento, cadência segura.core/rfm/, campaigns.py, campaigns_generic.py, telas reativacao/ sazonais/ informativos/ novidades/ giftback/ campanhas/, analise-rfv/
RetençãoretencaoBoas-vindas + Aniversariantes do dia, sempre rodando, com anti-duplicação no banco.AutomacaoAniversario, AutomacaoBoasVindas, tasks/campaign_birthday.py, campaign_welcome.py, telas aniversariantes/ boas-vindas/
E-commerceFlowflowCatálogo no WhatsApp, IA vendedora (5 nós B2C já existentes), WhatsApp Flows para variação/entrega/pagamento, pedido criado na loja.core/agentes/, prompts B2C (b2c.intent, b2c.recommend_*, b2c.suggestions_intro, b2c.validate_complements), Produto/Categoria, Integracao. Flows é greenfield.
Campanhas InteligentescampanhasMotor de priorização de ofertas (objetivos O1–O14), recomendação de produto/categoria, cupons controlados, aprovação pelo lojista.core/ai/cesta.py, gerador_recomendacao_oferta.py, services/oferta.py, novidades_bi.agregar_cruzado, tela "Ofertas sugeridas". Inferência fuzzy (Mamdani) é greenfield no Hub (hoje só no prompt panel.marketing_assistant).

Preço e regra comercial, iguais para os 5 módulos:

2. Revisão da arquitetura atual

2.1 Django (ecomsmart-hub-django)

O que já existe e será reaproveitado:

Lacunas (zero ocorrências no repositório): Stripe; lookup de CNPJ; WhatsApp Flows; matching/inferência fuzzy; signup fora da Shopify; enforcement de cota (pode_enviar devolve sempre True); gating de endpoint por módulo (o JSON modulos_habilitados só monta menu).

Pontos de refatoração obrigatórios:

  1. MODULOS_CATALOGO → 5 keys comerciais. Migração de dados traduz principal em carrinho + disparo + retencao para empresas atuais. Consumidores a ajustar: Plano.clean, Assinatura.clean, /api/admin/modulos/, tool modulos_disponiveis, modulos.config.ts no Angular.
  2. TemplateWhatsapp.MODULOS_CHOICES (11 valores) passa a ser sub-uso dentro de um módulo comercial (ex.: aniversario e boas-vindas pertencem a retencao). Criar mapa SUBMODULO → MODULO em models/tenant.py e usá-lo no gating de templates.
  3. Constraint uma_assinatura_vigente_por_empresa deixa de valer: ver §3.

2.2 Angular (ecomsmart-hub-angular)

Existe e será reaproveitado: Angular 21 standalone + signals + Tailwind 4 + biblioteca própria (~60 componentes em shared/components/, incluindo bottom-sheet, responsive-table, rfm-gate, funil, stat-card); infra de módulos (ModuloKey, MODULOS, ModuleService, moduleGuard, switcher, modulos_habilitados); telas de negócio dos 5 módulos dentro de features/comunicacoes/, analise-rfv/, agentes-ia/; layout com sidebar off-canvas em telas menores que 1024px; onboarding embutido da Shopify (features/shopify/shopify-app.component.ts) como molde de máquina de estados.

Lacunas: nenhuma rota pública além de login e nova-senha; sem cadastro; sem landing; zero referências a Stripe; moduleGuard redireciona com toast em vez de mostrar tela bloqueada; os 5 módulos comerciais não existem como ModuloKey; sem assistente conversacional embutido nas telas; sem layout público.

Tokens a manter: brand-600 #4f54e4, brand-950 #1d1e4c (sidebar), superfícies surface-50 #f8f9fc, texto #0f1117 / #5b6478 / #9aa3b2, fonte Inter. O protótipo introduz Sora apenas para títulos de landing/painel (opcional) e uma cor por módulo: carrinho #E8890C, disparo #3B6FE0, retenção #D64C8C, flow #7C3AED, campanhas #0E9F8A.

3. Modelo de domínio (novo e alterado)

Empresa (existente)
  + cnpj validado, razao_social, nome_fantasia, cnae, endereco_json   (preenchidos pelo lookup)
  + onboarding = JSON { passo, modulo_origem, utm, flags: {whatsapp, loja, stripe, smartconversas} }
  + stripe_customer_id

Assinatura (existente)  → passa a ser a CONTA DE COBRANÇA da empresa
  origem: direta | shopify | stripe        (+ 'stripe' em METODO_PAGAMENTO_CHOICES)
  (remover constraint uma_assinatura_vigente_por_empresa OU manter 1 Assinatura e mover
   o ciclo de vida para o item — recomendação: manter 1 Assinatura, ciclo de vida no item)

AssinaturaModulo (NOVO)
  assinatura FK · modulo (5 keys) · status: trial | ativa | inadimplente | cancelada
  trial_ate · fase: intro (3 ciclos R$99) | cheia (R$299) · ciclos_pagos
  stripe_subscription_id (UMA Subscription Stripe por módulo)
  cota_mensagens_mes = 10000 · cancelada_em
  UniqueConstraint (assinatura, modulo) WHERE status != cancelada

ConsumoMensal (existente) + coluna modulo  → UniqueConstraint (empresa, competencia, modulo)

Pagamento (existente) · referencia_externa = id do evento/invoice Stripe

MCPToken (existente) → key_hash (SHA-256), prefixo visível, escopos JSON, revogado_em
LogMcp (NOVO) usuario · origem (painel|claude_desktop|claude_ai|chatgpt) · tool · args · resultado · duracao

OnboardingEvento (NOVO) empresa · etapa · status · detalhe · criado_em   (auditoria do provisionamento)

Regra de gating (fonte única): services/modulos.py::modulos_ativos(empresa) -> set[key] lendo AssinaturaModulo com status trial|ativa. Cache por empresa (@cache_empresa), invalidado pelos webhooks Stripe.

4. Fluxo de cadastro e onboarding

Mobile first: uma decisão por tela, estado persistido em Empresa.onboarding, retomável.

  1. Landing /lp/:slug → CTA grava modulo_origem + UTM → /cadastro?modulo=carrinho.
  2. Cadastro: CNPJ com autocomplete (GET /api/publica/cnpj/?q=, proxy para o serviço listacnpj já em produção no cluster; debounce 300 ms, mínimo 8 dígitos), nome, WhatsApp, e-mail, senha ou Google. POST /api/auth/cadastro/ cria User + Empresa + UserPerfil(admin_empresa) + Assinatura + AssinaturaModulo(trial); loga por sessão.
  3. Passo Empresa: confirma razão social, fantasia, endereço, CNAE, plataforma da loja, faixa de faturamento.
  4. Passo Módulos: o módulo de origem já incluído; oferta dos outros 4 com uma linha de argumento cada; qualquer um pode ser adicionado ao trial.
  5. Passo Pagamento (Stripe): POST /api/billing/setup-intent/ → Stripe Elements salva o cartão sem cobrar → POST /api/billing/assinar/ cria as Subscriptions (§5). Pode ser pulado ("Cadastrar cartão depois"); nesse caso o trial segue e o painel mostra aviso a partir do dia 5.
  6. Passo WhatsApp (roda em paralelo com o provisionamento): Meta Embedded Signup via JS SDK → POST /api/canais-whatsapp/embedded-signup/ troca o code por token, cria CanalWhatsapp(tipo=oficial). Alternativa: informar WABA ID + Phone Number ID.
  7. Passo Loja: escolha da Integracao (Shopify em 1 clique pelo app existente; Magazord/Nuvemshop/VTEX/Woo/CSV) → sync_integration backfill 24 meses. RFV nasce após o primeiro sync completo (guard já existente).
  8. Pronto: três atalhos que acionam o assistente ("Ativar régua padrão", "Só capturar", "Personalizar").

Provisionamento SmartConversas (task Celery provisionar_smartconversas, fila express_queue, idempotente por etapa, registra OnboardingEvento):

1 login super → 2 criar estabelecimento → 3 créditos iniciais → 4 buscar/cadastrar usuário admin
5 autenticar → 6 usuário do cliente → 7 depto "Vendas" → 8 depto "Atendimento" → 9 pipeline padrão
10 campo customizado lead_id → 11 origem do lead → 12 senha padrão
13 (Hub) smartconversas/associar → 14 apis/criar (webhook_token) → 15 canais sync → 16 templates padrão do módulo enviados à Meta

GET /api/onboarding/status/ devolve a lista de etapas com done|running|todo|erro para a tela de progresso; POST /api/onboarding/retry/ reexecuta a etapa que falhou.

5. Stripe

Catálogo (criado uma vez, ids guardados em ParametroSistema):

Endpoints:

MétodoRotaFunção
POST/api/billing/setup-intent/SetupIntent para salvar cartão
POST/api/billing/assinar/ {modulos:[]}cria Subscriptions (trial) e AssinaturaModulo
POST/api/billing/modulos/ {modulos:[]}adiciona módulos a uma conta existente (checkout in-app)
DELETE/api/billing/modulos/:key/cancela ao fim do ciclo (cancel_at_period_end)
GET/api/billing/resumo/módulos, status, uso no ciclo, próxima fatura, faturas
POST/api/billing/portal/link do Customer Portal (trocar cartão, baixar faturas)
POST/webhook/stripe/eventos abaixo, assinatura verificada, idempotente por event.id

Webhooks → efeito:

Shopify continua como origem alternativa de cobrança (origem=shopify): a empresa vinda da Shopify recebe AssinaturaModulo conforme o shopify_plan_handle.

6. Gating por módulo

Backend:

Frontend:

7. Frontend Angular: nova estrutura

src/app/
  layouts/
    public-layout/        header marketing (links dos 5 módulos, Entrar, Testar grátis) + footer
    onboarding-layout/    barra de passos, sem sidebar, mobile first
    app-shell/            layout atual, sidebar = Início · Assistente · Meus módulos (5, com lock) · Minha base · Conta
  features/
    public/               landing/:slug (pré-render estático p/ SEO) · cadastro · login
    onboarding/           empresa · modulos · pagamento · whatsapp · loja · pronto  (+ status polling)
    home/                 início: KPIs consolidados, cards dos 5 módulos, sugestão do assistente
    modulos/
      carrinho/           dashboard · configurar · mensagens · historico   (move recuperacao-carrinho + cancelados)
      disparo/            dashboard · campanhas (reativação/sazonal/informativo/novidades/giftback/manual) · rfv · mensagens · historico
      retencao/           dashboard · boas-vindas · aniversario · mensagens · historico
      flow/               dashboard · catalogo · ia-vendedora (nós B2C) · flows · conversas
      campanhas/          dashboard · objetivos (O1–O14) · cupons · aprovacoes · historico
      _shared/            modulo-shell (cabeçalho, abas, banner de trial, painel do assistente) · modulo-bloqueado · modulo-checkout
    assistente/           hub-assistente (painel dockado à direita / bottom-sheet no mobile; contexto = módulo ativo)
    conta/                assinatura-uso (Stripe) · conectar-mcp · configuracoes (existente)
  core/
    config/modulos.config.ts   ModuloKey = 'carrinho'|'disparo'|'retencao'|'flow'|'campanhas'
                               ModuloDef += cor, slugLanding, argumentoCurto, feats[], preco
    services/billing.service.ts · assistente.service.ts (SSE) · cnpj.service.ts · onboarding.service.ts

Rotas: /lp/:slug · /cadastro · /login · /onboarding/:passo · /app (início) · /app/m/:modulo/(dashboard|configurar|mensagens|historico|assistente) · /app/m/:modulo/ativar (checkout) · /app/assistente · /app/conta/(assinatura|mcp).

Mobile: tab bar inferior (Início · Módulos · Assistente · Conta) usando bottom-sheet existente para o assistente; KPIs em grade 2×2; abas roláveis; formulários de uma coluna. Web: sidebar como hoje, assistente fixo à direita (360 px) em toda tela de módulo.

Regra de UX mantida das telas atuais: toda tela de envio tem Dashboard com KPIs + funil + mensal + histórico, e a aba Configurar segue a sequência de cards numerados (Nome → Canal → Mensagem → Regra → Agendamento → Revisão).

8. Assistente conversacional (MCP)

Arquitetura em duas portas sobre o mesmo servidor de tools:

Angular <hub-assistente [modulo]>  ──SSE──▶  POST /api/assistente/conversar/
                                              │  monta system prompt (empresa, módulo, config atual)
                                              │  tools = mcp_server filtradas por modulos_ativos ∩ escopo do usuário
                                              ▼
                                         Claude API (tool use, streaming)
                                              │  tool de escrita → devolve ToolCard {tool, diff, status:'pendente'}
                                              │  usuário confirma no chat → POST /api/assistente/confirmar/{id}
                                              ▼
                                         executa a tool (mesma função do mcp_server) → LogMcp

Claude Desktop / claude.ai / ChatGPT  ──Streamable HTTP──▶  https://mcp.hub.ecomsmart.com.br/:slug
                                              OAuth 2.1 (Django como authorization server), escopos <modulo>:read|write
                                              lista de tools dinâmica por tenant: módulo bloqueado = tool não registrada

Regras: toda escrita exige confirmação (elicitation); nenhuma tool envia mensagem, só agenda; assinatura.manter_modulo e assinatura.ativar_trial abrem a confirmação de cobrança, nunca cobram sozinhas; MCPToken.key migra para hash.

Tools de escrita a criar (o mcp_server hoje é quase todo leitura):

MóduloTools
comumhub.resumo_semana, hub.modulos_status, templates.listar/arquivar, canais.status, assinatura.ativar_trial, assinatura.manter_modulo
carrinhocarrinho.regua_atual, carrinho.atualizar_regua, carrinho.trocar_template, carrinho.pausar/retomar, carrinho.kpis
disparorfv.resumo, rfv.contar_publico, rfv.listar_clientes, campanhas.criar_{reativacao,sazonal,informativo,novidade}, campanhas.agendar/cancelar, campanhas.desempenho
retencaoretencao.boas_vindas.configurar/ativar, retencao.aniversario.configurar/ativar, retencao.kpis, retencao.previa_dia
flowflow.regras.atualizar, prompts.nova_versao, flow.simular_conversa, catalogo.status, flow.horario_humano
campanhascampanhas.analisar_estoque, campanhas.sugerir_ofertas, campanhas.aprovar_objetivo, campanhas.simular_margem, cupons.regras

9. Módulos: telas e reaproveitamento

Cada módulo usa o mesmo modulo-shell: cabeçalho (ícone, nome, status, banner de trial), abas Dashboard · Configurar · Mensagens · Histórico · Assistente, painel do assistente à direita.

10. Fases de entrega

FaseEscopoDependências
0MODULOS_CATALOGO 5 keys + migração; AssinaturaModulo; ConsumoMensal.modulo; @require_modulo; pode_enviar real; me com modulosnenhuma
1Landing ×5 (pré-render), cadastro com CNPJ, login público, public-layoutlistacnpj exposto via /api/publica/cnpj/
2Onboarding 6 passos + provisionamento SmartConversas + Embedded Signup + integração lojacredenciais Meta (Embedded Signup app review)
3Stripe (catálogo, setup-intent, assinar, webhooks, portal), tela Assinatura & uso, checkout in-app, módulo bloqueadoconta Stripe BRL
4Novo app-shell + modulo-shell + migração das telas existentes para os 3 módulos maduros (carrinho, disparo, retenção)fase 0
5Assistente MCP interno (SSE + confirmação) + tools de escrita dos 3 módulos maduros; MCP externo com OAuth 2.1fase 4
6Campanhas Inteligentes no Hub (motor fuzzy, cupons, aprovações)fase 4
7E-commerceFlow (Flows, catálogo, pedido via integração)canal oficial com Flows habilitado

11. Decisões abertas