quantumbpm

package module
v1.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 25, 2026 License: MIT Imports: 8 Imported by: 0

README

QuantumBPM Go SDK

Official Go SDK for the QuantumBPM platform - DMN evaluation, BPMN process orchestration, and external job workers.

Installation

go get github.com/QuantumBPM/quantum-go-sdk

Requires Go 1.23+.

What's in the box

Package Purpose
quantumbpm (root) Top-level Client exposing .DMN and .BPMN, plus NewWorker(...)
quantumbpm/auth TokenProvider interface, ZitadelTokenProvider, StaticTokenProvider
quantumbpm/dmn DMN evaluation: stored definitions, ad-hoc XML, batch
quantumbpm/bpmn BPMN resources, instances, messaging, user tasks, processes
quantumbpm/workers External job worker runtime - long-poll, lock heartbeat, dispatch
quantumbpm/variables Vars map type with typed accessors and FEEL-context conversion
quantumbpm/generated OpenAPI-generated client. Reachable via Client.Raw(), never hand-edited

Quick start

package main

import (
    "context"
    "log"

    "github.com/google/uuid"

    quantumbpm "github.com/QuantumBPM/quantum-go-sdk"
    "github.com/QuantumBPM/quantum-go-sdk/auth"
    "github.com/QuantumBPM/quantum-go-sdk/variables"
)

func main() {
    provider, err := auth.NewZitadelTokenProvider(
        "./service-account.json",       // Zitadel JSON Key file
        "https://auth.quantumbpm.com",  // issuer
        "your-zitadel-project-id",      // audience scope
    )
    if err != nil {
        log.Fatal(err)
    }

    client, err := quantumbpm.New(quantumbpm.Config{
        BaseURL:       "https://api.quantumbpm.com",
        ProjectID:     uuid.MustParse("00000000-0000-0000-0000-000000000000"),
        TokenProvider: provider,
    })
    if err != nil {
        log.Fatal(err)
    }

    ctx := context.Background()
    result, err := client.DMN.Evaluate(ctx, "loan-eligibility", variables.New().
        Set("requestedAmt", 1000).
        Set("creditScore", 720))
    if err != nil {
        log.Fatal(err)
    }
    log.Printf("decisions: %+v", result)
}

Authentication

The auth.TokenProvider interface returns a bearer token on each request. Two implementations ship out of the box.

Zitadel service account
provider, err := auth.NewZitadelTokenProvider(
    "./service-account.json",      // path to JSON Key file
    "https://auth.quantumbpm.com", // issuer URL
    "your-zitadel-project-id",     // adds the audience scope
)

The provider caches tokens in-memory until shortly before expiry.

Static bearer token

For Enterprise deployments that issue long-lived API keys, or in tests where a token is acquired out of band:

provider := auth.NewStaticTokenProvider("eyJhbGciOi...")
Bring your own

Implement the interface:

type TokenProvider interface {
    Token(ctx context.Context) (string, error)
}

auth.TokenProviderFunc(fn) adapts a plain function literal.

DMN evaluation

The client.DMN sub-client offers four methods.

Evaluate a stored definition
result, err := client.DMN.Evaluate(ctx, "loan-eligibility", variables.New().
    Set("requestedAmt", 5000).
    Set("creditScore", 720))

Returns map[string]EvaluationResult keyed by decision ID. Each result has Value, HitRules, Error, and Type.

Pin a version, restrict the evaluated decisions, or attach decision services:

result, err := client.DMN.Evaluate(ctx, "loan-eligibility", vars,
    dmn.WithVersion(3),
    dmn.WithDecisions("eligibility", "rate"),
)
Evaluate by platform UUID

When you already hold a database-version pointer:

result, err := client.DMN.EvaluateByID(ctx, definitionUUID, vars)
Ad-hoc XML evaluation

For "evaluate while editing" flows that don't store the XML:

result, err := client.DMN.EvaluateDesign(ctx, dmnXML, vars,
    dmn.WithAdditionalXMLs(importedXML1, importedXML2),
    dmn.WithDesignDecisions("eligibility"),
)
Batch ad-hoc evaluation
rows := []variables.Vars{
    variables.New().Set("requestedAmt", 1000),
    variables.New().Set("requestedAmt", 5000),
    variables.New().Set("requestedAmt", 25000),
}
batch, err := client.DMN.EvaluateDesignBatch(ctx, dmnXML, rows)

BPMN processes

client.BPMN covers the full BPMN runtime surface. Highlights:

