Skip to content

Hexagonal architecture

The platform follows strict hexagonal architecture (ports and adapters). This is what keeps the domain testable and lets you extend the platform without forking it.

flowchart TD
    ui["User interfaces<br/>CLI · Web UI · REST API"]
    app["Application layer<br/>Use cases · services · orchestration"]
    domain["Domain layer<br/>Entities · Ports / interfaces"]
    infra["Infrastructure layer<br/>Adapters: DB · API · file system"]

    ui --> app --> domain --> infra
  • Ports (interfaces) live in packages/platform-domain/**/ports/. The domain package is infrastructure-free — no drizzle-orm, pg-boss, fs, or http imports.
  • Adapters (concrete implementations) live in apps/api/**/adapters/.

For example, the workflow runtime defines IWorkflowRepository, IQueueStats and INode as ports; DrizzleWorkflowRepository, the pg-boss queue and the concrete nodes are adapters.

The ports are the extension surface. You extend the platform by implementing one:

Implement……to add
INode / SelfSourcingNodea new workflow node
IExportTargeta new export destination
ISourceReadera new ingestion source
ILlmClienta new LLM provider (reached through the AI gateway)

See Extend the platform for a worked example.