Skip to content

Service Architecture

Overview

Floh uses a monorepo with optional service separation. The core deployment consists of three services:

  1. API Server -- Fastify HTTP server handling all API requests
  2. Worker -- BullMQ job consumer for background processing
  3. Infrastructure -- PostgreSQL, Redis, and SMTP
┌─────────────┐   ┌─────────────┐   ┌──────────────┐
│  Admin Web  │   │ Portal Web  │   │  MCP Client  │
│  (Angular)  │   │  (Angular)  │   │              │
└──────┬──────┘   └──────┬──────┘   └──────┬───────┘
       │                 │                  │
       ▼                 ▼                  ▼
┌──────────────────────────────────────────────────┐
│               API Server (Fastify)               │
│  ┌──────────┐ ┌──────────┐ ┌──────────────────┐  │
│  │   Auth   │ │ Workflows│ │  Admin Settings  │  │
│  │  (OIDC)  │ │  Engine  │ │   (CORS, etc.)   │  │
│  └──────────┘ └──────────┘ └──────────────────┘  │
│  ┌──────────┐ ┌──────────┐ ┌──────────────────┐  │
│  │ Reports  │ │  Roles   │ │   Connectors     │  │
│  │ Schedules│ │Entitle.  │ │                  │  │
│  └──────────┘ └──────────┘ └──────────────────┘  │
│  Rate-limited │ CORS-restricted │ CSRF-protected │
└────────────────┬──────────┬──────────────────────┘
                 │          │
       ┌─────────┘          └──────────┐
       ▼                               ▼
┌──────────────┐              ┌──────────────┐
│  PostgreSQL  │              │    Redis     │
│   (pooled)   │              │  (sessions,  │
│              │              │   BullMQ)    │
└──────────────┘              └──────┬───────┘
                            ┌──────────────┐
                            │   Worker(s)  │
                            │  (BullMQ     │
                            │   consumer)  │
                            └──────────────┘

Service Boundaries

API Server

  • All HTTP endpoints (REST API, Swagger docs)
  • Authentication and session management (OIDC, JWT, API tokens)
  • Rate limiting, CORS, CSRF protection
  • Workflow engine execution (synchronous)
  • Enqueues background jobs to Redis/BullMQ

Worker Process

  • Consumes BullMQ jobs from the workflow-scheduler queue
  • Runs scheduled workflows, report generation, reconciliation
  • Handles escalation reminders and reassignments
  • Performs stuck run recovery and orphan cleanup
  • Independently scalable (multiple replicas)

Shared State

Both processes share:

Resource Purpose
PostgreSQL Application data, audit logs, system settings
Redis BullMQ queue, session store, distributed locks

No in-memory state is shared between processes.

Deployment Modes

1. Combined (Default)

Single process runs both HTTP server and BullMQ worker. Suitable for development and small deployments.

node dist/index.js

HTTP server and worker run as independent processes. Set WORKER_MODE=separate on the HTTP server.

# HTTP server
WORKER_MODE=separate node dist/index.js

# Worker (1+ instances)
node dist/worker.js

Security Architecture

See Security for detailed security documentation.

Layer Protection
Transport TLS termination (Caddy/Nginx)
Authentication OIDC + session cookies
Authorization Permission-based guards per route
CORS Whitelist of allowed origins
CSRF Double-submit cookie pattern
Rate Limiting Global + per-route limits
Secrets Validated at startup, no defaults in production
Encryption AES-256-GCM for connector secrets and sessions
Error Handling Stack traces stripped in production

Future Separation Candidates

The service separation plan identifies additional extraction opportunities:

  1. Report Service -- Extract report generation into a dedicated service with its own BullMQ queue. Justified when report load impacts API latency.
  2. Queue-Driven Execution -- Move workflow execution behind BullMQ for fully async processing. Requires frontend changes.
  3. Notification Worker -- Extract email delivery into a dedicated worker for isolation from main processing.

See the Service Separation Plan in TODO.md (repo root) for detailed analysis.