Arquitetura
Visão geral
┌──────────────────────────────────────────────────┐
│ Frontend (React 19 + Vite) │
│ TanStack Router → Componentes → Axios → API │
└────────────────────┬─────────────────────────────┘
│ HTTPS / JWT / WebSocket
▼
┌──────────────────────────────────────────────────┐
│ Backend (Spring Boot 3.5) │
│ │
│ Security Filters │
│ JWT → ApiKey → TenantFilter → AuditLog │
│ ↓ │
│ Controllers (REST, OpenAPI 3.1) │
│ ↓ │
│ Services (@Transactional) │
│ ↓ │
│ Repositories (JPA) + Flowable Engines │
│ (BPMN, CMMN, DMN, Task, History) │
│ │
│ + NotificationService (WebSocket STOMP) │
│ + RobotExecutor (Scheduler + ClassLoader) │
│ + WebhookDispatcher (retry + HMAC-SHA256) │
│ + AttachmentStorage (Global filesystem / S3) │
│ + AgenticLlmCoreService (Spring AI + RAG) │
└────────────────────┬─────────────────────────────┘
│
┌────────────┼────────────┐
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│ public │ │tenant_abc│ │tenant_xyz│
│ (shared) │ │(isolado) │ │(isolado) │
└──────────┘ └──────────┘ └──────────┘
└────────────┴────────────┘
│
┌──────┴──────┐
│ PostgreSQL 16│
└─────────────┘Camadas da aplicação
Backend
Controller — REST endpoint, anotações OpenAPI, sem lógica de negócio
↓
Service — lógica de negócio, @Transactional, validações
↓
Repository — interfaces JPA (Spring Data)
Engine — Flowable BPMN/CMMN/DMN (via Services)
↓
Entity — modelos JPA mapeados ao bancoRegras:
- Controller nunca acessa Repository diretamente
- Services gerenciam todas as transações
- Toda interação com Flowable passa pelo Service
Frontend
Routes (TanStack Router)
↓
Pages (componentes de página)
↓
Hooks (React Query — dados remotos) + Stores (Zustand — estado local)
↓
lib/axios.ts (cliente HTTP com interceptors JWT + refresh)Filtros de segurança (Backend)
Os filtros são aplicados em cadeia a cada requisição:
| Filtro | Responsabilidade |
|---|---|
JwtAuthFilter | Valida Bearer token JWT e popula o SecurityContext |
ApiKeyFilter | Autentica requisições via header X-API-Key |
TenantFilter | Extrai X-Tenant-ID do header e popula TenantContext (ThreadLocal) |
AuditLogFilter | Registra requisições de escrita para auditoria |
Componentes especiais
TenantAwareDataSource
AbstractRoutingDataSource que roteia cada conexão de banco para o schema correto baseado no TenantContext. Cada tenant tem um pool HikariCP dedicado, criado no momento do provisionamento.
RobotExecutor
Carrega JARs de robôs em ClassLoaders isolados (sem conflito de dependências entre robôs). Usa ScheduledTaskRegistrar para executar conforme expressão cron.
WebhookDispatcher
Envia eventos assíncrona e com retry exponencial. Cada payload é assinado com HMAC-SHA256 se o webhook tiver secret configurado.
NotificationService
Usa Spring WebSocket (STOMP) para enviar notificações em tempo real ao frontend. Cada usuário se inscreve em um canal pessoal.
FormVersionLockListener
Listener Flowable do tipo TASK_CREATED. Quando o engine cria uma tarefa, este listener:
- Lê o
formKeydefinido no modelo BPMN/CMMN - Chama
FormService.resolvePublishedVersion(formKey)para obter a versão publicada (ou a mais recente se nenhuma foi publicada) - Armazena o UUID da versão na variável local da tarefa:
_form_version_id
Isso garante que a tarefa sempre exiba o formulário com o schema da versão que estava vigente em sua criação. isFailOnException = false — uma falha ao travar a versão não impede a criação da tarefa.
AiClientFactory e PgVector Dinâmico
O Flowi Agentic integra nativamente o Spring AI. Para suportar o fato de que a plataforma permite alterar as configurações de provedor e dimensões do modelo de embeddings via banco (Tabela rag_global_config), o Vector Database (PgVectorStore com indexação HNSW em PostgreSQL) é recriado on-the-fly. O AiClientFactory lê a configuração e instancia o VectorStore dinamicamente sob demanda. Quando uma alteração estrutural de dimensão ocorre, o banco deforma e auto-reconstrói a tabela vector_store, invalidando vetores antigos que precisariam ser gerados através do endpoint de reindexação.