Arquitetura

Como os serviços se dividem e conversam.

Arquitetura do Ecossistema Asender (v2 - Decentralizada)

Stack Geral

Visao Geral

┌─────────────────┐    ┌─────────────────┐
│   BACKOFFICE    │    │   DASHBOARD     │
│   (Next.js)     │    │   (Next.js)     │
│   Asender team  │    │   Customers     │
└────────┬────────┘    └────────┬────────┘
         │                      │
         ▼                      ▼
┌────────────────────────────────────────┐
│          asender-api (Go)              │
│  Public API + Dashboard BFF gateway    │
│  Validates + Dispatches                │
└───┬──────────┬──────────┬──────────┬──┘
    │          │          │          │
    ▼          ▼          ▼          ▼
┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐
│  AUTH  │ │  CORE  │ │  NATS  │ │  REDIS │
│  (Go)  │ │  (Go)  │ │  JS    │ │        │
└────────┘ └────────┘ └────────┘ └────────┘
                          │
            ┌─────────────┼─────────────┬─────────────┐
            ▼             ▼             ▼             ▼
       ┌────────┐   ┌────────┐   ┌────────┐   ┌────────┐
       │ EMAIL  │   │  SMS   │   │  PUSH  │   │ WEBHOOK│
       │ WORKER │   │ WORKER │   │ WORKER │   │ WORKER │
       └───┬────┘   └───┬────┘   └───┬────┘   └───┬────┘
           │            │            │            │
           ▼            ▼            ▼            ▼
       ┌────────┐  ┌─────────┐  ┌────────┐  ┌────────┐
       │ RELAY  │  │ Twilio  │  │  FCM   │  │Customer│
       │  PHP   │  │ /  SNS  │  │ /APNs  │  │ HTTPS  │
       └────────┘  └─────────┘  └────────┘  └────────┘

Servicos (Repositorios Separados)

Cada servico eh um diretorio/repo independente. Desenho baseado em perfis de carga distintos.

ServicoLinguagemPerfil de CargaScaling
asender-authGoBaixo, picos em login2-4 replicas
asender-coreGoBaixo, business logic1-2 replicas
asender-apiGoMuito alto (ingress publico)5-20 replicas
asender-email-workerGoBursty (campanhas)2-10 replicas
asender-sms-workerGoBursty1-5 replicas
asender-push-workerGoSpikey (blasts)1-5 replicas
asender-webhook-workerGoBursty (egress)2-5 replicas
asender-backofficeTS/NextBaixo (team interno)1 replica
asender-dashboardTS/NextMedio (customers)2-4 replicas
asender-sharedGo lib--
asender-relay-phpPHPEdge (deploy por customer)-

Comunicacao entre Servicos

Sincrona (HTTP)

Protocolo: HTTP JSON. Auth inter-service via token service-to-service (JWT com claim svc=<name>).

Assincrona (NATS JetStream)

Streams:

Request/Reply (NATS)

Para calls sincronos sem HTTP (e.g. validacao rapida de tenant).

Auth Flow

Customer (dashboard)

1. POST /api/auth/login (dashboard BFF) -> asender-api -> asender-auth
2. asender-auth valida credenciais, cria session, retorna JWT
3. Dashboard guarda JWT em httpOnly cookie
4. Proximas requests mandam JWT via cookie

API publica (SDK do customer)

1. Customer app manda header Authorization: Bearer sk_live_xxx
2. asender-api valida API key contra asender-core
3. asender-api cria contexto de tenant + scope
4. Roteia request pro handler apropriado

Internal team (backoffice)

Similar ao customer flow, mas com role = asender_admin no JWT.
Acesso a endpoints /api/admin/* que operam cross-tenant.

Service-to-service

Cada servico tem um key de servico (SERVICE_SECRET env var).
Requests internas usam header X-Asender-Svc-Token: <jwt signed with shared secret>.
Claims: { svc, iss, exp, iat }.

Database Strategy

Shared Postgres instance, schema por servico.

Isolation via schema + roles Postgres. Cada servico tem role propria com acesso so ao seu schema + referencias a dados de outros services via ID.

Trade-off: migracao pra DB-per-service se um deles precisar.

IDs Publicos

Convencao: <prefixo>_<16 hex> (usando crypto/rand).

PrefixoRecurso
usr_User
acc_Tenant (account)
key_API Key
sk_live_API Key plaintext
sk_test_API Key test mode
sk_master_Relay master key
rel_Relay
whk_Webhook endpoint
tpl_Template
cam_Campaign
cnt_Contact
lst_List
msg_EmailMessage
sms_SmsMessage
psh_PushMessage
evt_Event
whd_Webhook delivery
req_Request (tracing)

Deployment

Cada servico:

Orchestracao: Kubernetes (prod), docker-compose (dev), Fly.io ou Railway (staging).

Convencoes Comuns (asender-shared)

Lib asender-shared (Go) expoe:

Observabilidade

Seguranca

Frontend Architecture

Backoffice (interno Asender)

Dashboard (customer-facing)

Shared UI

Cada frontend tem seu proprio design system mas compartilham design tokens via @asender/design-tokens (opcional, mais tarde).

Roadmap por Fase (Revisado)

Ver ROADMAP.md.