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(dbwrkflw) - Temporal →
localhost:7233, UI onlocalhost: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 forlegal-reviewers,FLOW_STARTEDin 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.