PartnerRelationship — Lifecycle State Machine
Generated from
specification/state-machines/partner-relationship.md. Edit the canonical source file, not this page.
RFC 2119 normative language applies throughout.
1. States
Section titled “1. States”| State | Meaning |
|---|---|
draft |
Relationship request assembled but not yet submitted to the accepting organization. Visible only to the requesting organization. |
requested |
Submission sent; awaiting acceptance by the accepting organization. Both organizations can observe the relationship. |
active |
Both sides have authorized the relationship. Capacity and load data sharing is enabled within the granted scopes. |
suspended |
Temporarily deactivated. Data sharing is disabled; existing matched offers and requests are unaffected but no new sharing occurs. |
terminated |
Permanently closed. Data sharing has ended. The record is retained for audit. |
Terminal states: terminated
2. State-Transition Table
Section titled “2. State-Transition Table”| From State | Command | To State | Notes |
|---|---|---|---|
| (none) | POST /partner-relationships |
draft |
Initiating organization creates the relationship object. |
draft |
submit (implicit on first POST /partner-relationships/{id}/request) |
requested |
Requesting organization submits to accepting org. |
requested |
accept (POST /partner-relationships/{id}/accept) |
active |
Accepting organization approves. |
requested |
reject (POST /partner-relationships/{id}/reject) |
terminated |
Accepting organization declines. |
requested |
withdraw |
terminated |
Requesting organization withdraws before acceptance. |
active |
suspend (POST /partner-relationships/{id}/suspend) |
suspended |
Either authorized organization suspends. |
active |
terminate (POST /partner-relationships/{id}/terminate) |
terminated |
Either authorized organization terminates. |
suspended |
reactivate (POST /partner-relationships/{id}/reactivate) |
active |
The organization that suspended it reactivates. |
suspended |
terminate |
terminated |
Either authorized organization terminates while suspended. |
Invalid Transitions
Section titled “Invalid Transitions”Any command applied to a state not listed in the “From State” column above MUST return 422 Unprocessable Entity with error type urn:freyt:protocol:error:invalid-state-transition.
3. Preconditions
Section titled “3. Preconditions”submit (draft → requested)
Section titled “submit (draft → requested)”- Authorization: Actor belongs to
requestingOrganizationId. - Scope required:
relationships:manage - Relationship state: N/A (creating new).
- Version check: None required for initial submission.
- Policy check:
acceptingOrganizationIdmust be a known organization in the registry.
accept (requested → active)
Section titled “accept (requested → active)”- Authorization: Actor belongs to
acceptingOrganizationId. - Scope required:
relationships:manage - Version check:
If-Matchheader MUST match currentresourceVersion. - Policy check: Accepting organization’s policy must not prohibit the requested scopes.
reject (requested → terminated)
Section titled “reject (requested → terminated)”- Authorization: Actor belongs to
acceptingOrganizationId. - Scope required:
relationships:manage - Version check:
If-Matchheader MUST match currentresourceVersion.
withdraw (requested → terminated)
Section titled “withdraw (requested → terminated)”- Authorization: Actor belongs to
requestingOrganizationId. - Scope required:
relationships:manage - Version check:
If-Matchheader MUST match currentresourceVersion.
suspend (active → suspended)
Section titled “suspend (active → suspended)”- Authorization: Actor belongs to either
requestingOrganizationIdoracceptingOrganizationId. - Scope required:
relationships:manage - Version check:
If-Matchheader MUST match currentresourceVersion. - Policy check: Suspension reason MUST be provided.
terminate (active | suspended → terminated)
Section titled “terminate (active | suspended → terminated)”- Authorization: Actor belongs to either participating organization.
- Scope required:
relationships:manage - Version check:
If-Matchheader MUST match currentresourceVersion. - Policy check: Termination reason MUST be provided.
reactivate (suspended → active)
Section titled “reactivate (suspended → active)”- Authorization: Actor belongs to the organization that issued the
suspendcommand. - Scope required:
relationships:manage - Version check:
If-Matchheader MUST match currentresourceVersion. - Policy check: If
effectiveUntilhas passed, reactivation MUST be rejected.
4. Postconditions
Section titled “4. Postconditions”| Command | Postconditions |
|---|---|
submit |
status set to requested; submittedAt timestamp recorded; event pcx.partner-relationship.requested.v1 emitted. |
accept |
status set to active; effectiveFrom set to current time if not pre-set; resourceVersion incremented; event pcx.partner-relationship.activated.v1 emitted. |
reject |
status set to terminated; terminatedAt recorded; rejection reason stored; event pcx.partner-relationship.terminated.v1 emitted. |
withdraw |
status set to terminated; terminatedAt recorded; withdrawal reason stored; event emitted. |
suspend |
status set to suspended; suspendedAt recorded; suspension reason stored; resourceVersion incremented; event pcx.partner-relationship.suspended.v1 emitted. Data sharing ceases immediately. |
terminate |
status set to terminated; terminatedAt recorded; resourceVersion incremented; event pcx.partner-relationship.terminated.v1 emitted. Data sharing ceases immediately. |
reactivate |
status set to active; reactivatedAt recorded; resourceVersion incremented; event pcx.partner-relationship.reactivated.v1 emitted. |
5. Concurrency Rules
Section titled “5. Concurrency Rules”- All state-changing commands require
If-Matchwith the current ETag. - Concurrent
suspendandterminateon the same resource: the first writer wins; the second receives409 Conflictwithstale-resource-version. - Concurrent
acceptandwithdraw: whichever commits first wins; the other receives409. - The server MUST apply transitions atomically. A transition MUST NOT be partially committed.
6. Invariants
Section titled “6. Invariants”- Uniqueness: At most one non-terminated
PartnerRelationshipmay exist between a given(requestingOrganizationId, acceptingOrganizationId)pair at any time. - Audit retention: Records in
terminatedstate MUST be retained for the period defined inretentionPolicyRefand MUST NOT be physically deleted. - Scope containment:
scopesin anactiverelationship must be a subset of scopes granted by both organizations’ policies. - Effective period: If
effectiveUntilis set and the current time exceeds it, the relationship behaves assuspendedfor authorization checks even ifstatusisactive. A background job transitions it toterminated. - No resurrection: A
terminatedrelationship MUST NOT be transitioned to any other state. A new relationship may be created to replace it. - Visibility isolation: A
draftrelationship MUST NOT be visible to theacceptingOrganizationIduntilstatusisrequested.