1. Visao Geral

MegaCall — SaaS multi-tenant de atendimento WhatsApp. Stack: Python 3.12+, Flask 3.0, SQLAlchemy 2.0, Socket.IO, PostgreSQL (prod) / SQLite (dev), Redis, Stripe, Evolution API. Frontend: Bootstrap 5.3, Jinja2, Chart.js. Porta dev: 1997.

2. Arquitetura

Clean Architecture em 4 camadas: Domain (models), Application (services), Infrastructure (repositories, gateways), Interface (blueprints, templates, SocketIO). Multi-tenancy por banco dedicado: Control Plane (master) + bancos por tenant. TenantManager resolve tenant por subdominio/JWT.

3. Estrutura de Pastas

megacall/
  __init__.py          # App factory + context processors
  config.py            # Config dev/test/prod
  extensions.py        # db, migrate, login, jwt, csrf, limiter, socketio
  core/
    errors.py, logging.py, middleware.py, utils.py
    security/          # crypto.py (AES-256-GCM), passwords.py (Argon2), tokens.py
    tenancy/           # base.py, manager.py, provisioner.py
  control_plane/       # models.py, repository.py (banco master)
  tenant/              # models.py (schema por cliente)
  application/         # 18 services (auth, billing, bot, evolution, etc.)
  interface/
    web.py             # Paginas HTML publicas + app
    admin.py           # Painel Super Admin (Flask-Login)
    health.py          # /health
    api/               # 12 blueprints de API REST
  realtime/            # events.py, emitters.py (Socket.IO)
  templates/           # base, landing, login, register, app/*, admin/*
  static/              # css/, js/ (14 arquivos), manifest.json, sw.js
migrations/            # Alembic
tests/                 # 35 testes pytest
deploy/                # nginx.conf, megacall.service, README
gunicorn.conf.py, wsgi.py, requirements.txt, .env.example

4. Models

Control Plane (megacall/control_plane/models.py)
ModelTabelaCampos principais
SuperAdminsuper_adminsid, name, email, password_hash, is_active
Planplanscode(starter/pro/business/enterprise), price_cents, max_users, max_departments, max_connections, max_bots, max_simultaneous_attendances, api_rate_limit, message_rate_limit, storage_mb
Tenanttenantsuuid, company_name, slug, db_name, owner_email, encryption_salt, status(trial/active/blocked/canceled), plan_id, stripe_customer_id, extra_connections, brand_name, logo_url, primary_color
Subscriptionsubscriptionstenant_id, plan_id, stripe_subscription_id, status, current_period_end
Paymentpaymentstenant_id, stripe_invoice_id, amount_cents, status
EvolutionInstanceevolution_instancestenant_id, instance_name, status, webhook_token
AuditLogaudit_logstenant_id, actor_type, action, entity, ip_address, details
ApiKeyapi_keystenant_id, name, key_hash, key_prefix, is_active
WebhookConfigwebhook_configstenant_id, url, secret, events, is_active
WebhookDeliverywebhook_deliverieswebhook_config_id, event_type, payload, status_code, error
Tenant (megacall/tenant/models.py)
ModelTabelaCampos principais
Userusersuuid, name, email, password_hash, role(admin/supervisor/agent), is_online, departments(M:N)
Departmentdepartmentsname, description, is_active, users(M:N), conversations(1:N)
Contactcontactsname, phone, whatsapp_id, is_blocked
Conversationconversationscontact_id, department_id, assigned_user_id, status(open/pending/closed), unread_count, first_response_at, csat_score, tags(M:N), notes(1:N)
Messagemessagesconversation_id, direction(inbound/outbound), media_type, content_encrypted(AES-256-GCM), external_id, is_read
Tagtagsname, color
QuickReplyquick_repliesshortcut, content
InternalNoteinternal_notesconversation_id, user_id, content
BotFlowbot_flowsname, status(draft/active/paused), trigger_keywords, nodes_json, start_node_id
BotSessionbot_sessionsconversation_id, bot_flow_id, current_node_id, context_json, is_active

5. Seguranca

MecanismoArquivoDescricao
AES-256-GCMcore/security/crypto.pyMensagens cifradas com chave derivada por tenant (HKDF-SHA256). Chave mestra em env var.
Argon2idcore/security/passwords.pyHash de senhas resistente a GPU
JWTFlask-JWT-ExtendedAccess token 30min + refresh 7 dias. Claims: tenant_id, role, email
CSRFFlask-WTFHabilitado; API blueprints isentos (usam JWT)
Rate LimitingFlask-LimiterLogin 20/min, Register 10/h, API publica 60/min, dinamico por plano
Cloudflare Turnstilecore/security/turnstile.pyAnti-bot nos forms de login e cadastro. Widget client-side + verificacao server-side. Gratis, sem friccao.
HMAC-SHA256webhook_service.pyAssinatura de webhooks de tenant
Stripe Signaturebilling_service.pyVerificacao de assinatura de webhooks Stripe
Headers (Nginx)deploy/nginx.confHSTS, X-Frame-Options, X-Content-Type-Options, X-XSS-Protection
SSLdeploy/nginx.confTLSv1.2 + TLSv1.3, Let's Encrypt

