| ← Back to Design Docs | ← Documentation Home |
Responsibility
ExecutionStarted, then either ExecutionSucceeded or ExecutionFailed.Interfaces
Identity & Context
IDs Generated:
IDs Received (from StartExecution command):
Pattern:
```typescript ignore // Receive IDs from command const { tenantId, serviceCallId, requestSpec } = command
// Construct domain event (validated via Schema) const event = new ExecutionStarted({ tenantId, serviceCallId, startedAt: now, // DateTime.Utc })
// Publish with MessageMetadata Context yield * eventBus.publishExecutionStarted(event).pipe( Effect.provideService(MessageMetadata, { correlationId: command.correlationId, // Forward from command causationId: Option.some(commandEnvelopeId), // StartExecution envelope }), )
**Pattern** (execution-event-bus.adapter.ts - future implementation):
```typescript ignore
// Adapter extracts MessageMetadata from Context
const metadata = yield * MessageMetadata
// Generate envelope ID (UUID v7)
const envelopeId = yield * EnvelopeId.makeUUID7()
// Construct envelope via Schema class
const envelope: MessageEnvelope.Type = new MessageEnvelope({
id: envelopeId,
type: event._tag,
payload: event,
tenantId: event.tenantId,
timestampMs: yield * clock.now(),
correlationId: metadata.correlationId,
causationId: metadata.causationId,
aggregateId: Option.some(event.serviceCallId),
})
yield * eventBus.publish([envelope])
Rationale: Execution is stateless and doesn’t own any aggregates. All IDs flow through from Orchestration via StartExecution command. Adapter generates EnvelopeId (UUID v7) for broker deduplication. Workflow provides MessageMetadata Context, forwarding correlationId from command and setting causationId to command envelope ID. See ADR-0010 for identity generation strategy, ADR-0011 for schema patterns, and ADR-0013 for MessageMetadata Context pattern.
Behavior
– On StartExecution:
Notes
Resolve RequestSpec
Resolve RequestSpec
sequenceDiagram
autonumber
participant EXECUTION as Execution
participant HTTP_CLIENT as HttpClientPort
Note over EXECUTION,HTTP_CLIENT: solid = command/port, dashed = event
link EXECUTION: Doc @ ./execution.md
link HTTP_CLIENT: Port @ ../ports.md#httpclientport
EXECUTION->>HTTP_CLIENT: execute(requestSpec)
Inputs/Outputs Recap
Sequence (StartExecution HTTP Outcome)
sequenceDiagram
autonumber
participant ORCHESTRATION as Orchestration
participant EXECUTION as Execution
participant HTTP_CLIENT as HttpClientPort
participant EXTERNAL_SERVICE as External Service
Note over ORCHESTRATION,EXECUTION: solid = command/port, dashed = event
link ORCHESTRATION: Doc @ ./orchestration.md
link EXECUTION: Doc @ ./execution.md
ORCHESTRATION->>EXECUTION: StartExecution [command]
EXECUTION-->>ORCHESTRATION: ExecutionStarted [event]
EXECUTION->>HTTP_CLIENT: execute(requestSpec)
HTTP_CLIENT->>EXTERNAL_SERVICE: request
alt success
EXTERNAL_SERVICE-->>HTTP_CLIENT: response(status, headers, body)
HTTP_CLIENT-->>EXECUTION: ok(statusCode, headers, bodySnippet, durationMs)
EXECUTION-->>ORCHESTRATION: ExecutionSucceeded [event]
else failure/timeout
EXTERNAL_SERVICE--x HTTP_CLIENT: error/timeout
HTTP_CLIENT-->>EXECUTION: fail(kind, statusCode?, message, responseSnippet?, durationMs)
EXECUTION-->>ORCHESTRATION: ExecutionFailed [event]
end
State (Attempt lifecycle)
stateDiagram-v2
[*] --> Starting: StartExecution received
Starting --> Succeeded: Response ok
Starting --> Failed: Timeout/Network/HttpError
Succeeded --> [*]
Failed --> [*]
Messages