Functional exit conditions
Candidate exit conditions for the Functional type. See the catalog overview for how to adopt these.
API contract conformance
| Exit condition | What it checks |
|---|---|
|
Every endpoint response body validates against its published OpenAPI/JSON Schema definition with no extra or missing required fields. |
|
Requests that violate the declared request schema are rejected rather than silently coerced or partially applied. |
|
The endpoint returns the |
|
Every field marked required in the contract is always present and non-null in successful responses. |
|
Each response field carries the JSON type declared in the contract (no string-for-number or number-for-string drift). |
|
Fields typed as enums only ever emit values from the documented enumeration set. |
|
Responses contain no fields absent from the contract, preventing accidental leakage of internal state. |
|
gRPC responses deserialize cleanly against the compiled |
|
Documented request/response examples in the contract validate against their own schemas. |
HTTP endpoint semantics
| Exit condition | What it checks |
|---|---|
|
Each endpoint returns the semantically correct status code for the outcome (200/201/204/4xx/5xx) rather than a generic 200. |
|
Resource-creating requests return |
|
Deleting an existing resource returns |
|
|
|
Unsupported HTTP methods on a route return |
|
Requests to undefined paths return |
|
|
|
Documented redirects return the correct 3xx code and a resolvable |
|
Each Akka HTTP endpoint method is reachable at its declared path and binds path/query parameters as specified. |
Error semantics
| Exit condition | What it checks |
|---|---|
|
Error responses return a consistent machine-readable shape (e.g. RFC 9457 problem+json) rather than free-form text. |
|
Caller-caused failures (bad input, missing resource, conflict) map to 4xx, never 5xx. |
|
Genuine server faults map to 5xx and never masquerade as a 2xx success. |
|
Validation errors identify the offending field and reason so a client can correct the request. |
|
Error responses never expose stack traces, internal class names, or SQL to the caller. |
|
Operations that violate a uniqueness or state precondition return |
|
Syntactically valid but semantically invalid payloads return |
|
Application error codes are stable identifiers that do not change wording-to-wording across releases. |
|
Batch operations report per-item success/failure rather than failing or succeeding as an opaque whole. |
Input validation and output behavior
| Exit condition | What it checks |
|---|---|
|
Minimum, maximum, and zero-length inputs produce the specified result rather than an unhandled error. |
|
Omitting a required input field is rejected with a validation error, not defaulted silently. |
|
Malformed payloads (invalid JSON, wrong encoding) are rejected with |
|
Inputs exceeding documented length limits are rejected rather than truncated or stored oversized. |
|
Out-of-range numeric inputs are rejected against the documented min/max bounds. |
|
Non-ASCII and multi-byte characters round-trip through the endpoint without corruption. |
|
The API distinguishes an explicit |
|
Given identical inputs and state, the endpoint returns an equivalent output (field values and ordering as specified). |
|
Optional inputs left unset receive the documented default values in the stored and returned representation. |
Idempotency and concurrency
| Exit condition | What it checks |
|---|---|
|
Replaying a mutating request with the same idempotency key produces one effect and returns the original result. |
|
Repeated identical |
|
Conflicting concurrent updates are detected via version/ETag and the loser receives |
|
|
|
A retried create does not produce duplicate entities when an idempotency key or natural key is supplied. |
|
Event-sourced command handling yields the same resulting state regardless of at-least-once delivery retries. |
|
A consumer reprocessing a redelivered message produces no duplicate or divergent downstream effect. |
|
A command either fully applies its state change and events or applies none of it (no partial mutation). |
Pagination, filtering, and sorting
| Exit condition | What it checks |
|---|---|
|
Paging through a collection returns every item exactly once with no gaps or duplicates across pages. |
|
Requested page sizes are clamped to a documented maximum rather than allowing unbounded result sets. |
|
Cursor/keyset pagination remains consistent under concurrent inserts, avoiding skipped or repeated rows. |
|
Results are returned in the requested and documented sort order, with a defined tiebreaker for equal keys. |
|
Filter parameters return exactly the subset matching the documented predicate, including empty results when nothing matches. |
|
Unknown filter or sort fields are rejected with a |
|
Any returned total/count reflects the true number of matching items under the active filter. |
|
An empty collection returns a valid empty list with |
|
Each Akka View query returns the rows matching its declared selection criteria and projection. |
Business-rule correctness
| Exit condition | What it checks |
|---|---|
|
Documented domain invariants (e.g. balance never negative) hold after every accepted command. |
|
Only the transitions defined in the workflow/entity state model are permitted; illegal transitions are rejected. |
|
Operations requiring a precondition (e.g. approved before shipped) fail cleanly when the precondition is unmet. |
|
Derived values (totals, taxes, prorations, rounding) match the specified formula to the required precision. |
|
Business-level duplicates (same order, same email) are rejected per the uniqueness rule. |
|
Actions disallowed for the caller’s role are refused with |
|
Operations exceeding a documented quota or rate limit are refused with the specified status. |
|
A successful command emits the specified downstream effect (event, notification, timer) exactly as required. |
|
Compensating actions (cancel, refund, rollback) return the entity to the specified prior state. |
Agents, workflows, and asynchronous behavior
| Exit condition | What it checks |
|---|---|
|
An agent returning structured output produces a payload that validates against its declared response schema. |
|
The agent calls the specified tool/function with correctly typed arguments for the documented scenario. |
|
The agent’s answer is derived from the supplied context/retrieval rather than fabricating unsupported facts. |
|
A started workflow reaches its terminal success state under nominal inputs within the defined step sequence. |
|
A failing workflow step triggers the defined compensation and leaves no partially committed state. |
|
A workflow interrupted mid-flight resumes from its last durable step rather than restarting or dropping work. |
|
Scheduled timers/durable timers fire the specified action at or after their due time. |
|
A consumer subscribed to an entity’s events applies the documented reaction for each event type it handles. |
|
Messages that exhaust retries are routed to the defined failure path rather than being silently dropped. |
Versioning and backward compatibility
| Exit condition | What it checks |
|---|---|
|
A new API version does not remove or rename fields that existing clients depend on. |
|
Minor-version schema changes are additive, with new fields optional and defaulted for older clients. |
|
Requests shaped for the previous contract version continue to succeed against the current deployment. |
|
Older persisted events deserialize under the current event schema via the defined upcasting/migration path. |
|
Stored entity state written by a prior version is readable by the current version without data loss. |
|
Newly added required-by-logic fields receive a safe default when reading records that predate them. |
|
Endpoints marked deprecated remain functional and advertise their deprecation per the documented policy. |
|
The service honors the requested API version (path/header) and returns the matching contract behavior. |
|
Clients and consumers tolerate newly added enum values without crashing on the unknown case. |