6. Autenticacao

// Login
POST /api/v1/auth/login
{"email": "...", "password": "...", "tenant_slug": "..."}

// Response
{"access_token": "eyJ...", "refresh_token": "eyJ...", "token_type": "Bearer"}

// Usar token
Authorization: Bearer <access_token>

Roles: admin (total), supervisor (operacional), agent (atendimento). Decorator: @require_role("admin", "supervisor").

API Publica: Bearer mc_... (chave de API, sem JWT).

7. API REST

Prefixo base: /api/v1. Todas as respostas sao JSON. Erros seguem formato {"error": "ErrorType", "message": "..."}.

Auth /auth
MetodoRotaAuthDescricao
POST/register-Cadastra empresa + admin + trial
GET/confirm/<token>-Confirma email
POST/login-Autentica, retorna JWT
POST/refreshRefreshRenova access token
GET/meJWTDados do usuario
Billing /billing
MetodoRotaRoleDescricao
GET/plans-Lista planos ativos
POST/checkoutadminCria sessao Stripe Checkout
POST/portaladminCria sessao Stripe Portal
GET/statusadmin/supervisorStatus da assinatura
GET/connectionsadmin/supervisorLimite de conexoes WhatsApp
POST/connections/addadminAdiciona numero extra (metered)
Evolution /evolution
MetodoRotaRoleDescricao
POST/instanceadminCria/retorna instancia WhatsApp
GET/qrcodeadminQR code para conectar
GET/statusadmin/supervisorEstado de conexao
POST/reconnectadminReconecta instancia
Inbox /inbox
MetodoRotaAuthDescricao
GET/conversationsJWTLista conversas
GET/conversations/<id>/messagesJWTLista mensagens decifradas
POST/conversations/<id>/messagesJWTEnvia mensagem (rate limited)
POST/conversations/<id>/assignJWTAtribui conversa
POST/conversations/<id>/transferJWTTransfere departamento
POST/conversations/<id>/readJWTMarca como lida
POST/conversations/<id>/closeJWTFecha conversa
Manage /manage
MetodoRotaRoleDescricao
GET/POST/PUT/DELETE/departments[/<id>]admin/supervisorCRUD departamentos
GET/POST/PUT/DELETE/users[/<id>]adminCRUD usuarios (limite por plano)
GET/POST/PUT/DELETE/contacts[/<id>]admin/supervisorCRUD contatos (com busca)
GET/auditadminTrilha de auditoria
Bots /bots
MetodoRotaRoleDescricao
GET/POST/flowsadmin/supervisorLista/cria fluxos
GET/PUT/DELETE/flows/<id>admin/supervisorDetalha/atualiza/remove
POST/flows/<id>/activateadmin/supervisorAtiva fluxo (verifica limite)
POST/flows/<id>/pauseadmin/supervisorPausa fluxo
Reports /reports
MetodoRotaAuthDescricao
GET/statsJWTEstatisticas do dashboard
GET/attendanceJWTRelatorio de atendentes
GET/daily-volumeJWTVolume de mensagens/dia
GET/frtJWTFirst Response Time
GET/csatJWTSatisfacao (CSAT)
GET/departmentsJWTRelatorio por departamento
GET/export/conversationsJWTExporta CSV
GET/export/contactsJWTExporta CSV
API Publica /public + Keys /manage/api-keys
MetodoRotaAuthDescricao
GET/public/conversationsBearer mc_...Lista conversas
GET/public/contactsBearer mc_...Lista contatos
GET/POST/manage/api-keys/JWT adminLista/cria chaves
DELETE/manage/api-keys/<id>JWT adminRevoga chave
Webhooks /webhooks + Tenant Webhooks /manage/webhooks
MetodoRotaAuthDescricao
POST/webhooks/stripeStripe SignatureEventos Stripe
POST/webhooks/evolution/<token>Token URLEventos Evolution API
GET/POST/manage/webhooks/JWT adminLista/cria webhooks de tenant
DELETE/manage/webhooks/<id>JWT adminRemove webhook
POST/manage/webhooks/<id>/toggleJWT adminAtiva/desativa
White Label /manage/white-label
MetodoRotaRoleDescricao
GET/JWTConfig atual (brand_name, logo_url, primary_color)
PUT/adminAtualiza white label
Web (HTML) /
RotaDescricao
/Landing page
/login, /register, /confirm/<token>Auth pages
/developersEsta pagina
/appDashboard
/app/inboxAtendimento
/app/whatsappConectar WhatsApp
/app/billingAssinatura
/app/departments, /users, /contactsCRUD
/app/botsBots/URA com editor visual
/app/reportsRelatorios
/app/settingsWhite label + webhooks
Admin (HTML) /admin
RotaDescricao
/admin/login, /admin/logoutAuth Super Admin
/admin/Dashboard (MRR, churn, graficos)
/admin/tenantsLista/busca tenants, block/unblock
/admin/auditTrilha de auditoria global
/admin/plansPlanos

