Service Architecture¶
Overview¶
Floh uses a monorepo with optional service separation. The core deployment consists of three services:
- API Server -- Fastify HTTP server handling all API requests
- Worker -- BullMQ job consumer for background processing
- 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-schedulerqueue - 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.
2. Separate (Recommended for Production)¶
HTTP server and worker run as independent processes. Set WORKER_MODE=separate on the HTTP server.
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:
- Report Service -- Extract report generation into a dedicated service with its own BullMQ queue. Justified when report load impacts API latency.
- Queue-Driven Execution -- Move workflow execution behind BullMQ for fully async processing. Requires frontend changes.
- 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.