Skip to content

Run the document-approval flow locally

This tutorial gets you from a clean checkout to a running flow you can drive by hand.

Authoritative steps

The canonical, always-current run instructions live in specs/001-document-approval-engine/quickstart.md. This page is the gentle, narrative version; if they disagree, the quickstart wins (and please fix this page).

Prefer Docker for everything?

See Run the full stack with Docker to build and run api-service and worker-service inside containers instead of on the host.

1. Prerequisites

  • mise — installs and pins all other tools
  • Docker

2. Install pinned tools

mise install         # installs temurin-21 + uv (for the docs site)

This reads mise.toml and installs exactly the JDK and Python versions the project requires. No manual JAVA_HOME wrangling needed.

3. Start backing services

mise run services:up
  • PostgreSQL → localhost:5432 (db wrkflw)
  • Temporal → localhost:7233, UI on localhost:8233

4. Build and migrate

mise run build       # compile + test all modules (includes the boundary-test gate)
mise run migrate     # apply schema migrations + seed document-approval definition

The build runs the architecture boundary test — if domain/application ever import a framework type, it fails here by design.

5. Run the two services

Open two terminals:

# terminal 1
mise run run:worker  # Temporal workflows + activities

# terminal 2
mise run run:api     # REST on :8080 + outbox publisher

6. Drive a flow

Identity is supplied via headers in the first deliverable (X-Actor-Id / X-Actor-Groups).

# Submit (caller must be in the initiator group)
curl -s -X POST localhost:8080/api/v1/flows \
  -H 'Content-Type: application/json' \
  -H 'X-Actor-Id: alice' -H 'X-Actor-Groups: initiators' \
  -d '{"definitionKey":"document-approval","documentRef":"doc-123"}'

# Reviewer claims and approves
curl -s -X POST localhost:8080/api/v1/tasks/$TASK_ID/claim \
  -H 'X-Actor-Id: bob' -H 'X-Actor-Groups: legal-reviewers'
curl -s -X POST localhost:8080/api/v1/tasks/$TASK_ID/decision \
  -H 'Content-Type: application/json' \
  -H 'X-Actor-Id: bob' -H 'X-Actor-Groups: legal-reviewers' \
  -d '{"outcome":"APPROVE","comment":"looks good"}'

# Inspect status + history
curl -s localhost:8080/api/v1/flows/$FLOW_ID

What you just exercised

  • US1 submit → flow RUNNING, first task for legal-reviewers, FLOW_STARTED in history.
  • US2 claim → approve → task COMPLETED, flow advances, decision recorded.
  • Audit history and (US5) CloudEvents emitted via the outbox.

Next: Add a new flow definition.