8. Socket.IO (Realtime)

Arquivo: megacall/realtime/events.py

Conexao
const socket = io({ auth: { token: "<jwt>" } });
Eventos Cliente -> Servidor
EventoPayloadDescricao
conversation:join{conversation_id}Entra na sala da conversa
conversation:leave{conversation_id}Sai da sala
message:send{conversation_id, text}Envia mensagem
typing{conversation_id, is_typing}Indicador digitando
message:read{conversation_id}Marca como lida
Eventos Servidor -> Cliente
EventoPayloadDescricao
connected{tenant_id}Confirmacao de conexao
message:new{conversation_id, message}Nova mensagem (inbound/outbound)
conversation:update{...conversation}Atualizacao de conversa
typing{conversation_id, user_id, is_typing}Indicador de digitacao

Isolamento: cada tenant em sua room (tenant:{id}). Conversas em sub-rooms (conv:{tenant_id}:{conv_id}).

9. Camada de Services

ServiceArquivoResponsabilidade
AuthServiceauth_service.pyRegistro de empresa, confirmacao email, login JWT
BillingServicebilling_service.pyStripe: checkout, portal, webhooks, add-ons metered
BotServicebot_service.pyCRUD de fluxos, execucao de nos (start/message/menu/wait/transfer/end)
EvolutionServiceevolution_service.pyInstancia WhatsApp, QR code, webhook inbound, dispatch webhook eventos
MessagingServicemessaging_service.pyStore/read mensagens cifradas, listagens
OutboundServiceoutbound_service.pyEnvio outbound + Evolution + broadcast SocketIO + webhook dispatch
AttendanceServiceattendance_service.pyAssign/transfer/mark_read/close conversas
ReportServicereport_service.pyDashboard stats, FRT, CSAT, export CSV, relatorio departamentos
WebhookServicewebhook_service.pyCRUD webhooks, dispatch HMAC-SHA256, registro de entregas
ApiKeyServiceapi_key_service.pyGerar/listar/revogar chaves mc_..., resolver tenant
AuditServiceaudit_service.pyLog e listagem de auditoria
EmailServiceemail_service.pySMTP com templates HTML
PlanServiceplan_service.pySeed de planos, DEFAULT_PLANS
PlanLimitServiceplan_limit_service.pyEnforcement de limites em runtime (users, bots, connections, depts)
PlatformMetricsServiceplatform_metrics_service.pyMRR, churn, crescimento, distribuicao por plano
RateLimitServicerate_limit_service.pyRate limiting dinamico por plano (api + message)

10. Templates (Jinja2)

