Developers
Arquitetura e referência da API do Firmbeat.
Arquitetura
Backend em Go (hexagonal: domain → ports → adapters + use-cases em app), schema-first em Protobuf (buf) para o boundary canônico. Três deployables: ingest-core (Go), platform-api (Go, control-plane + API REST), risk-engine (Python). Frontends em React + Vite + TypeScript + Tailwind (monorepo: admin, studio, app + packages api/auth/ui).
Engine Stack
O produto é uma cadeia de motores:
Enterprise Context Engine organograma, métricas, RBAC
↓
Expectation Engine fórmulas + eventos (baseline esperado)
↓
Business Observability Eng. pulse contínuo + snapshots
↓
Probabilistic Engine risco, valor em risco, probabilidade
↓
Decision Engine alertas / roteamento (IA conversacional: roadmap)
↓
Surfaces Executive Pulse · Sala de Situação (NOC) · Studio · Admin
Stack & deploy
| Camada | Tecnologia |
|---|---|
| API / control-plane | Go (net/http, hexagonal) |
| Persistência | Postgres (Neon) — JSONB por entidade; fallback in-mem+JSON |
| Motor de fórmulas | expr-lang/expr (avaliador sandboxed) |
| Auth | Microsoft Entra (CIAM clientes + workforce), OIDC multi-issuer (go-oidc) |
| Hospedagem | Azure Container Apps (scale-to-zero), ACR firmbeatacr, RG firmbeat-rg |
| Frontends | Cloudflare Pages (admin/studio/app + help/developers) |
Recipe de deploy
az acr build --registry firmbeatacr --image platform-api:vN \
--file services/platform-api/Dockerfile .
az containerapp update -n firmbeat-platform-api -g firmbeat-rg \
--image firmbeatacr.azurecr.io/platform-api:vN
# frontend
npm run build -w @firmbeat/<app>
npx wrangler pages deploy apps/<app>/dist --project-name firmbeat-<app> --branch main
Base & convenções
- Base URL:
https://firmbeat-platform-api.<env>.brazilsouth.azurecontainerapps.io(prefixo/api/v1). - Multi-tenant: rotas escopadas por
/tenants/{id}/...; isolamento portenant_id. - JSON em request/response;
Content-Type: application/json. - IDs com prefixo:
tnt_,usr_,dept_,pos_,evt_,fml_,snp_,rule_… - CORS liberado para
*.firmbe.at+ localhost.
Autenticação
Bearer token (JWT) do Entra no header Authorization: Bearer <token>. O backend valida múltiplos issuers (CIAM dos clientes + workforce da Spingere) e aceita o aud em ambas as formas (api://<guid> e <guid>).
Authorization: Bearer eyJhbGciOi...
RBAC
platform_admin:GET/POST /tenants(cross-tenant).- Rotas
/tenants/{id}/...: exigemplatform_adminou usuário do próprio tenant. - Sem env OIDC, a auth fica desabilitada (dev) e
/meretorna um admin sintético.
Identidade
Tenants & onboarding
Organograma & visões
Métricas, Pulse & Wall
Firmbeat Calendar
Motor de Risco — fórmulas
Expressões avaliam variáveis (amostras) + eventFactor + funções exp, log, sqrt, pow, min, max, abs. Fórmula expected calcula a expectativa; probability retorna 0..1.
Business Observability — snapshots
Sources & agentes
Modelo de domínio
| Entidade | Resumo |
|---|---|
Tenant | cliente/workspace |
User / Invite | identidade (issuer+subject) + onboarding por token |
Department / Position | organograma (árvore via parentId); Position tem role, pessoa, widgets |
Widget | métrica + tipo de gráfico (number/line/bar/donut) |
CalendarEvent / MetricImpact | evento multi-área + impacto na métrica (direção, magnitude) |
Formula (+ FormulaVersion) | expectativa/probabilidade versionada e publicável |
ReportSnapshot | estado congelado da empresa/área |
SourceSystem / Agent / Metric / AlertRule | fontes, coletores, data contracts e regras de alerta |
Erros
Erros retornam { "error": "mensagem" } com o status apropriado:
| Status | Quando |
|---|---|
400 | corpo inválido |
401 | token ausente/inválido |
403 | sem acesso ao tenant / requer platform_admin |
404 | não encontrado |
409 | tenant inativo |
422 | validação (nome, e-mail, data, fórmula…) |
500 | erro interno |
Firmbeat — Expectation OS.