Architecture
How Pomavo is built: the service topology, data stores, messaging, and the principles behind the platform.
Overview
This section goes under the hood. While the rest of the documentation describes what Pomavo does, these pages explain how it works: the services that make up the system, where data lives, how work flows asynchronously, and the design principles that keep the platform fast, multi-tenant, and extensible.
This is engineering-oriented documentation. You do not need any of it to use Pomavo, but it is useful if you operate a deployment, build plugins, or integrate deeply.
Service Topology
Pomavo is composed of focused services orchestrated together. Each has a single responsibility:
| Service | Responsibility |
|---|---|
| Web | React single-page app, the entire user interface |
| Web API | The core REST API: tickets, templates, workflows, projects, search, permissions |
| Worker | Asynchronous background processing, every side effect runs here |
| Automations | One-time startup tasks: database migrations, seeding, search-index setup |
| Auth | Standalone identity service for sessions, OAuth, and token issuance |
| Plugins & integrations | Sandboxed extensions and first-party integrations such as GitHub |
The browser talks to the Web API; the Web API performs the operation, persists it, and hands off everything that can happen later to the Worker through a message log.
Data Stores
Pomavo uses the right store for each job rather than forcing everything into one database:
| Store | What it holds |
|---|---|
| PostgreSQL | The system of record, tickets, templates, workflows, projects, users, permissions |
| Elasticsearch | The search index that powers the query language and saved queries |
| MongoDB | Background jobs and their per-run execution logs |
| Object storage | Attachments and binary assets |
| Messaging - Kafka | The durable event log connecting the Web API to the Worker |
Core Principles
Asynchronous by default
User actions return immediately; side effects - indexing, history, notifications, and automations - run in the background so the UI is always responsive.
Multi-tenant isolation
Every record is scoped to an organization. Tenant context flows through every request and job.
Typed automation contracts
Automation nodes share one canonical, typed contract validated at runtime: no silent type mismatches.
Extensible by design
Plugins run in a sandbox and communicate through a typed SDK, so the core never needs to change to add capabilities.
Deep Dives
Automation Engine Internals
The typed node contract, the resolution pipeline, the orchestrator, and runtime shape validation.
The Job Pipeline
How an event becomes a durable job, gets consumed, executed, and spawns sub-jobs: including schedulers.
Search Internals
How the query language is lexed, parsed, and translated into Elasticsearch queries and aggregations.
Extensibility Internals
The plugin SDK message protocol, the iframe sandbox, manifests, and the lifecycle handshake.
Security Model
Identity, tokens, API keys, permissions, plugin sandboxing, and tenant isolation.
Observability
Every service emits OpenTelemetry traces, metrics, and structured logs to a Grafana-based stack, so operators can follow a single user action from the API through the message log and into the Worker's job runs.