TemplateDescricao
base.htmlBase: head, PWA meta, CSS vars (white label), footer, SW registration
landing.htmlHero, features, planos (JS carrega via API)
login.html, register.html, confirm.htmlAuth pages
developers.htmlEsta pagina
app/layout.htmlShell: sidebar (10 items) + topbar, footer oculto
app/dashboard.htmlStats via API + conversas recentes
app/inbox.htmlChat realtime (Socket.IO), typing, acoes
app/whatsapp.htmlQR code, status, polling
app/billing.htmlPlanos, checkout, portal
app/departments.htmlCRUD com modais
app/users.htmlCRUD com modais, associacao departamentos
app/contacts.htmlCRUD com busca
app/bots.htmlLista fluxos + modal com editor visual drag-and-drop
app/reports.htmlGraficos Chart.js, exportacao CSV
app/settings.htmlWhite label (color picker, logo, brand) + webhooks
admin/base.htmlShell admin + footer dev credit
admin/login.htmlLogin Super Admin
admin/dashboard.htmlMRR, churn, graficos, tenants recentes
admin/tenants.htmlLista/busca, block/unblock
admin/audit.htmlTrilha de auditoria
admin/plans.htmlPlanos
emails/*11 templates HTML de email

Context processor injeta: brand_name, logo_url, primary_color, current_year.

11. Arquivos Estaticos (JS/CSS)

JavaScript
ArquivoFuncao
api.jsAPI client: JWT em localStorage, refresh automatico, logout
app.jsShell: sidebar, logout, tenant status badge
landing.jsCarrega planos via API
login.js, register.jsAuth forms
inbox.jsChat realtime com Socket.IO client
dashboard.jsStats via API
whatsapp.jsQR code polling, conectar/desconectar
billing.jsCheckout/portal
departments.js, users.js, contacts.jsCRUD com modais
bots.jsCRUD fluxos + integracao FlowEditor
flow-editor.jsEditor visual drag-and-drop (canvas, nos, conexoes SVG, painel edicao)
reports.jsChart.js + exportacao CSV
settings.jsWhite label + webhooks management
CSS

app.css: hero gradient, auth, app shell, sidebar, inbox bubbles, QR box, flow editor, site footer (dark theme).

PWA

manifest.json (standalone, icons, theme-color) + sw.js (cache-first assets, network-first pages).

12. Configuracao

Arquivo: megacall/config.py — 3 ambientes: DevelopmentConfig, TestingConfig, ProductionConfig.

VariavelDefault DevDescricao
FLASK_ENVdevelopmentAmbiente
SECRET_KEYdev-secretChave Flask/CSRF/tokens
JWT_SECRET_KEY=SECRET_KEYChave JWT
MASTER_ENCRYPTION_KEYdev-keyChave mestra AES (HKDF por tenant)
MASTER_DATABASE_URLSQLite instance/Banco control plane
TENANT_DATABASE_TEMPLATESQLite instance/{db_name}Template banco tenant
REDIS_URLredis://localhost:6379/0Redis
SOCKETIO_ASYNC_MODEthreadingeventlet em prod
STRIPE_SECRET_KEYvazioStripe
EVOLUTION_API_URLvazioEvolution API
TURNSTILE_SITE_KEYvazioCloudflare Turnstile site key (widget client-side)
TURNSTILE_SECRET_KEYvazioCloudflare Turnstile secret key (verificacao server-side)
SMTP_HOSTvazioServidor email
RATELIMIT_STORAGE_URImemory://Redis em prod

Ver .env.example para referencia completa.

13. Deploy

# 1. Pre-req: Ubuntu + Python 3.11+ + PostgreSQL + Redis + Nginx
# 2. Criar banco: CREATE DATABASE megacall_master OWNER megacall;
# 3. git clone + venv + pip install -r requirements.txt
# 4. cp .env.example .env  (ajustar chaves, banco, Stripe, Evolution, SMTP)
# 5. flask --app wsgi init-master && seed-plans && create-superadmin
# 6. flask --app wsgi db upgrade  (Alembic)
# 7. sudo cp deploy/nginx.conf /etc/nginx/sites-available/megacall
# 8. sudo cp deploy/megacall.service /etc/systemd/system/
# 9. sudo systemctl enable megacall && start megacall
# 10. SSL: sudo certbot --nginx -d app.seudominio.com

Gunicorn: gunicorn -c gunicorn.conf.py wsgi:app (4 workers eventlet, bind 127.0.0.1:8000)

Nginx: proxy reverso + WebSocket + static files + SSL + headers de seguranca

14. Comandos CLI

flask --app wsgi init-master           # Cria tabelas do control plane
flask --app wsgi seed-plans            # Cria 4 planos padrao
flask --app wsgi create-superadmin     # Cria Super Admin
flask --app wsgi sync-stripe-plans     # Sincroniza planos com Stripe
flask --app wsgi backup-tenant <db>    # Backup SQLite de um tenant
flask --app wsgi backup-master         # Backup SQLite do banco master
flask --app wsgi db upgrade            # Aplica migracoes Alembic
python scripts/migrate_tenants.py     # Aplica schema em tenants existentes

15. Testes

python -m pytest tests/ -v   # 35 testes
ArquivoTestesCobertura
test_auth.py6register, duplicate, login, wrong password, /me, no token
test_billing.py4plans, status, connections, add connection
test_bots.py5list, create, update, pause, delete
test_manage.py6departments, users, contacts CRUD
test_public_api.py5api keys, public endpoints, no key
test_reports.py7stats, attendance, daily-volume, FRT, CSAT, departments, CSV

16. Planos e Limites

PlanoPrecoUsuariosDeptsConexoesBotsAtend.API/minMsg/min
StarterR$ 24,9032111060100
ProR$ 79,901053550120300
BusinessR$ 139,0030151020200300600
EnterpriseR$ 249,9020010025100500010002000

Add-on numero extra: R$ 19,90 (Starter) / R$ 14,90 (Pro) / R$ 9,90 (Business/Enterprise) por numero/mes.

17. PWA

  • manifest.json: standalone, icons 192/512, theme-color, start_url
  • sw.js: cache-first para assets, network-first para paginas, fallback cache
  • Meta tags: theme-color, apple-mobile-web-app-capable, apple-touch-icon
  • Registro: no base.html, registra SW no load