Skip section navigation

Relay / fictional worked example

Relay behavioural contracts

On this page

Interfaces are only useful context boundaries when they define behaviour, including failure behaviour. These contracts are normative for the fictional example; the runnable demonstration implements only the intake subset.

Request record

FieldMeaningInvariant
idOpaque request identifierStable after creation; no meaning inferred from its format
sourceSubmission source nameNon-empty string
external_idIdentifier assigned by that sourceUnique within the source for this logical submission
site_idSite associated with the requestNon-empty; authoritative tenancy checks required in production
summaryReporter-entered short descriptionNon-empty after trimming
statusCurrent request stateOne of new, assigned, resolved
assignee_idCurrent ownernull until assigned
versionOptimistic record versionPositive integer; begins at 1

The example JSON Schema lives at ../../04-executable-example/contracts/request.schema.json.

RequestStore.create_if_absent

Inputs: source, external_id, site_id, summary.

Expected results:

  1. New key: returns the created Request and created=true.
  2. Replay, same key and same canonical input: returns the original Request and created=false, without changing fields or version.
  3. Replay, same key but changed input: raises DuplicatePayloadConflict; must not replace or merge the original.
  4. Invalid input: raises ValidationError, no record is written.

Idempotency key is exactly (source, external_id) in the teaching example. This is not fuzzy deduplication. Two reports with the same text but different external IDs are distinct.

Important subtlety

If external identifiers are unique only within a tenant, the correct production key may be (tenant_id, source, external_id). The example assumes source namespaces the identifier across the store. That assumption requires explicit validation in a real integration; do not silently port it to a multi-tenant release.

RequestIntake.submit

The integration calls the store and emits RequestCreated to the audit sink only when created=true. On a replay, the audit event is not duplicated. On a conflicting duplicate or validation failure, no creation event is emitted.

A real application must consider what happens if writing the request succeeds but recording the event fails. Possible approaches include a transactional outbox or idempotent retry. The in-memory example is not transactionally durable; this is a release-blocking design decision for a production adapter.

AssignmentWorkflow.assign (design target, not included in demo code)

Inputs: request ID, authorised actor, assignee ID, expected version.

Expected behaviour:

  • Reject if actor lacks permission for that request’s site or tenant.
  • Reject if version no longer matches; never silently overwrite another assignment.
  • In the initial version, allow transition from new to assigned only; reassignment and reopening require separate design.
  • Record RequestAssigned with before/after state and actor.
  • Request a notification, but do not conflate external notification delivery with a committed state change.

No implementation of this design target is claimed in the runnable demo.

Error contract

ErrorMeaningHandling intent
ValidationErrorRequired input is invalidSurface correction to caller; no side effects
DuplicatePayloadConflictSame external key used for different payloadEscalate or reconcile with upstream source; never overwrite
NotFoundRequest ID does not existCaller handles known missing state
VersionConflictConcurrent update/version mismatchRefresh and retry only under an agreed policy
PermissionDeniedCaller lacks rightsNo disclosure of restricted request data

The last three are part of the intended overall design; they are not implemented by the intake teaching slice.

Proving contracts

The runnable tests cover input validation, replay, conflicting duplicates, audit emission and independent submissions. Additional contract tests would be required for persistence, concurrency, multitenancy, recovery and notification delivery.

The definition of ‘done’ is not ‘method exists’. It is ‘the agreed externally observable guarantees have evidence’.

Consulting

Need help with the work?

We can review a design, help set up an AI-assisted workflow or work with your team on implementation.