Deploy and start
// Stage a BPMN draft, then deploy it.
draft, err := client.BPMN.CreateResource(ctx, "loan-process", bpmnXML)
if err != nil { log.Fatal(err) }

if err := client.BPMN.DeployResource(ctx, draft.Id); err != nil {
    log.Fatal(err)
}

// Start an instance from the deployed process definition.
workflowID, err := client.BPMN.StartInstance(ctx, draft.ProcessDefinition.Id, variables.New().
    Set("applicantID", "u-123").
    Set("requestedAmt", 25000))
Inspect runtime state
state, err := client.BPMN.GetInstance(ctx, workflowID)
fmt.Println(state.Status, state.ActiveScopes)

vars, err := client.BPMN.GetInstanceVariables(ctx, workflowID)

children, err := client.BPMN.GetInstanceChildren(ctx, workflowID)
Send messages and signals
err := client.BPMN.PublishMessage(ctx, "loan-approved",
    variables.New().Set("approvedAmt", 24000),
    bpmn.WithCorrelationKeys(bpmn.CorrelationKeys{ /* ... */ }),
    bpmn.WithMessageTTL("PT5M"),
)

err = client.BPMN.PublishSignal(ctx, "system-maintenance", variables.New())
User tasks
page, err := client.BPMN.ListUserTasks(ctx,
    bpmn.WithUserTaskAssignee("alice@example.com"),
    bpmn.WithUserTaskStatus("CREATED"),
)

err = client.BPMN.CompleteUserTask(ctx, executionKey,
    variables.New().Set("approved", true))

// Or fail with a BPMN error code (matches boundary error events):
err = client.BPMN.ThrowUserTaskError(ctx, executionKey, "REVIEW_REJECTED", variables.New())

External job workers

Workers handle service tasks asynchronously. Register a handler per taskType, then call Run. The runtime owns long-polling, lock heartbeats, dispatch, and outcome mapping.

Minimal worker
worker := client.NewWorker(workers.Config{ClientID: "billing-svc"})

worker.Handle("send-email", func(ctx context.Context, j *workers.Job) (variables.Vars, error) {
    to, _ := variables.Get[string](j.Vars, "recipient")
    subject, _ := variables.Get[string](j.Vars, "subject")

    if err := emailer.Send(to, subject); err != nil {
        return nil, err  // → ThrowError("WORKER_ERROR"); retry budget decrements
    }
    return variables.New().Set("messageID", "msg-123"), nil  // → Complete
})

ctx, cancel := context.WithCancel(context.Background())
defer cancel()
if err := worker.Run(ctx); err != nil {
    log.Fatal(err)
}

Run blocks until ctx is cancelled. In-flight handlers are allowed to finish before it returns.

Concurrency, polling, and locks
worker.Handle("send-email", handler,
    workers.WithMaxJobs(10),                    // up to 10 in flight per task type
    workers.WithPollTimeout(45*time.Second),    // long-poll wait
    workers.WithLockDuration(2*time.Minute),    // exclusive lock per job
)

Concurrency is per task type. Different task types run in independent goroutine pools. The runtime auto-renews the lock at half the lock-duration interval while the handler runs.

Throwing typed BPMN errors

Return a *workers.BpmnError to fail the job with a code that boundary error events on the originating service task can catch:

worker.Handle("charge-card", func(ctx context.Context, j *workers.Job) (variables.Vars, error) {
    if err := charge(j.Vars); errors.Is(err, ErrInsufficientFunds) {
        return nil, workers.NewBpmnError("INSUFFICIENT_FUNDS",
            variables.New().Set("availableBalance", 12.00))
    }
    return variables.New().Set("transactionID", txID), nil
})

Other errors (transient I/O, panics) are reported as WORKER_ERROR, which the server treats as a retryable failure that decrements the job's retry budget.

Typed handlers

HandleTyped[T] decodes the job's input variables into a struct before invoking the handler:

type EmailJob struct {
    Recipient string `json:"recipient"`
    Subject   string `json:"subject"`
}

workers.HandleTyped(worker, "send-email",
    func(ctx context.Context, j *workers.Job, in EmailJob) (variables.Vars, error) {
        if err := emailer.Send(in.Recipient, in.Subject); err != nil {
            return nil, err
        }
        return variables.New().Set("messageID", "msg-123"), nil
    },
)

Variables

The variables.Vars type is a thin map[string]any shared by DMN, BPMN, and workers.

