TA Workflow
Version 0.2
Introduction
This Technical Agreement (TA) specifies a standards-based way to send a referral, order, or transfer from one care organization to another and to keep track of it until the work is done. It is built on COW IG and TA Notifications, and brings existing, separately developed Dutch agreements for this same problem together under a single, shared specification.
Limitations of this document
This document is a working version. It has the following limitations.
-
Sections and decisions are missing. Some sections are still to be filled in, and some decisions are still to be made. The points are the following; each refers to the section in which it is described:
-
Whether a code system is defined for the reason not selected: see Reason for cancelling a non-selected candidate.
-
How a Fulfiller establishes the resources of a dataset: see Retrieving the resources of a dataset.
-
Whether the rules are worked out for request types other than ServiceRequest: see Request types other than ServiceRequest.
-
Whether the extra code request-fulfillment is kept, and how a Fulfiller recognizes which pattern applies: see Optional support for the code request-fulfillment and Recognizing the pattern that applies.
-
Whether the step from in-progress to failed is allowed after the Fulfiller has accepted a Cancellation Request Task: see After an accepted Cancellation Request.
-
The requirements and rules for the maintenance when healthcare services change: see Changes to healthcare services.
-
Whether the BSN is carried in Task.for.identifier, and from which moment: see Patient context and readability.
-
The consequences of the readability rule are not yet worked out. A candidate cannot read the Request before it is selected (see Patient context and readability). Sections that assume otherwise have not yet been adapted: Routing by the Fulfiller, Reason for cancelling a non-selected candidate, the options in Recognizing the pattern that applies, and Bidding, including the meaning of accepting.
-
Artefacts and implementation guides are not yet available. This TA relies on artefacts and implementation guides that are not yet available, such as the formal definitions of the profiles, the search parameters and the CapabilityStatement, the code system and value set of the optional extra code, and the specifications of GF Addressing and TA I&A&A. Their content is therefore described in this document.
-
There is no list of changes. This document has no section on the changes since the previous version, because there are far too many.
-
This version is verbose. Requirements of the underlying specifications are repeated, also where this is not strictly needed. They are separated from the requirements that this TA specifies, so that they can be removed later.
Context
Dutch healthcare organizations already exchange referrals, orders, and transfers between systems today, but they do so using at least two separately developed, incompatible mechanisms, and neither fully supports exchanging the status of that work once it is underway. The Technical Agreement Exchanging FHIR Data using a generic Notified Pull mechanism (TA NP) specifies one such mechanism, built for the exchange of the BgZ during a patient referral. The Nuts eOverdracht Bolt specifies another, built independently, on a similar timeline, for the nursing handover referral.
Two national specifications, developed independently for closely related problems, cannot both remain the reference every new implementer is pointed to — harmonizing them is worthwhile. Doing so depends on two things being settled at the technical level:
-
TA Notifications specifies the standardized Subscription and notification mechanism by which a party learns that a resource it does not own has changed.
-
The forthcoming TA I&A&A specifies how the parties to an exchange identify, authenticate, and authorize one another.
Together, these give a harmonized specification the technical building blocks that neither TA NP nor eOverdracht had available when each defined its own mechanism.
These two agreements are not enough on their own. TA NP and eOverdracht each model the clinical workflow itself in its own way: a system built to one specification still cannot exchange a referral with a system built to the other, and a healthcare organization operating across both domains still needs two separate implementations to do what is, underneath, the same kind of work. The two domains are also not always separate processes: when an admitted patient moves from one hospital to another, the medical handover (TA NP) and the nursing handover (eOverdracht) belong to the same transfer and must be able to run as one integrated flow, yet each specification covers only its own half. Left alone, the divergence between the two specifications would only widen as each specification continues to evolve independently. Harmonizing the workflow model itself — not just the transport it travels over — is what allows an organization to build and maintain one implementation instead of two.
It also does something neither original specification could, precisely because each was written for one use case at a time: a harmonized model is general enough that referral, order, and transfer are simply particular instances of it, so that the next use case this ecosystem needs is described as a profile of something that already exists, rather than specified again from first principles.
This Technical Agreement is that model. It specifies, in one place, a standards-based way to exchange clinical workflow status for orders, referrals, and transfers, so that the agreements currently expressed via TA NP and via eOverdracht can each be specified and implemented as a profile of it.
Scope
In scope
-
Exchanging clinical workflow status between a Placer and a Fulfiller.
-
Hosting, creating, and updating a Coordination Task at the Placer, and the FHIR profile constraining it.
-
The standing Subscription and notification mechanism informing a Fulfiller of relevant Task changes.
-
The payload mode of the notification, and the requirements on the ids of Tasks and Subscriptions.
-
Sharing content beyond the standard dataset, in Task.input.
-
The Multiple Fulfillers Pattern, including bidding by candidates, and the simpler case of a single, already-known Fulfiller.
-
Conformance to TA Routing.
-
Conformance to GF Addressing, independently of TA Routing.
Out of scope
-
Identification, authentication, and authorization of the parties — the subject of the forthcoming TA I&A&A.
-
How a Placer weighs the responses of the candidates and decides which one to select among multiple Fulfillers. Responses of the candidates such as accepting and bidding, and the recording of the decision, are in scope.
-
Whether the BSN is carried on the Coordination Task, and from which moment (see Patient context and readability).
Vocabulary
|
Term |
Definition |
|
Placer |
The party that authorizes and initiates a Request. |
|
Fulfiller |
The party expected to carry out the Request. |
|
Request |
The FHIR resource representing what is being asked for, such as a ServiceRequest. COW IG also allows a DeviceRequest, MedicationRequest, NutritionOrder, SupplyRequest or VisionPrescription. This TA does not limit the Request to a ServiceRequest; the rules on specific elements (code, instantiatesCanonical, performer and subject) are written for ServiceRequest (see Request types other than ServiceRequest). |
|
The code of a ServiceRequest. In this TA it identifies the standard dataset for the referral, and it states the type of service that is requested (TA Routing). |
|
|
The reference of a ServiceRequest to an ActivityDefinition or a PlanDefinition that describes how the service is requested and what it requires. |
|
|
The party that is to carry out the requested service. It remains unset while more than one Fulfiller is under consideration. |
|
|
Standard dataset |
The baseline set of information a referral requires, as identified by the Request (see Resource Definitions → Request). |
|
Coordination Task |
A profile of the FHIR Task resource that tracks one Fulfiller's handling of one Request from start to finish. |
|
Cancellation Request Task |
A profile of the FHIR Task resource used to ask for work that is already under way to be stopped. |
|
Bidding task |
A Coordination Task during the phase in which several candidates are invited to accept and, where the Placer wants it, to bid. It is not a separate kind of Task: the Coordination Task of the selected candidate continues after the bidding. |
|
Bid |
A Fulfiller's response to a bidding task that describes what it would offer, such as its availability, a more specific service, or the person who would perform it. |
|
Notified Pull |
Delivery via notification, followed by the Fulfiller retrieving the Task itself. |
|
Direct Write |
A Fulfiller's authenticated write to the Placer-hosted Coordination Task, observed by the Placer. |
|
The FHIR resource Task.owner resolves to, per TA Routing. |
|
|
The FHIR resource Task.location resolves to, per TA Routing. |
Basis of this TA
Base Specifications
|
Specification |
Role |
|
COW IG (HL7 Clinical Order Workflows Implementation Guide), version 1.0.0-ballot, FHIR R4 package hl7.fhir.uv.cow.r4, build of 2026-04-24 |
Base resource and workflow model. |
|
FHIR R4 (v4.0.1) |
Base standard for resources, interactions and search: hl7.org/fhir/R4. |
|
TA Notifications |
Base notification mechanism. |
|
Conformance target: internal routing of a referral once received. The specification is referred to by the Twiin page: nl-generic-functions-ig/routing. |
|
|
GF Addressing (forthcoming; no canonical URL available) |
Conformance target: registration and discovery of HealthcareService/Location. In scope independently of TA Routing. |
|
TA I&A&A (forthcoming; no canonical URL available) |
Outside the scope of this TA; covers identification, authentication, authorization. |
|
Evidence for design choices (e.g., Task at Placer); not a base specification. |
|
|
Evidence for design choices (e.g., Multiple Fulfillers); not a base specification. |
Relationship to COW IG
COW IG was chosen as the base resource and workflow model for four reasons: it is generic enough to cover order, referral, and transfer workflows alike, rather than one at a time; complete enough that this TA needs no invented extension to address the core problem; pitched at the right level of detail to be profiled rather than rebuilt; and an international standard, keeping this TA aligned with an ecosystem wider than the Netherlands alone.
COW IG cannot serve as a technical agreement on its own. Its generality is deliberate: it leaves open many of the choices two systems must agree on to actually interoperate, and implementers left free to make those choices differently produce systems that are each individually COW-conformant yet unable to exchange anything with one another.
This TA is a profile of COW IG, not an extension of it. It makes binding choices among the options COW IG already permits — which hosting pattern applies, which values Task.code takes, how cancellation is realized — so that independently built systems converge on one behavior. It does not add resource types, elements, or mechanisms beyond what COW IG itself defines, apart from, optionally, one code for Task.code (see Optional support for the code request-fulfillment). Where this TA is silent, COW IG's own guidance applies unmodified.
Design Choices
This section states, for each major choice this TA makes within COW IG's model, why it was made this way rather than left to individual implementers.
Task at Placer, not Task at Fulfiller
COW IG names two patterns for where the Coordination Task is hosted. This TA fixes it at the Placer. TA NP's own persistent, status-bearing resource (the Workflow Task) is already hosted at the Sending System — the Placer, in COW IG's terms — and eOverdracht's Task is likewise hosted at the bronhouder (the source holder), for the same reason its own specification gives: keeping data at the source. Both existing agreements, developed independently of each other and of COW IG, already converge on this hosting choice.
The Multiple Fulfillers Pattern is adopted, not only the simpler single-performer case
Some use cases need to offer one patient to several candidate organizations in parallel, for example a transfer of care. A specification that covered only a single performer would leave those use cases out, so this TA adopts the Multiple Fulfillers Pattern as COW IG describes it.
The pattern has two further uses:
-
Bidding. Candidates can do more than accept: they can describe what they would offer, so that the Placer can compare them before one is selected (see Bidding).
-
Negotiation with one candidate. A genuine negotiation before a referral is finalized can be useful even with exactly one Fulfiller under consideration. Many single-Fulfiller referrals need no negotiation at all (see Single Fulfiller Pattern).
Task.owner and Task.location resolve to HealthcareService and Location, not Organization
Notifications are addressed to the people who must act on them. An organization is too coarse for that, which is why TA Routing works with services and locations. This TA follows TA Routing:
-
Task.owner identifies the HealthcareService that is asked to carry out the work.
-
Task.location identifies the Location at which the work is to be carried out. A HealthcareService can be performed at several physical Locations, and a Placer can request care at a specific one. (TA Routing)
The Subscription follows the service, not the organization:
-
A Subscription is established per HealthcareService. It has one notification endpoint, and in TA Routing that endpoint belongs to the service.
-
This TA cannot assume that all services of a Fulfiller share one endpoint. A Subscription per service works in every case; a Subscription for the whole organization would not.
-
Task.location plays no part in the Subscription, and the notification endpoint is that of the HealthcareService, not of the Location.
The SubscriptionTopic triggers on create and update, not create alone
eOverdracht notifies on every Task change without exception, and TA NP's own mechanisms for both dataset updates and cancellation are update-triggered, not creation events. A topic that only covered create could not be specified as a profile of either.
Task.groupIdentifier is not used to link Tasks to the same Request
TA NP and eOverdracht each attach their own meaning to this element, and those meanings are incompatible with each other, so this TA does not add a further use to it. Linking Tasks to a Request is also unnecessary: Task.focus is mandatory in the profile of this TA, so Coordination Tasks that compete for the same Request can already be recognized by their shared reference to it.
The notification is id-only
The Task is addressed to a single receiver, and for such a resource TA Notifications says that id-only should be used in preference to empty. A full-resource notification would put a Task, which refers to a patient, into the notification itself, which is a disclosure of its own.
Actors
The obligations of each actor are listed in two groups. The first group follows from COW IG and is repeated here for completeness; this TA adds nothing to it. The second group is specified by this TA: a choice or an addition of this TA, which may build on another specification named in parentheses.
Placer
The Placer:
Follows from COW IG
-
SHALL create the Request, hosted on its own FHIR server, and is the only party that modifies the Request directly.
-
SHALL create a Coordination Task that refers to the Request, for the Fulfiller that is to carry it out.
-
MAY cancel the Coordination Task before the work has started, and SHALL use a Cancellation Request Task to stop work that has started (see Cancellation (Before in-progress) and Cancellation Request (After in-progress)).
-
SHALL, whenever a Coordination Task reaches an end status (completed, failed, rejected, cancelled or entered-in-error), decide what happens to the Request and update Request.status where required.
-
With several candidates, SHALL select one and cancel the Coordination Tasks of the others (see Multiple Fulfillers Pattern).
Specified by this TA
-
SHALL host the Coordination Task on its own FHIR server (COW IG allows either hosting pattern; see Design Choices).
-
SHALL make sure that a standing Subscription exists for each HealthcareService of a Fulfiller that receives Tasks, by creating it out-of-band or by accepting it in-band (see Subscription). (TA Notifications)
-
SHALL grant the Fulfiller access to the Coordination Task for which the Fulfiller is accountable, limited to the elements that the Fulfiller may change (see Resource Definitions → Coordination Task → Write access), and SHALL record the URA of the accountable organization when it creates the Task (see Coordination Task).
-
SHALL NOT create a Coordination Task, or create or accept a Subscription, for an owner identifier that does not resolve to exactly one HealthcareService (see Coordination Task and Subscription).
-
SHALL act on the end of a Coordination Task as specified in Handling the End of a Coordination Task.
-
MAY invite bids by creating a bidding task for each candidate (see Bidding).
Fulfiller
The Fulfiller:
Follows from COW IG
-
SHALL update the Coordination Task on the server of the Placer to report the progress of the work.
-
MAY reject the Coordination Task, with a statusReason.
-
MAY set the Coordination Task to failed when it can no longer carry out the work (see Cancellation by the Fulfiller).
-
SHALL accept or reject a Cancellation Request Task.
-
MAY ask the Placer to cancel the Request itself (see Cancellation by the Fulfiller).
Specified by this TA
-
SHALL authenticate to the Placer on every read or write of the Coordination Task.
-
SHALL make its updates as a Direct Write, changing only status, businessStatus, statusReason and output of the Coordination Task, and making them version-aware (see Write access).
-
SHALL support the ActivityDefinitions and PlanDefinitions that its HealthcareService lists (see Routing by the Fulfiller). (TA Routing)
-
MAY respond to a bidding task with a bid (see Bidding).
Resource Definitions
Profiles
Task profiles
This TA uses the FHIR Task resource, a general-purpose resource for tracking a piece of work. A FHIR profile narrows a general resource for a specific purpose: it states which elements must be filled in, which values are allowed, and how elements are to be used. This TA uses two profiles of Task:
-
The Coordination Task follows one Fulfiller's handling of one Request, from the moment the Request is sent until the work ends. It refers to the Request, names the Fulfiller asked to carry it out, and carries the status of the work. The Placer and the Fulfiller both use it to see where the work stands.
-
The Cancellation Request Task is used by the Placer to ask the Fulfiller to stop work that has already started. It refers to the Coordination Task to be cancelled, and the Fulfiller answers by accepting or rejecting it.
Both profiles build on the profiles of the same names in COW IG, which define the minimum expectations for these Tasks. This TA adds further requirements, described in the sections below.
The formal definitions of these two profiles, of the search parameters and of the CapabilityStatement of the Placer's server will be linked here. They are not yet available. Until they are, the requirements in this Resource Definitions section apply.
Preliminary description of the profiles
The tables below describe what the two profiles will contain. This description is preliminary: the formal definitions are not yet available (see above). Elements that are not listed are not constrained by this TA. The column R4 gives the base definition in FHIR R4, and the column COW IG gives the profile of the same name in COW IG. Several entries depend on decisions that are still open (see Limitations of this document). Until the formal definitions are available, these tables are the normative description of the restrictions on the elements.
Coordination Task
|
Element |
R4 |
COW IG |
This TA |
Written by |
|
id |
server-assigned |
not constrained |
stable, opaque and unpredictable (see Identifiers of Tasks and Subscriptions) |
Placer |
|
0..* |
1.. (must support) |
1.. |
Placer |
|
|
1..1; 12 codes |
not constrained |
requested at creation; afterwards the R4 state machine and the meaning that COW IG gives to each status (see Status of the Coordination Task) |
Fulfiller; Placer for cancelled, before in-progress |
|
|
0..1 CodeableConcept |
not constrained |
SHOULD be populated when the status is rejected or cancelled; not selected MUST be used when the Placer cancels a non-selected candidate (see Multiple Fulfillers Pattern); it has no code system yet (see Reason for cancelling a non-selected candidate) |
Fulfiller (reason for rejecting); Placer (not selected) |
|
|
0..1 |
must support; example binding to the ValueSet of COW IG |
SHOULD be populated; selected is reserved for the Placer and is taken from http://fhir.nl/CodeSystem/nl-cow-business-status (Nuts IG) |
Fulfiller; Placer for selected |
|
|
1..1; required binding |
not constrained |
fixed to order |
Placer |
|
|
0..1; example binding |
1.. (must support) |
1..; fulfill (see Optional support for the code request-fulfillment) |
Placer |
|
|
0..1; any resource |
1.. (must support) |
1..; refers to the Request |
Placer |
|
|
0..1 |
not constrained |
not used to indicate that Coordination Tasks belong to the same Request |
Placer |
|
|
0..1; any resource |
not constrained |
not specified; open |
Placer |
|
|
0..1 |
not constrained |
identifies the Placer by Reference.identifier (the URA for an Organization); a literal Reference.reference MAY be added alongside |
Placer |
|
|
0..1; includes HealthcareService |
not constrained |
Reference.type is HealthcareService; the resource is a HealthcareService as profiled by TA Routing, not merely an Organization; identifier from the AssignedId slice of that profile, with the URA-identified Organization as assigner; a literal Reference.reference MAY be added alongside (TA Routing) |
Placer |
|
|
0..1 |
not constrained |
SHOULD be supported; the Location profile of TA Routing, by Reference.identifier |
Placer |
|
|
0..* |
not constrained |
SHOULD be supported; also used for a bid |
Fulfiller |
|
|
0..* |
not constrained |
the Placer MAY share content beyond the standard dataset (see Sharing additional content) |
Placer |
The Fulfiller may change only status, businessStatus, statusReason and output (see Write access).
Cancellation Request Task
|
Element |
R4 |
COW IG |
This TA |
Written by |
|
id |
server-assigned |
not constrained |
stable, opaque and unpredictable (see Identifiers of Tasks and Subscriptions) |
Placer |
|
1..1 |
not constrained |
requested at creation; afterwards accepted or rejected, as a Direct Write by the Fulfiller |
Placer at creation; Fulfiller afterwards |
|
|
0..1 |
not constrained |
not further specified |
Fulfiller |
|
|
0..1; example binding |
pattern abort |
fixed to abort |
Placer |
|
|
1..1; required binding |
not constrained |
fixed to order |
Placer |
|
|
0..1; any resource |
1.. ; a Request or the Coordination Task |
refers to the Coordination Task to be cancelled |
Placer |
|
|
0..1 |
not constrained |
the same HealthcareService as the Coordination Task, so that the Subscription filter on Task.owner (see Subscription) delivers it as well |
Placer |
The Fulfiller may change only status and statusReason of a Cancellation Request Task.
Rules that a profile cannot express
These rules remain text of this TA, or are declared in the CapabilityStatement of the Placer's server:
-
that exactly one candidate is selected;
-
that ServiceRequest.performer remains unset while more than one Fulfiller is under consideration;
-
that a Cancellation Request Task is created only when the Coordination Task is in-progress;
-
the permitted status changes and who makes them;
-
that writes by the Fulfiller are version-aware;
-
that an owner identifier resolves to exactly one HealthcareService.
Coordination Task
The elements of the Coordination Task are restricted as in the table in Preliminary description of the profiles. The following rules apply in addition.
Follows from COW IG
-
A Coordination Task is created by the Placer for the Fulfiller that is to carry out the Request (see Task Creation).
Specified by this TA
-
The Coordination Task is hosted on the Placer's own FHIR server and is created there via create. (COW IG allows either hosting pattern; see Design Choices.)
-
The Placer MUST NOT create a Coordination Task for an owner identifier that does not resolve to exactly one HealthcareService in the directory data that the Placer uses to select the Fulfiller (see the assumption about GF Addressing under Search parameters).
-
When the Placer creates a Coordination Task, it records the URA of the organization that is accountable for the Task: the organization that provides the HealthcareService it selected as Task.owner. The Placer takes this URA from the directory data at the moment of selection and keeps the record internally; it is not an element of the Task. The Placer applies the same record to the Cancellation Request Task of that Coordination Task. When it decides whether a Fulfiller may read or write a Task, the Placer uses this record and the authentication of the Fulfiller, and MUST NOT use directory data. How the Fulfiller authenticates is the subject of TA I&A&A.
Write access
Follows from FHIR R4
-
An update (PUT) replaces the whole resource.
Specified by this TA
-
The Fulfiller MUST authenticate on every read or write; access is verified per interaction.
-
The Placer MUST grant the Fulfiller access only to the Coordination Tasks for which the Fulfiller is accountable, and within those only to the elements that the Fulfiller may change (see below). The Fulfiller is accountable for a Coordination Task when the URA in its authentication equals the URA that the Placer recorded for that Task when it created it. The Fulfiller may read every element of its own Coordination Task.
-
The Fulfiller MAY change only the elements marked Fulfiller in the column Written by of the table in Preliminary description of the profiles: status, businessStatus, statusReason and output. All other elements are set by the Placer and MUST NOT be changed by the Fulfiller. The Placer sets focus, requester, and owner once, at creation.
-
Within the writable elements, two values are reserved for the Placer: Task.businessStatus selected and Task.statusReason not selected (see Multiple Fulfillers Pattern).
-
The Placer's server MUST check every write by the Fulfiller and reject it if it changes an element other than the ones named above or sets a reserved value.
-
A Fulfiller that uses a full update (PUT) sends the Task with all other elements unchanged.
Concurrent writes
The first three rules below use mechanisms of the RESTful API of FHIR R4 for managing resource contention and for declaring capabilities. Those mechanisms are defined there, and this TA requires their use between the Placer and the Fulfiller. The last rule is an addition of this TA and is not defined by FHIR.
-
A write by the Fulfiller MUST be version-aware. The Fulfiller reads the Coordination Task, takes its version from the ETag, and sends that version in the If-Match header of its update. The Placer's server MUST reject a write on a version that is no longer current with 412 Precondition Failed. The Fulfiller then reads the Task again and decides again. (FHIR R4, Managing Resource Contention and update)
-
The Fulfiller MAY change the Coordination Task with PUT or with PATCH. A PATCH document is a JSON Patch (application/json-patch+json) and is version-aware in the same way. (FHIR R4, PATCH) The Placer's server MUST support JSON Patch.
-
The Placer's server MUST declare the versioning level versioned-update in its CapabilityStatement (see Placer server capabilities). (FHIR R4, CapabilityStatement)
-
The Placer bases its own updates of a Coordination Task on the current version in the same way, so that it does not overwrite a write by the Fulfiller.
Status of the Coordination Task
Follows from COW IG and FHIR R4
-
The statuses are the codes of the TaskStatus code system of FHIR R4, and the transitions follow the typical state machine of FHIR R4 (see the figure below). The diagram has no move from in-progress to cancelled. (FHIR R4)
-
The workflow meaning of Task.status comes from the Workflow State Overview of COW IG, and the rules for stopping work that has started from the cancellation rules of COW IG. To stop work that has started, the Placer creates a Cancellation Request Task. (COW IG)
Specified by this TA
-
This TA adds no states.
-
A Coordination Task MUST NOT move directly from in-progress to cancelled.
-
The statuses draft and on-hold are not used by this TA. Whether the status ready is used is still to be decided (see Limitations of this document).
-
Where this TA uses a transition that the diagram does not show, this is stated.
[The diagram is not embedded in this Word version. See the state machine of the FHIR R4 Task resource.]
Figure: the typical state machine of the FHIR R4 Task resource. Source: FHIR R4, Task, Task state machine. This TA follows it, except where stated in this section.
|
Status |
Meaning in this TA |
Reached from |
Set by |
Follow-up for the Request |
|
requested |
The Placer has sent the Task. This is the initial status. |
Initial status |
Placer |
None. |
|
received |
The Fulfiller has read the Task but has not yet decided. |
requested |
Fulfiller |
None. |
|
accepted |
The Fulfiller can and will carry out the work. In the Multiple Fulfillers Pattern, several candidates may accept; acceptance does not imply selection. |
requested, received |
Fulfiller |
None, until a candidate is selected. |
|
rejected |
The Fulfiller declines, giving Task.statusReason. |
requested, received |
Fulfiller |
See Handling the End of a Coordination Task. |
|
in-progress |
The Fulfiller has started the work. |
accepted; requested in the Single Fulfiller Pattern |
Fulfiller |
None. |
|
failed |
The Fulfiller started the work but could not complete it. |
in-progress |
Fulfiller |
See Handling the End of a Coordination Task. |
|
completed |
The Fulfiller has finished its work. |
in-progress |
Fulfiller |
See Handling the End of a Coordination Task. |
|
cancelled |
The Coordination Task is withdrawn. |
requested, received, accepted |
Placer, before in-progress |
See Handling the End of a Coordination Task. |
|
entered-in-error |
The Task was created by mistake. |
Not shown in the diagram of FHIR R4 |
Placer |
See Handling the End of a Coordination Task. |
Cancellation Request Task
The elements of the Cancellation Request Task are restricted as in the table in Preliminary description of the profiles. The following rules apply in addition.
Follows from COW IG
-
A Cancellation Request Task MUST be created by the Placer when Task.status has already reached in-progress on the Coordination Task it targets.
Specified by this TA
-
The Cancellation Request Task is created on the Placer's own FHIR server.
-
The Coordination Task is in-progress when a Cancellation Request Task is used, so it MUST NOT be set to cancelled (see Status of the Coordination Task). Whether the Fulfiller may then set the Coordination Task to failed is still to be decided (see After an accepted Cancellation Request).
Request and patient
Request
The standard dataset for a referral is the baseline set of information a Fulfiller needs to carry it out — what would otherwise have to be negotiated case by case. This TA has the Request identify it directly, rather than leaving it to be inferred or agreed separately.
Follows from COW IG and TA Routing
-
A Request resource SHALL exist for every Coordination Task. (COW IG)
-
Request.status is changed only by the Placer, as the party that created the Request. (COW IG)
-
ServiceRequest.instantiatesCanonical MAY additionally reference an ActivityDefinition or a PlanDefinition, where a bare code is not precise enough. A PlanDefinition is a composite of ActivityDefinitions; the same rules apply to both. (TA Routing)
-
Where a directory defines an ActivityDefinition or PlanDefinition for a service, a receiving server MAY decline a Request that does not reference it via instantiatesCanonical, or that does not adhere to its requirements. (TA Routing)
Specified by this TA
-
ServiceRequest.code SHALL identify the standard dataset for the referral.
-
ServiceRequest.performer SHALL remain unset while more than one Fulfiller is under consideration (see Multiple Fulfillers Pattern).
-
This version of the TA does not yet specify how a Fulfiller establishes, from this dataset code, which resources it can actually retrieve (see Retrieving the resources of a dataset).
Request types other than ServiceRequest
This TA does not limit the Request to a ServiceRequest. The rules on specific elements, however, are written for ServiceRequest: ServiceRequest.code (the standard dataset), ServiceRequest.instantiatesCanonical, ServiceRequest.performer and ServiceRequest.subject (see Request, Routing by the Fulfiller and Patient context and readability). The other request resources that COW IG allows (DeviceRequest, MedicationRequest, NutritionOrder, SupplyRequest and VisionPrescription) do not all have these elements, or not under the same names.
The options:
-
Limit the TA to ServiceRequest. The Request is a ServiceRequest.
-
Work out the rules for each request type. For each resource, the equivalent elements are named.
-
Leave the rules for other request types to the use case.
[To be decided.]
Retrieving the resources of a dataset
The Request identifies the standard dataset by ServiceRequest.code (see Request). This TA does not yet say how a Fulfiller finds out, from that code, which resources it can retrieve. Possible solutions are listed below; others may exist.
-
DataRequirements. The definition to which ServiceRequest.instantiatesCanonical refers describes the dataset as DataRequirements: in the input of the actions of a PlanDefinition, or in the dataRequirement of a Library to which an ActivityDefinition or a PlanDefinition refers. TA Routing mentions neither.
-
A list of queries. The Nuts IG (page Clinical Workflow, draft) describes a PlanDefinition, published once by the owner of the dataset, that lists the FHIR queries for the dataset. A Fulfiller may also implement the queries directly from the dataset code.
-
The actual resources. The Placer lists the resources that are shared for a Task in Task.input (see Sharing additional content).
These solutions can be combined. [To be decided.]
Sharing additional content
The Placer MAY share content beyond the standard dataset that the Fulfiller needs to carry out the work. This content is supplied with the Coordination Task, in Task.input. Each entry of Task.input has a type, which says what the content is, and a value, which is the content or a reference to it.
Follows from COW IG
-
Content that relates to why the Request was authorized, or what is authorized, belongs to the Request (Request.supportingInfo). Content that relates to how the Request is to be fulfilled belongs to the Task (Task.input).
Specified by this TA
-
The Placer sets and changes Task.input. It is not one of the elements that the Fulfiller may change (see Write access).
-
A change of Task.input is a change of the Coordination Task, and reaches the Fulfiller through the notification of that change, in the same way as any other update by the Placer.
-
What an entry contains depends on the care domain and is not defined by this TA.
Patient context and readability
Requirements of COW IG and FHIR R4
-
The Coordination Task refers to the Request in Task.focus, which is mandatory. (COW IG)
-
Task.for is not constrained by COW IG. In FHIR R4 it is optional and can refer to the Patient; Task.for.identifier can carry an identifier of the patient, such as the BSN. (COW IG, FHIR R4)
-
Every ServiceRequest has a subject: ServiceRequest.subject is mandatory. (FHIR R4)
Functional requirement
During the preliminary phases of the workflow, a candidate Fulfiller has no link to the patient. The preliminary phases are the phases before the candidate is selected.
Solution, specified by this TA
-
ServiceRequest.subject MUST reference a Patient. A Group, a Location or a Device is not supported, and neither is leaving out or masking the subject, for example with the extension data-absent-reason.
-
Until a candidate is selected, the Placer MUST NOT give it read access to the Request or to the Patient resource.
-
Until a candidate is selected, Task.for of its Coordination Task is empty, including Task.for.identifier, and the Task carries no other information that identifies the patient.
-
When the Placer selects a candidate, it sets Task.for in the same update in which it sets Task.businessStatus to selected. From then on the candidate may read the Request and the Patient resource.
-
In the Single Fulfiller Pattern the Fulfiller is selected from the creation of the Task, so Task.for may be set at creation and the Fulfiller may read the Request from the start.
Open: the BSN. Whether the BSN is carried in Task.for.identifier, and from which moment, is still to be decided (see Limitations of this document). If it is carried, Task.for.identifier carries the patient's BSN, it is not required while Task.status is requested or accepted, and it MUST be populated no later than the point at which Task.status reaches in-progress. Since the Fulfiller, not the Placer, drives the transition to in-progress (see Task Update by Fulfiller), the Placer would then add Task.for.identifier, if it is not already present, as part of processing that same write: atomically, within the same operation that the status update of the Fulfiller triggers, and not as a separate round trip.
The patient is referred to in these places:
|
Where |
The patient is referred to by |
Status in this TA |
|
ServiceRequest.subject |
a reference to the Patient; mandatory |
MUST be a Patient; not readable by a candidate before selection |
|
Task.for |
a reference to the Patient |
empty before selection; set at selection |
|
Task.for.identifier |
an identifier, such as the BSN |
empty before selection; whether it is used afterwards is open |
What a candidate may read in each phase:
|
Phase |
Task.status of the candidate |
Request |
Patient resource (name, address) |
|
Invited |
requested, received |
May not read. |
May not read. |
|
Accepted, not yet selected |
accepted |
May not read. |
May not read. |
|
Selected, work started |
accepted (selected), in-progress |
May read. |
May read. |
|
Not selected |
cancelled |
May not read. |
May not read. |
Routing by the Fulfiller
A notification tells the Fulfiller that a Coordination Task it owns has been created or changed. It does not say what kind of work the Task concerns, or where it is to be carried out. The Fulfiller finds this out after reading the Task, from the Request that Task.focus refers to and from Task.location:
Follows from TA Routing
-
ServiceRequest.code states the type of service that is requested.
-
ServiceRequest.instantiatesCanonical, where present, refers to an ActivityDefinition or a PlanDefinition that describes how the service is requested and what it requires.
-
The HealthcareService that owns the Task lists the ActivityDefinitions it supports, in the extension supportedActivityDefinitions.
-
Task.location, where present, identifies the Location at which the work is to be carried out. A HealthcareService can be performed at several physical Locations, and a Placer can request care at a specific one.
-
Task.code does not carry the kind of work: it states what the owner is expected to do with the Request (see Task.code under Coordination Task).
Specified by this TA
-
The Fulfiller supports the ActivityDefinitions and PlanDefinitions that its HealthcareService lists: when a Request refers to such a definition, the Fulfiller MUST be able to resolve it and to process a Request according to it.
-
Supporting a definition does not oblige the Fulfiller to accept a Request: the Fulfiller MAY decline any Request, including one that refers to a definition it supports, by rejecting the Coordination Task.
-
The Fulfiller uses the information above to route the Request to the right internal process and, where Task.location is present, to the right Location, or to decline it (see Request).
Identifiers and search
Search parameters
This TA defines two search parameters on Task, so that Tasks can be found, and Subscriptions filtered, by business identifier:
|
Name |
Type |
Expression |
Used for |
|
owner-identifier |
Task.owner.identifier |
Filtering a Subscription (see Subscription) and searching for the Tasks of a Fulfiller (see Resynchronisation). |
|
|
requester-identifier |
token |
Task.requester.identifier |
Searching for the Tasks of a Placer. |
Follows from FHIR R4
-
A search parameter of type token takes a value of the form <system>|<value>, and each search parameter is published as a SearchParameter resource.
Specified by this TA
-
The canonical URL of the SearchParameter resources is to be decided.
-
This TA defines no new identifier systems: the systems are those of the identifiers of GF Addressing. The identifiers reflect the values with which the entity (the Organization, the HealthcareService or the Location) is registered in GF Addressing.
-
The Placer:
– SHALL support the search parameters owner-identifier and requester-identifier on Task in its FHIR server, and declare them in its CapabilityStatement (see Placer server capabilities).
– SHALL support owner-identifier as the filter parameter of a Subscription (see Subscription).
– SHALL record in Task.owner.identifier and Task.requester.identifier the identifiers with which the HealthcareService and the Placer are registered in GF Addressing.
-
The Fulfiller:
– SHALL use owner-identifier, with the identifier of its HealthcareService, in the filter of its Subscription (see Subscription) and when it searches the Placer's server for its Tasks (see Resynchronisation).
– SHALL give the value of a search parameter in the form <system>|<value>.
– MAY use requester-identifier to search for the Tasks of a given Placer.
Assumption about GF Addressing. This TA cannot place requirements on GF Addressing. It therefore does not require, but assumes, that GF Addressing ensures that an identifier system can only be used in a registration by the organization that the system refers to, so that a system and value identify one entity. The rules on ambiguous identifiers (see Coordination Task and Subscription) rely on this assumption.
Identifiers of Tasks and Subscriptions
The id of a Coordination Task, the id of a Cancellation Request Task and the id of a Subscription are carried in the notifications, so that every party that handles a notification sees them.
Follows from TA Notifications
-
Each id MUST be stable, opaque and unpredictable:
– Stable: the same id on every request for the same resource.
– Opaque: the id MUST NOT reveal creation order, volume, creation time or content.
– Unpredictable: the id MUST NOT be guessable, nor computable from a real-world identifying number such as the BSN by anyone who does not hold a secret of the Placer.
-
A consumer treats an id as an opaque string. It does not parse the id or derive meaning from it.
Specified by this TA
-
These requirements apply to the id of a Coordination Task, of a Cancellation Request Task and of a Subscription.
-
A randomly generated identifier (UUIDv4) meets these requirements. TA Notifications gives examples of constructions that satisfy the requirements and of constructions that do not.
Notification
SubscriptionTopic
The requirements of TA Notifications on a SubscriptionTopic apply in full, whether or not they are repeated here. The requirements below are separated into those that follow from TA Notifications and those that this TA specifies.
Follows from TA Notifications
-
A topic has a unique canonical URL, and names a single monitored resource type: SubscriptionTopic.resource and resourceTrigger.resource name the same resource type. (TA Notifications)
-
A topic defines the filter parameters that a Subscription may use, with the name and the element of the monitored resource to which each applies. (TA Notifications)
Specified by this TA
-
SubscriptionTopic.url MUST be https://landelijkafsprakenstelsel.nl/fhir/SubscriptionTopic/zorgaanbieder-verwijzing. The domain landelijkafsprakenstelsel.nl is a placeholder; the final canonical base is to be decided.
-
SubscriptionTopic.resource and resourceTrigger.resource MUST both be Task.
-
resourceTrigger.supportedInteraction MUST include create and update. create alone is not sufficient: both TA NP and eOverdracht rely on update-triggered notifications (dataset updates, cancellation), so this topic must support create and update to be specifiable as a profile of either.
-
The topic defines the filter parameter owner-identifier, which applies to Task.owner.identifier (see Search parameters).
-
The topic does not distinguish between types of work such as referrals, orders and transfers. The Coordination Task carries no code for the type of work, so a topic cannot narrow on it. The Fulfiller receives notifications for the Coordination Tasks it owns (see Subscription) and finds out what kind of work a Task concerns from the Request (see Routing by the Fulfiller).
-
The topic delivers both Coordination Tasks and Cancellation Request Tasks, because both are Tasks owned by the Fulfiller.
-
Because a Subscription fires on any matching interaction regardless of who performed it, including update in the topic means the Fulfiller is also notified of its own Direct Writes to the Coordination Task and to a Cancellation Request Task. A Fulfiller MAY disregard a notification it recognizes as reporting its own prior write.
Subscription
The requirements of TA Notifications on a Subscription apply in full, whether or not they are repeated here. A Subscription is as defined below, whether it is established out-of-band or in-band. The requirements below are separated into those that follow from TA Notifications and COW IG and those that this TA specifies.
Follows from TA Notifications and COW IG
-
A Subscription informs the Fulfiller of changes to the Coordination Tasks that it owns, and is held by the Placer, as Subscription Server, on its own server. (COW IG, Task at Placer with Subscriptions)
-
A Subscription MAY be established out-of-band by the Placer, or in-band by the Fulfiller. (TA Notifications)
-
Subscription.criteria MUST carry the SubscriptionTopic canonical, via the extension backport-topic-canonical. (TA Notifications)
-
The extension backport-filter-criteria carries the filter, a search-style key defined by the topic. (TA Notifications)
-
The extension backport-payload-content sets the payload mode. (TA Notifications)
-
How the notification endpoint of the HealthcareService is discovered is the responsibility of GF Addressing. (GF Addressing; TA Routing)
Specified by this TA
-
A Subscription MUST be established once per HealthcareService of the Fulfiller that receives Tasks, as part of onboarding that service in the Placer–Fulfiller relationship — not per Task — and remain in place across every subsequently created Task. A Fulfiller with several HealthcareServices therefore has one Subscription per service.
-
A Subscription is addressed to the notification endpoint of the HealthcareService. When it is established out-of-band, the Placer creates it. When it is established in-band, the Fulfiller creates it with the notification endpoint of the HealthcareService.
-
The filter MUST be of the form Task.owner-identifier=<system>|<value>, in which <system>|<value> is the business identifier of the HealthcareService (see Task.owner). The filter parameter is defined by the topic (see SubscriptionTopic).
-
A filter in backport-filter-criteria MUST NOT exclude a Cancellation Request Task that is owned by the Fulfiller, for example by filtering on Task.code without admitting abort.
-
The payload mode MUST be id-only. The payload modes empty and full-resource MUST NOT be used under this TA.
-
The Placer MUST NOT create or accept a Subscription for an owner identifier that does not resolve to exactly one HealthcareService in the directory data that the Placer uses to select the Fulfiller (see the assumption about GF Addressing under Search parameters).
On what basis the Placer accepts a Subscription that the Fulfiller creates in-band, or decides to create a Subscription itself out-of-band, is outside the scope of this TA, apart from the rule above on ambiguous identifiers. The same holds for the verification of the notification endpoint. TA Notifications and the generic functions for authorization and consent apply.
Healthcare services
Changes to healthcare services
Healthcare services change: they are split, merged, renamed or retired. Each HealthcareService has its own Subscription, and open Tasks refer to the service by its identifier. A change to a service therefore calls for maintenance of the Subscription of that service and of the Tasks that refer to it. The requirements and rules for this maintenance are to be decided. They concern at least:
-
how the Placer learns of a change to a service;
-
what happens to the Subscription of a service that is split, merged, renamed or retired, and whether a Subscription is needed for a successor service;
-
what happens to open Tasks that refer to the old service;
-
what happens to notifications for a Task whose owner no longer matches an active Subscription.
[Requirements and rules to be decided.]
Transactions
In each transaction and pattern, the rules are separated into those that follow from COW IG, TA Notifications or FHIR, and those that this TA specifies. The requirements of those specifications apply in full, whether or not they are repeated here.
Task lifecycle
Task Creation
-
Trigger: the Placer has authorized a Request and identified one or more candidate Fulfillers.
-
Exchange: POST on the Placer's own Task endpoint (Resource Definitions → Coordination Task).
Follows from COW IG and TA Notifications
-
The Task is delivered as Notified Pull, via the standing Subscription (Resource Definitions → Subscription). The Fulfiller reads the Task from the Placer's server.
Specified by this TA
-
The notification is id-only: it carries a reference to the Coordination Task and no content. The reference is an absolute URL.
Task Update by Fulfiller
-
Trigger: the Fulfiller updates Task.status, Task.businessStatus, Task.statusReason, or Task.output.
-
Exchange: PUT/PATCH by the Fulfiller on the Placer-hosted Coordination Task.
Follows from COW IG
-
The Fulfiller updates the Coordination Task at the Placer to report the progress of the work, over the Request's lifecycle.
Specified by this TA
-
The update is a Direct Write, limited to the four elements named in the trigger. The write is version-aware (see Write access).
Task Update by Placer
-
Trigger: the Placer updates the Coordination Task on its own initiative — for example, by cancelling it before in-progress (see Cancellation, below), or by changing any other element.
-
Exchange: local PUT/PATCH by the Placer on its own Coordination Task.
Follows from COW IG and TA Notifications
-
The update is delivered as Notified Pull: the Fulfiller did not make this change itself and can learn of it only through the notification or by reading the Task.
Handling the End of a Coordination Task
A Coordination Task ends when Task.status becomes completed, failed, rejected, cancelled or entered-in-error. The Placer decides about the Request by looking at all Coordination Tasks that refer to it, not at one Task alone. The column Source shows whether a row follows from COW IG or is specified by this TA.
|
Task.status |
Meaning |
What the Placer does |
Source |
|
completed |
The Fulfiller has finished its work. |
Review Task.output. Normally set Request.status to completed. If more work is needed, keep the Request active and create a new Coordination Task. |
COW IG |
|
failed |
The Fulfiller started the work but could not complete it. |
Either create a new Coordination Task, for another Fulfiller or the same one, and leave the Request active, or stop and set Request.status to revoked. |
COW IG |
|
rejected |
The Fulfiller declined before starting, giving Task.statusReason. |
If other candidates remain under consideration, leave the Request unchanged. Otherwise create a new Coordination Task for another Fulfiller, or set Request.status to revoked. |
COW IG |
|
cancelled |
The Coordination Task was cancelled by the Placer, before it reached in-progress. |
If the Placer is withdrawing the Request, set Request.status to revoked as well as cancelling the Task. If only a non-selected candidate was cancelled, leave the Request unchanged. |
COW IG |
|
entered-in-error |
The Task was created by mistake. |
Correct or replace the Task. Change the Request only if it was also wrong. |
This TA |
This TA specifies in addition:
-
While other candidates are still under consideration, the end of one candidate's Task does not change the Request. The Placer SHOULD NOT leave a Request active when no open Coordination Task refers to it, unless it is about to create one.
-
Other Tasks that relate to a Coordination Task, such as a Cancellation Request Task, do not change the Request themselves. The Placer acts on the status of the Coordination Task.
Patterns for several candidates
Multiple Fulfillers Pattern
A Placer facing more than one reasonable candidate solicits several at once, lets each respond, and commits to one, without having authorized any other candidate to act on the Request in the meantime. (COW IG, eOverdracht; see Design Choices)
Follows from COW IG
-
One Request MUST be shared by every candidate under consideration.
-
One Coordination Task MUST be created per candidate, each referencing the same Request via Task.focus.
-
Each candidate MAY accept, by updating its own Task.status to accepted, as a Task Update by Fulfiller (see Transactions). Acceptance does not imply selection.
-
When a candidate is chosen, the Placer MUST set that candidate's Task.businessStatus to selected, and MUST set every other candidate's Task.status to cancelled with statusReason set to not selected.
Specified by this TA
-
ServiceRequest.performer MUST remain unset while solicitation is open.
-
ServiceRequest.performer MAY be set to the selected candidate once chosen; Task.owner on the selected Task remains authoritative regardless.
How the Placer weighs the responses of the candidates and decides which one to select is outside the scope of this TA. This TA specifies responses of the candidates such as accepting and bidding (see Bidding), and how the decision is recorded and communicated once made.
Unless the optional code request-fulfillment is used, nothing in this pattern gives a candidate Fulfiller a way to learn, from its own Task alone, that it is one of several under consideration. What a candidate that is not yet selected may read is stated in Patient context and readability.
Nothing in this pattern depends on the referral use case that motivated it: the same structure applies to any workflow type this TA covers, wherever a Placer might solicit more than one Fulfiller for the same piece of work.
Reason for cancelling a non-selected candidate
When the Placer selects a candidate in the Multiple Fulfillers Pattern, it cancels the Coordination Tasks of the other candidates. COW IG gives these Tasks the reason not selected in Task.statusReason, and this TA uses that reason (see Multiple Fulfillers Pattern and the table in Preliminary description of the profiles). The reason is not defined in a code system. Task.statusReason has only an example binding in FHIR R4. COW IG does not define it either, and the Nuts IG (CodeSystem nl-cow-business-status, draft version 0.3.0) defines only selected; its page Clinical Workflow uses "not selected" as plain text. A candidate whose Task is cancelled can also read from Request.status whether the Request was withdrawn (see Cancellation (Before in-progress)).
The options:
-
Plain text. The Placer writes "not selected" as text in Task.statusReason.
-
A code. This TA defines a code, for example not-selected, in a code system of its own.
-
No reason. The Placer sets the status cancelled and leaves Task.statusReason empty; the candidate reads Request.status.
[To be decided.]
Bidding
Bidding is a way of using the Multiple Fulfillers Pattern in which candidates do not only accept but also describe what they would offer, so that the Placer, and where relevant the patient, can compare the candidates before one is selected. (COW IG)
Follows from COW IG
-
A candidate describes what it would offer in a bid. What a bid contains depends on the care domain and is not defined by this TA. A bid may describe, for example, the candidate's availability, a more specific service it would perform, the expected cost, or the person who would carry out the work.
Specified by this TA
-
A bidding task is a Coordination Task. The Placer invites bids by creating a Coordination Task for each candidate, all referring to the same Request (see Multiple Fulfillers Pattern). While several candidates are under consideration, these Coordination Tasks are the bidding tasks.
-
A candidate responds with a bid by accepting its bidding task and recording the bid in Task.output, as a Task Update by Fulfiller.
-
A candidate that does not want to bid MAY reject its bidding task with a statusReason. A candidate that accepts without a bid signals only that it is available.
-
The Placer reviews the bids received and selects a candidate. How it compares the bids and decides is outside the scope of this TA. The selection is recorded as described in the Multiple Fulfillers Pattern. A bid is not a commitment by the Placer: bidding, like accepting, does not imply selection.
-
The bidding ends when the Placer selects a candidate. The Coordination Task of the selected candidate continues for the work itself, and its Task.output keeps the bid. The Coordination Tasks of the other candidates are cancelled (see Multiple Fulfillers Pattern).
-
Each candidate has its own bidding task, so a candidate's bid is recorded on its own task only. Whether a candidate may see the bids of other candidates is an access-control question, outside the scope of this TA.
Single Fulfiller Pattern
Where a Placer already knows, at the moment the Request is authorized, which single Fulfiller should carry out the work, the Multiple Fulfillers Pattern does not apply. This pattern is specified by this TA.
-
Task.code MUST be fulfill from creation.
-
Task.owner MUST identify the one Fulfiller directly.
-
The Fulfiller MAY use accepted, or MAY move directly from requested to in-progress. The typical state machine of FHIR R4 does not show the direct move: it reaches in-progress from accepted or ready. This TA adds it for the case in which acceptance is a given.
-
Declining is likewise direct: the Fulfiller MAY move Task.status from requested straight to rejected, with statusReason.
This pattern applies only where the Placer and the sole Fulfiller have nothing to negotiate. Where negotiation is wanted — a proposed timing, a different scope, a request for more information — even with only one candidate, the Multiple Fulfillers Pattern applies instead, and the referral is treated as a solicitation of exactly one.
How a Fulfiller recognizes that this pattern applies is described in Recognizing the pattern that applies.
Cancellation
Cancellation (Before in-progress)
This is an instance of Task Update by Placer, above, in which Task.status is set to cancelled.
-
Trigger: the Placer wishes to withdraw the Request; Task.status has not reached in-progress.
-
Exchange: local PUT/PATCH by the Placer on its own Coordination Task, status → cancelled.
Follows from COW IG
-
The update is delivered as Notified Pull and requires no cross-organization write access.
-
When the Placer withdraws the Request, it also sets Request.status to revoked. When only this Coordination Task is cancelled, for example because another candidate was selected, Request.status stays active. A Fulfiller whose Task is cancelled reads Request.status to see which of the two applies.
Cancellation Request (After in-progress)
-
Trigger: the Placer wishes to withdraw the Request; Task.status has reached in-progress.
-
Exchange: POST by the Placer, on its own server, creating a Cancellation Request Task.
Follows from COW IG
-
The Cancellation Request Task is delivered as Notified Pull.
Cancellation Request Response
-
Trigger: the Fulfiller has read a Cancellation Request Task.
-
Exchange: PUT/PATCH by the Fulfiller, updating the Cancellation Request Task's status. Whether the Fulfiller may then set the Coordination Task to failed is still to be decided (see After an accepted Cancellation Request).
Follows from COW IG
-
The response is a Direct Write.
Specified by this TA
-
When the Fulfiller accepts the Cancellation Request Task, the work is stopped and the Placer sets Request.status to revoked. When the Fulfiller rejects it, the work continues and Request.status stays active.
After an accepted Cancellation Request
When the Fulfiller accepts a Cancellation Request Task, the Coordination Task is in-progress and MUST NOT be set to cancelled (see Status of the Coordination Task). The Placer sets Request.status to revoked when it withdraws the Request (see Cancellation Request Response). The choice is whether the step from in-progress to failed is allowed here:
-
Allowed. The state machine of FHIR R4 has the step from in-progress to failed. The Fulfiller sets failed, with a statusReason, and the Placer follows Handling the End of a Coordination Task. R4 defines failed as "attempted but could not be completed due to some error", which fits a withdrawal less well.
-
Not allowed. The Coordination Task stays in-progress. The accepted Cancellation Request Task, together with Request.status revoked, is the record.
[To be decided.]
Cancellation by the Fulfiller
A Fulfiller that cannot or does not want to carry out the work has three possibilities. None of them changes the Request itself, which only the Placer modifies. All three follow from COW IG.
-
Declining before starting. The Fulfiller sets the status of its Coordination Task to rejected, with a statusReason. The Request stays active.
-
Unable to complete. A Fulfiller that has accepted or started the work, and finds that it can no longer carry it out, sets the status of its Coordination Task to failed, with a statusReason. The Placer then decides what happens to the Request (see Handling the End of a Coordination Task).
-
Asking the Placer to withdraw the authorization. A Fulfiller that finds that the Request itself is inappropriate or even dangerous asks the Placer to cancel it, with an Authorization Cancellation Request Task. This Task has the status requested, the code abort, the intent proposal, and refers to the Request in Task.focus. The Placer decides. When the Placer accepts, it sets Request.status to revoked and cancels the Coordination Tasks that are still open.
Recovery and server behaviour
Resynchronisation
A Fulfiller that has missed notifications (a gap in the event numbers, a missed heartbeat, or a Subscription that was in error) retrieves the current state by searching the Placer's server. This TA does not require the $events operation. This section is the route for reconciliation that TA Notifications requires of a use-case agreement when $events is not required.
Follows from TA Notifications
-
The period of the search starts before the last processed notification, with a margin, because the time of an event need not equal meta.lastUpdated of the Task (see _lastUpdated). A Task processed twice is processed idempotently.
-
Every search includes the owner-identifier filter and the period, so that the Fulfiller retrieves no more than its Subscription would have delivered.
Specified by this TA
-
The Fulfiller searches Tasks with the filter of its Subscription over the period of the gap: GET [base]/Task?owner-identifier=<system>|<value>&_lastUpdated=ge<time>.
-
To find the Coordination Tasks for one Request, the Fulfiller adds focus=<Request>. To find the Cancellation Request Tasks for a Coordination Task, it adds focus=Task/<id>&code=abort.
Placer server capabilities
The server of the Placer MUST publish a CapabilityStatement (the capabilities interaction) that declares at least the following.
Follows from FHIR R4 and TA Notifications
-
A server publishes a CapabilityStatement through the capabilities interaction. (FHIR R4)
-
For Subscription: read and search with the parameters of TA Notifications, the $status operation, and the $events operation where it is supported. (TA Notifications)
-
The supported SubscriptionTopics, in the extension capabilitystatement-subscriptiontopic-canonical. (TA Notifications)
Specified by this TA
-
For Task: the interactions read, search, update and patch; the versioning level versioned-update; and the search parameters owner-identifier, requester-identifier, focus, code, status, business-status and _lastUpdated.
-
For the Request: the interaction read.
The formal definition of this CapabilityStatement will be linked here. It is not yet available.
Optional support for the code request-fulfillment
Optional: this section applies only if the profile of the Coordination Task keeps the extra code request-fulfillment. Whether it does is still to be decided (see Limitations of this document). Without the extra code, every Coordination Task has Task.code fulfill, as stated under Coordination Task.
Values of Task.code
Task.code says what the owner of a Task is expected to do with the Request. Where the extra code is used, this TA uses two values:
|
Code |
System |
Meaning |
|
fulfill |
The owner is asked to carry out the Request. |
|
|
request-fulfillment |
https://landelijkafsprakenstelsel.nl/fhir/CodeSystem/ta-workflow-task-code |
The owner is one of several candidates for the same Request and is invited to accept and, optionally, to bid (a bidding task; see Bidding). |
The domain landelijkafsprakenstelsel.nl in the URL of the code system is a placeholder; the final canonical base is to be decided.
Follows from FHIR R4 and COW IG
-
The code fulfill is defined by HL7 in the FHIR code system for Task codes. (FHIR R4)
-
The code request-fulfillment is not defined in any published code system. COW IG uses it in its explanatory text and examples, but does not define it in its formal artifacts, and the COW IG profile for the Coordination Task accepts any value in Task.code. (COW IG)
Specified by this TA
-
Where the extra code is used, Task.code is request-fulfillment while more than one candidate Fulfiller is under consideration, and fulfill otherwise, including once a candidate has been selected. The bidding tasks of the subsection Bidding then carry the code request-fulfillment. That the code applies only while more than one candidate is under consideration is a rule of this TA that a profile cannot express.
-
This TA defines the code itself, because it depends on the code to distinguish a bidding task from a Task sent to a single Fulfiller (see Multiple Fulfillers Pattern and Single Fulfiller Pattern). Without a defined code, implementers would give it different systems, or write it as plain text, and systems could no longer check or reliably interpret it.
What this TA defines for the code
Where the extra code is used, this TA defines:
-
a code system, which contains the code request-fulfillment;
-
a value set, which contains fulfill from the HL7 code system and request-fulfillment from the code system of this TA;
-
the Coordination Task profile, which binds Task.code to this value set with a required binding.
Where the extra code is used, a Task.code that is not in this value set is not valid under this TA. The HL7 code system is not changed or extended.
The formal definitions of this code system and of the value set will be linked here. They are not yet available.
Recognizing the pattern that applies
This section lists the options for a problem that is still open. The choice is to be decided (see Limitations of this document).
A Fulfiller that receives a Coordination Task needs to know which pattern applies. In the Single Fulfiller Pattern the Placer has chosen the Fulfiller, nothing is negotiated, and the Fulfiller may start the work. In the Multiple Fulfillers Pattern the Fulfiller is one of several candidates, and it waits until the Placer selects a candidate; a Fulfiller that started the work too early would do work for nothing. Unless the optional code request-fulfillment is used, the Task itself does not show which pattern applies.
The problem has two parts: which statuses the Fulfiller sets, and when it may start the work. The options below can be combined.
|
Option |
How the Fulfiller recognizes the situation |
Downsides |
|
The path is the same in both patterns: requested, accepted, in-progress. The Fulfiller does not need to know the pattern for the statuses it sets. |
Every Task gets an extra update by the Fulfiller, also where nothing is negotiated. Each update is a new version of the Task and, because the topic fires on the Fulfiller's own writes too, an extra notification to the Fulfiller itself. It does not tell the Fulfiller when it may start the work: it still needs a signal, such as option 2. |
|
The Fulfiller starts the work only when the businessStatus of its Task is selected. In the Multiple Fulfillers Pattern the Placer sets it at selection; in the Single Fulfiller Pattern the Placer sets it when it creates the Task. |
The Fulfiller must apply the rule "start when selected", and a system that starts at once would not conform. It relies on the code selected, whose code system is not yet settled. |
|
The code shows that the Fulfiller is one of several candidates; fulfill shows that it is the only one. |
It needs the extra code system and value set (see Optional support for the code request-fulfillment). |
|
In the Single Fulfiller Pattern the Placer sets the performer of the Request to the HealthcareService of the Fulfiller; in the Multiple Fulfillers Pattern it stays unset until a candidate is selected, as this TA already requires. |
The Fulfiller must read the Request in addition to the Task. A change of the Request produces no notification, because the topic covers Tasks only. |
|
The Placer creates the Task as ready in the Single Fulfiller Pattern, and as requested in the Multiple Fulfillers Pattern. In FHIR R4, ready is the status for a request whose assignment and acceptance is a given. |
It departs from the rule that a Task is requested at creation, and the status is not used by COW IG. |
|
The pattern is agreed per Placer–Fulfiller relationship, for example when a service is onboarded. |
It is not visible in the data, differs per service, and is easy to get wrong. |