Arquitetura

O mapa de como tudo se conecta

Referência visual C4 (contexto, containers, componentes) do commerce-vc1: camada comercial multi-tenant da VC1 sobre ERP/SipPulse legados, com ports hexagonais e filas assíncronas. Diagramas clicáveis ampliam em lightbox; detalhes canônicos em 03-ARCHITECTURE.md.

Diagramas C4

Nível 1 = quem usa e com quem a plataforma integra. Nível 2 = processos e dados no meCloud. Nível 3 = módulos de domínio Laravel (schemas PostgreSQL).

C4 nível 1 — contexto commerce-vc1
Contexto (L1). Staff, revenda, cliente final e prospecto (PIN) acessam hosts distintos. O núcleo expõe ports para ERP, SipPulse, CDR, mePay (cobrança + NFCom), meSign, meDNS e notificações — não chama SOAP/Slim nos controllers.
Abrir SVG em nova aba
C4 nível 2 — containers
Containers (L2). Edge TLS (ACME DNS-01), Filament staff, SPA React, API Laravel, workers Horizon, scheduler, PostgreSQL, Redis, object storage e adapters. Observe roteamento por Host e filas nomeadas.
Abrir SVG em nova aba
C4 nível 3 — módulos de domínio
Componentes (L3). Bounded contexts (pricing/tiers, catalog/plans, sales/proposals, rating 30/6, billing/repasse, fiscal NFCom, integration/outbox, audit). Telco espelha SIP/DIDs; rating e crédito vivem no PG, não no switch.
Abrir SVG em nova aba

Mapa rápido por host (clique nas caixas)

Complemento ao C4: fluxo da esquerda (quem acessa) para a direita (sistemas externos).

Site institucional vc1.com.br (repo Site-VC1) só envia CTA; fora deste deploy.

Endereços e quem vê o quê

Pense no endereço na barra do navegador como a “porta de entrada” do prédio: ela define qual inquilino (revenda) e qual tipo de usuário você é — sem precisar escolher revenda num menu.

No ambiente de testes (LAB), os mesmos papéis existem com sufixo .lab (ex.: admin.lab.vc1.com.br).

Dentro da plataforma

Um único software publicado na nuvem (meCloud) serve todas as revendas. A interface muda de marca conforme o endereço — logo e cores vêm do cadastro da revenda, não de um site separado por cliente.

Filament = VC1 Cadastro de revendas, bases de preço, faturas VC1, repasses, bloqueios e suporte com “ver como revenda”.
React = revenda e cliente final Funil de vendas, kanban, área do cliente SIP, proposta pública — herdado e adaptado do produto MeWork de propostas.

O motor comum é Laravel 12 + PostgreSQL 16 + Redis (filas e sessão). Detalhes de onde roda: Onde roda.

Tomadas e plugues (ports e adapters)

Imagine a plataforma como uma tomada na parede: ela define o que precisa (provisionar cliente, bloquear linha, ler ligações, cobrar, emitir nota). Cada sistema de fora é um plugue diferente — hoje o plugue encaixa no ERP e no SipPulse; amanhã pode encaixar no hub falepaco-api e no Kamailio, sem refazer as telas.

Épico E6 — trocar o motor Quando o novo ERP e a telefonia Kamailio estiverem prontos, trocamos só os plugues (LegacyErp* → FalepacoApi*, SOAP → Kamailio). O restante do produto (preços, funil, fatura) permanece. Ver 06-INTEGRATIONS.md §12.

Multi-tenant e white-label

Cada revenda é um tenant resolvido só pelo HTTP Host (ResolveTenantByHost): nunca por path sozinho nem por token de usuário isolado. Slugs reservados (admin, api, sales, …) retornam 404.

  1. Cookie host-only — Sanctum SPA no {slug}.vc1.com.br; sem cookie em .vc1.com.br (evita cross-tenant). Proposta pública: PIN 6 dígitos + cookie de acesso (TTL padrão 12 h).
  2. Global scope — Eloquent BelongsToReseller em entidades de negócio; staff usa policy + withoutGlobalScopes com auditoria.
  3. Branding em runtime — GET /api/v1/tenancy/branding (público, cache Redis 60 s): logo, cores, nome comercial. Um bundle React; sem SCSS compilado por tenant.
  4. Modos de fatura — vc1_invoices (VC1 cobra cliente + repasse) vs reseller_invoices (extrato + fatura VC1→revenda); ver ADR-005.
  5. LAB — decorator LabGuarded* recusa writes fora da integration.lab_allowlist antes de HTTP/SOAP.

Decisões de arquitetura (ADRs)

Cards resumidos — registro completo em decisoes.html e 10-DECISIONS.md (D-ARQ-*).

Pendências operacionais frequentes: intervalo import CDR (D-ARQ-02, padrão 5 min), domínio SIP por revenda (D-ARQ-06, a verificar), path Filament em admin.* (D-ARQ-09).

O que roda “sozinho” no fundo

Muita coisa não acontece no clique do usuário: o sistema trabalha em filas, como uma cozinha com pedidos na passagem.

Job (exemplos)FilaIdempotência / gatilho
ImportCdrJobratingWatermark cdr_imports; schedule ~5 min (D-ARQ-02)
RateBatchJobratinglegacy_cdr_id UNIQUE
CycleCloseJobbilling02:10 America/Sao_Paulo; ciclo mês calendário
FiscalIssueJob / pollfiscal1 NF por invoice_id; consulta 15 min
OutboxDispatchJoboutboxMesma transação PG da mutação de domínio

Tabela completa: 03-ARCHITECTURE.md §7–8.

Por que isso importa

Para TI e desenvolvimento, o desenho C4 + ports deixa explícito onde cortar escopo (Filament vs SPA vs jobs) e como trocar ERP/central no E6 sem reescrever rating ou fatura. Multi-tenant por Host reduz risco de vazamento entre revendas e sustenta white-label sem deploy por cliente. Outbox + inbox idempotente evitam cobrança ou provisionamento duplicado quando webhooks ou SOAP falham e voltam.

LAB vs PROD — trava de segurança

No PROD, clientes reais. No LAB, o time testa com o legado de verdade, mas só contas demo cadastradas numa lista branca (allowlist): qualquer tentativa de alterar outro cliente no ERP ou na central é recusada antes de sair da plataforma.

Aprovação do operador Criar projetos demo no ERP/SipPulse de produção exige OK explícito. Sem isso, o LAB usa adaptadores “falsos” só para desenvolvimento local.

Mais em infraestrutura LAB e mudanças no legado.