Architecture
How BPMS is structured and the decisions behind it.
BPMS is an extensible modular monolith: one application, built from a fixed core and replaceable parts. Think of a building with a fixed structure and movable partitions: the core is the concrete, and the packages and strategies are the partitions.
Core, packages, and distributions
| Part | Role | Today |
|---|---|---|
Core (packages/core) | Contracts and infrastructure shared by every package: configuration, request context, tenancy, sessions, errors, and the audit log. It knows no business process. | core |
Packages (packages/*) | Each package adds one area of the business. It depends only on the core and activates itself when it is installed. | access: users, sign-in, and roles over the BPMS 3.x data. |
Distributions (apps/*) | A distribution assembles packages into a runnable application. | server |
Three mechanisms keep the core stable:
- Single configuration: one typed configuration describes the whole system.
- Strategies: every point of variation is an interface with a default implementation, such as the authentication method or the tenant resolver. A deployment replaces a strategy through configuration.
- Packages: modules that contribute entities, endpoints, permissions, and configuration.
Dependencies point inward only: the core never depends on a package, and a package never depends on another package's implementation. The build enforces this rule.
One API for every client
BPMS is headless. Its interface is one REST API, versioned as a whole, with paths of the form /api/v{n}/<package>/<resource>, for example /api/v1/access/roles. The dashboard, the command-line interface, and integrations use the same API, and permissions decide what each caller may do. Each protocol has its own root: api/ for REST, mcp/ for agents, and soap/ for regulated institutions, and a session is bound to the protocol it was opened for.
The OpenAPI document is a public contract: every operation has one tag, named after its package, and a stable operationId. The build fails if the published document breaks these rules or differs from the committed contract.
Request context and tenancy
Every operation runs with a request context that carries the tenant, taken from the caller's session, and the language. A tenant is a company or business group with its own users, models, processes, tasks, and configuration. The internal tenant number never leaves the server; clients only see an opaque public token.
Data and services
- PostgreSQL holds the business data on the BPMS 3.x schema. The application connection is read-only; only sign-in writes, and only the columns it needs. Schema changes are additive, and against a 3.x database they run only as an explicit migration step.
- Dedicated services each have one responsibility, because production customers hold gigabytes to terabytes of data: the design assigns RabbitMQ to background jobs and outgoing events, and Typesense to search.
- One image, several modes: the same container image runs as the HTTP server, as a background worker without HTTP, or as a one-off migration.
Continuity with BPMS 3.x
- BPMS works on the 3.x database schema; changes are additive.
- BPMS 3.x and BPMS never write to the same database at the same time.
- Each area is ported with the real 3.x behavior as its specification, captured as tests.
Technology
| Component | Version |
|---|---|
| Java | 25 (LTS) |
| Spring Boot | 4.1.2 |
| Spring Modulith | 2.1.2 |
| Gradle | 9.8.2 |
| PostgreSQL | 18 |