Quickstart: Document Approval Workflow Engine¶
How to run and exercise the first deliverable locally. (Build modules do not exist yet — this is the target developer experience the implementation should deliver.)
Prerequisites¶
- JDK 21
- Docker (for PostgreSQL, Temporal dev server, and Testcontainers)
Local dependencies¶
# PostgreSQL + Temporal dev server (compose file added during implementation)
docker compose up -d postgres temporal
- PostgreSQL:
localhost:5432(dbwrkflw) - Temporal:
localhost:7233(UI onlocalhost:8233)
Build & migrate¶
./gradlew build # compiles all modules, runs unit + integration tests
./gradlew :adapters:persistence-postgres:flywayMigrate # apply schema (seeds document-approval definition)
The build fails if domain or application acquire a forbidden framework/SQL/Temporal
dependency (Konsist/ArchUnit boundary test — Principle I).
Run the two services¶
./gradlew :apps:worker-service:run # hosts Temporal workflows + activities
./gradlew :apps:api-service:run # serves REST on :8080, runs the outbox publisher
Exercise the document-approval flow¶
Actor identity for the first deliverable is supplied via a trusted header (placeholder for real OIDC). Examples use
X-Actor-Id/X-Actor-Groups.
# 1. Submit a document (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: authors' \
-d '{"definitionKey":"document-approval","documentRef":"doc-123"}'
# → 201 { flowId, currentState: "Submitted", pendingTasks: [ { taskId, candidateGroupId: "reviewers" } ] }
# 2. A reviewer sees the group work list
curl -s localhost:8080/api/v1/worklists/group \
-H 'X-Actor-Id: bob' -H 'X-Actor-Groups: reviewers'
# 3. Claim the task
curl -s -X POST localhost:8080/api/v1/tasks/$TASK_ID/claim \
-H 'X-Actor-Id: bob' -H 'X-Actor-Groups: reviewers'
# 4. Approve it (advances the flow; signals Temporal)
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: reviewers' \
-d '{"outcome":"APPROVE","comment":"looks good"}'
# 5. Inspect status + full history
curl -s localhost:8080/api/v1/flows/$FLOW_ID
Acceptance smoke checks (map to spec)¶
- US1: submit → flow
RUNNING, onePENDINGtask forreviewers,FLOW_STARTEDin history. - US2: claim then approve → task
COMPLETED, decision recorded, flow advances; a second reviewer cannot decide the same task (409). - US3: approve through to
FinalReview→Approvedterminal; reject → returns to submitter (ReworkRequested). - Concurrency (SC-004): two simultaneous claims → exactly one 200, one 409.
- Events (SC-006): each step emits the matching CloudEvent via the outbox.