Iron Law
NO WORKFLOW WITHOUT DETERMINISM ENFORCEMENT AND IDEMPOTENT ACTIVITIES — non-deterministic workflow code causes replay failures; non-idempotent activities cause duplicate charges, double-sends, and data corruption
Workflow Orchestration Patterns — Temporal + Java 21 / Python 3.14 / NestJS 11.x
Quick Scaffold
# Start Temporal server locally (Docker)
docker run -d --name temporal \
-p 7233:7233 -p 8080:8080 \
temporalio/auto-setup:1.24
# Java 21 / Spring Boot — add to pom.xml
# io.temporal:temporal-sdk:1.25.0
# io.temporal:temporal-spring-boot-autoconfigure-alpha:0.6.0
# Python 3.14 — uv add
uv add temporalio==1.7.0 fastapi uvicorn
# NestJS 11.x — npm
npm install @temporalio/client @temporalio/worker @temporalio/workflow @temporalio/activity
Process
- Deploy Temporal — local Docker or Temporal Cloud (cloud.temporal.io)
- Define Activities — external interactions (API calls, DB writes, emails) — must be idempotent
- Define Workflow — orchestration logic only — must be deterministic (no I/O, no
Date.now(), no random)
- Configure Retry Policies — initial interval, backoff coefficient, max attempts, non-retryable errors
- Register Worker — binds workflow + activity implementations to task queues
- Start Execution — client sends
startWorkflow() with typed input
- Add Signals/Queries — external state mutations (signals) and reads (queries) on running workflows
- Implement Saga — register compensations BEFORE each step; run in reverse (LIFO) on failure
- Add Heartbeats — long-running activities must call
heartbeat() periodically
- Write Tests — use Temporal test environment with time-skipping for deterministic test execution
Key Patterns
| Pattern |
When to Use |
Reference |
| Saga + Compensation |
Distributed transactions needing rollback |
reference/implementation-playbook.md#saga |
| Entity Workflow (Actor) |
One workflow per entity lifecycle (cart, account, order) |
reference/implementation-playbook.md#entity |
| Fan-Out / Fan-In |
Parallel execution of N tasks with result aggregation |
reference/implementation-playbook.md#fanout |
| Async Callback / Signal |
Waiting for external event or human approval |
reference/implementation-playbook.md#signals |
| Activity Heartbeat |
Long-running activities (>30s) with progress tracking |
reference/implementation-playbook.md#heartbeat |
| Workflow Versioning |
Safe code changes while old executions still running |
reference/implementation-playbook.md#versioning |
| Child Workflows |
Decompose large workflows for scalability (1M tasks = 1K x 1K) |
reference/implementation-playbook.md#child |
Workflow vs Activity Decision Rule
Does the code touch an external system? (API, DB, file, email, network)
YES -> Activity
NO -> Workflow (orchestration/decision logic only)
Prohibited in Workflow code:
new Date() / datetime.now() / LocalDateTime.now() — use Workflow.currentTimeMillis() / workflow.now()
Math.random() / random.random() — use Workflow.newRandom() / workflow.random()
- HTTP calls, DB queries, file I/O — move to Activity
- Threading, locks,
Thread.sleep() — use Workflow.sleep()
- Non-deterministic libraries
Conventions & Rules
For per-SDK implementation templates (Java, Python, NestJS), read reference/implementation-playbook.md
Documentation Sources
Before generating code, consult these sources for current SDK APIs:
| Source |
URL / Tool |
Purpose |
| Temporal Docs |
https://docs.temporal.io/dev-guide |
Core concepts, SDK APIs, best practices |
| Java SDK |
https://www.javadoc.io/doc/io.temporal/temporal-sdk/latest/ |
Java workflow/activity annotations |
| Python SDK |
https://python.temporal.io/ |
Python asyncio API reference |
| TypeScript SDK |
https://typescript.temporal.io/ |
NestJS/TypeScript worker and client APIs |
| Context7 MCP |
resolve-library-id: temporalio |
Latest Temporal Python patterns |
Reference Files
| File |
Content |
When to Use |
reference/implementation-playbook.md |
Full workflow + activity code for Java, Python, NestJS; Saga, Entity, Fan-out, Signal, Heartbeat, Versioning, Child Workflow patterns |
Any Temporal implementation |
Common Commands
# View Temporal Web UI (workflows, history, task queues)
open http://localhost:8080
# Java — run worker
mvn spring-boot:run
# Python — run worker
uvicorn src.main:app --reload &
python -m src.worker # separate process
# NestJS — run worker
npm run start:worker # defined in package.json scripts
# Run Temporal test suite (time-skipping enabled)
# Java: mvn test
# Python: pytest -q
# NestJS: npm test
Error Handling
For retry policy templates and non-retryable error classification per SDK, read reference/implementation-playbook.md#retry
Activity retry rule: classify every exception before throwing. Validation errors and business rule violations -> ApplicationFailure.newNonRetryableFailure(). Transient network/timeout errors -> retryable (default).
Workflow failure rule: workflows do not catch activity exceptions unless implementing compensation. Let Temporal's retry engine handle transient failures. Only catch ActivityFailure when running saga compensations.
Idempotency rule: every activity MUST be safe to call N times. Use idempotency keys, upsert patterns, and check-then-act with unique constraints. Verify with: "If this activity runs twice with the same input, is the final state identical?"
Post-Code Review
After writing Temporal workflow code, dispatch these reviewer agents:
architect-review — workflow boundaries, saga completeness, entity lifecycle correctness
security-reviewer — activity input validation, no secrets in workflow state, payload size limits (2MB)
1---2name: workflow-orchestration-patterns3description: Durable workflow orchestration with Temporal for distributed systems across Java 21, Python 3.14, and NestJS 11.x. Covers Workflow vs Activity separation, Saga pattern, Entity workflows, Fan-out/Fan-in, determinism constraints, retry policies, and idempotency. Use when building long-running, failure-resilient distributed business processes.4---56## Iron Law78**NO WORKFLOW WITHOUT DETERMINISM ENFORCEMENT AND IDEMPOTENT ACTIVITIES — non-deterministic workflow code causes replay failures; non-idempotent activities cause duplicate charges, double-sends, and data corruption**910# Workflow Orchestration Patterns — Temporal + Java 21 / Python 3.14 / NestJS 11.x1112## Quick Scaffold1314```bash15# Start Temporal server locally (Docker)16docker run -d --name temporal \17 -p 7233:7233 -p 8080:8080 \18 temporalio/auto-setup:1.241920# Java 21 / Spring Boot — add to pom.xml21# io.temporal:temporal-sdk:1.25.022# io.temporal:temporal-spring-boot-autoconfigure-alpha:0.6.02324# Python 3.14 — uv add25uv add temporalio==1.7.0 fastapi uvicorn2627# NestJS 11.x — npm28npm install @temporalio/client @temporalio/worker @temporalio/workflow @temporalio/activity29```3031## Process32331. **Deploy Temporal** — local Docker or Temporal Cloud (cloud.temporal.io)342. **Define Activities** — external interactions (API calls, DB writes, emails) — must be idempotent353. **Define Workflow** — orchestration logic only — must be deterministic (no I/O, no `Date.now()`, no random)364. **Configure Retry Policies** — initial interval, backoff coefficient, max attempts, non-retryable errors375. **Register Worker** — binds workflow + activity implementations to task queues386. **Start Execution** — client sends `startWorkflow()` with typed input397. **Add Signals/Queries** — external state mutations (signals) and reads (queries) on running workflows408. **Implement Saga** — register compensations BEFORE each step; run in reverse (LIFO) on failure419. **Add Heartbeats** — long-running activities must call `heartbeat()` periodically4210. **Write Tests** — use Temporal test environment with time-skipping for deterministic test execution4344## Key Patterns4546| Pattern | When to Use | Reference |47|---------|-------------|-----------|48| Saga + Compensation | Distributed transactions needing rollback | `reference/implementation-playbook.md#saga` |49| Entity Workflow (Actor) | One workflow per entity lifecycle (cart, account, order) | `reference/implementation-playbook.md#entity` |50| Fan-Out / Fan-In | Parallel execution of N tasks with result aggregation | `reference/implementation-playbook.md#fanout` |51| Async Callback / Signal | Waiting for external event or human approval | `reference/implementation-playbook.md#signals` |52| Activity Heartbeat | Long-running activities (>30s) with progress tracking | `reference/implementation-playbook.md#heartbeat` |53| Workflow Versioning | Safe code changes while old executions still running | `reference/implementation-playbook.md#versioning` |54| Child Workflows | Decompose large workflows for scalability (1M tasks = 1K x 1K) | `reference/implementation-playbook.md#child` |5556## Workflow vs Activity Decision Rule5758```59Does the code touch an external system? (API, DB, file, email, network)60 YES -> Activity61 NO -> Workflow (orchestration/decision logic only)62```6364**Prohibited in Workflow code:**65- `new Date()` / `datetime.now()` / `LocalDateTime.now()` — use `Workflow.currentTimeMillis()` / `workflow.now()`66- `Math.random()` / `random.random()` — use `Workflow.newRandom()` / `workflow.random()`67- HTTP calls, DB queries, file I/O — move to Activity68- Threading, locks, `Thread.sleep()` — use `Workflow.sleep()`69- Non-deterministic libraries7071## Conventions & Rules7273> For per-SDK implementation templates (Java, Python, NestJS), read `reference/implementation-playbook.md`7475## Documentation Sources7677Before generating code, consult these sources for current SDK APIs:7879| Source | URL / Tool | Purpose |80|--------|-----------|---------|81| Temporal Docs | `https://docs.temporal.io/dev-guide` | Core concepts, SDK APIs, best practices |82| Java SDK | `https://www.javadoc.io/doc/io.temporal/temporal-sdk/latest/` | Java workflow/activity annotations |83| Python SDK | `https://python.temporal.io/` | Python asyncio API reference |84| TypeScript SDK | `https://typescript.temporal.io/` | NestJS/TypeScript worker and client APIs |85| Context7 MCP | `resolve-library-id: temporalio` | Latest Temporal Python patterns |8687## Reference Files8889| File | Content | When to Use |90|------|---------|-------------|91| `reference/implementation-playbook.md` | Full workflow + activity code for Java, Python, NestJS; Saga, Entity, Fan-out, Signal, Heartbeat, Versioning, Child Workflow patterns | Any Temporal implementation |9293## Common Commands9495```bash96# View Temporal Web UI (workflows, history, task queues)97open http://localhost:80809899# Java — run worker100mvn spring-boot:run101102# Python — run worker103uvicorn src.main:app --reload &104python -m src.worker # separate process105106# NestJS — run worker107npm run start:worker # defined in package.json scripts108109# Run Temporal test suite (time-skipping enabled)110# Java: mvn test111# Python: pytest -q112# NestJS: npm test113```114115## Error Handling116117> For retry policy templates and non-retryable error classification per SDK, read `reference/implementation-playbook.md#retry`118119**Activity retry rule:** classify every exception before throwing. Validation errors and business rule violations -> `ApplicationFailure.newNonRetryableFailure()`. Transient network/timeout errors -> retryable (default).120121**Workflow failure rule:** workflows do not catch activity exceptions unless implementing compensation. Let Temporal's retry engine handle transient failures. Only catch `ActivityFailure` when running saga compensations.122123**Idempotency rule:** every activity MUST be safe to call N times. Use idempotency keys, upsert patterns, and check-then-act with unique constraints. Verify with: "If this activity runs twice with the same input, is the final state identical?"124125## Post-Code Review126127After writing Temporal workflow code, dispatch these reviewer agents:128- `architect-review` — workflow boundaries, saga completeness, entity lifecycle correctness129- `security-reviewer` — activity input validation, no secrets in workflow state, payload size limits (2MB)