Construction
v := variables.New().Set("amount", 100).Set("name", "Alice")
v := variables.From(map[string]any{"amount": 100, "name": "Alice"})
Typed access
amt, err := variables.Get[float64](v, "amount")
flag, err := variables.Get[bool](v, "approved")

type Loan struct {
    RequestedAmt float64 `json:"requestedAmt"`
    Approved     bool    `json:"approved"`
}
loan, err := variables.As[Loan](v)

Get and As use a JSON round-trip, so nested structs and arbitrary value types work without custom registration.

Escape hatch

The client.Raw() and client.BPMN.Raw() methods expose the underlying generated client for endpoints that are not wrapped (instance migration, modification, ad-hoc triggers, batch job complete/error, etc.).

raw := client.Raw()
resp, err := raw.MigrateBpmnInstanceWithResponse(ctx, projectID, workflowID, body)

License

MIT License - see LICENSE for details.

Documentation

Overview

Package quantumbpm is the Go SDK for QuantumBPM: BPMN 2.0 workflow orchestration, DMN 1.5 decision evaluation with FEEL, and external job workers.

Construct a Client with quantumbpm.New, then reach the per-domain sub-clients via .DMN and .BPMN. To run external job workers, call Client.NewWorker.

provider, _ := auth.NewZitadelTokenProvider(keyPath, issuer, projectID)
client, _ := quantumbpm.New(quantumbpm.Config{
    BaseURL:       "https://api.quantumbpm.com",
    ProjectID:     projectUUID,
    TokenProvider: provider,
})

result, _ := client.DMN.Evaluate(ctx, "loan-eligibility", vars)
wfID,    _ := client.BPMN.StartInstance(ctx, processDefID, vars)

worker := client.NewWorker(workers.Config{ClientID: "billing-svc"})
worker.Handle("send-email", func(ctx context.Context, j *workers.Job) (variables.Vars, error) {
    // ... send email ...
    return variables.New().Set("messageID", id), nil
})
worker.Run(ctx)

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Client

type Client struct {

	// DMN evaluates DMN definitions in the project.
	DMN *dmn.Client
	// BPMN drives BPMN process resources, instances, messaging, and user tasks.
	BPMN *bpmn.Client
	// contains filtered or unexported fields
}

Client is the top-level QuantumBPM SDK entry point.

func New

func New(cfg Config) (*Client, error)

New constructs a Client. Returns an error when required config is missing or the underlying HTTP client cannot be initialized.

func (*Client) NewWorker

func (c *Client) NewWorker(cfg workers.Config) *workers.Worker

NewWorker constructs an external job worker bound to this client's project. Register handlers via Worker.Handle (or workers.HandleTyped[T]) and call Worker.Run to start polling.

func (*Client) ProjectID

func (c *Client) ProjectID() uuid.UUID

ProjectID returns the project the client is bound to.

func (*Client) Raw

Raw exposes the generated OpenAPI client for endpoints not covered by the wrapper (migrate, modify, ad-hoc, batch jobs, etc.).

type Config

type Config struct {
	// BaseURL is the QuantumBPM API root (e.g. https://api.quantumbpm.com).
	BaseURL string

	// ProjectID is the workspace the client is scoped to. All DMN, BPMN, and
	// worker calls operate against this project.
	ProjectID uuid.UUID

	// TokenProvider supplies a bearer token on every request. Use
	// auth.NewZitadelTokenProvider for Zitadel-issued tokens or
	// auth.NewStaticTokenProvider for fixed API keys.
	TokenProvider auth.TokenProvider
}

Config holds construction parameters for Client.

Directories

Path Synopsis
Package auth provides token providers and an authenticated HTTP client wrapper for the QuantumBPM SDK.
Package auth provides token providers and an authenticated HTTP client wrapper for the QuantumBPM SDK.
Package bpmn wraps the QuantumBPM BPMN engine endpoints.
Package bpmn wraps the QuantumBPM BPMN engine endpoints.
Package dmn wraps the QuantumBPM DMN evaluation endpoints with a project-scoped client.
Package dmn wraps the QuantumBPM DMN evaluation endpoints with a project-scoped client.
Package generated provides primitives to interact with the openapi HTTP API.
Package generated provides primitives to interact with the openapi HTTP API.
Package variables provides the Vars type for passing values to and from the QuantumBPM DMN engine and BPMN runtime.
Package variables provides the Vars type for passing values to and from the QuantumBPM DMN engine and BPMN runtime.
Package workers provides a long-poll runtime for BPMN external service tasks.
Package workers provides a long-poll runtime for BPMN external service tasks.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL