owned this note
owned this note
Published
Linked with GitHub
---
tags: argo-write
title: Archived:Argo InDirect Write Options
---
{%hackmd qFrEnWCZRxezInZtIIYarg %}
---
:::info
the Argo Write API builds on the FHIR RESTful API specification. The terms "EHR" and "Server" are used interchangeably in the document below.
:::
# Argo Write - InDirect Write Options
To covers these scenarios when submitting patient data to an EHR:
- immediate incorporation into the EHR
- immediate rejection from EHR
- asynchronous administrative or clinical review before deciding to incorporate or reject.
we have explored the following 2 options for indirectly writing to an EHR:
1. Task base writes
2. a RPC-like write [operation](http://build.fhir.org/operations.html)
### Background and Comparisons of Communication Patterns:
- [Workflow patterns](http://build.fhir.org/workflow-management.html#optiong)
- Choosing the right [FHIR interaction for You](http://build.fhir.org/ig/HL7/davinci-ehrx/exchanging.html#approaches-to-exchanging-fhir-data) which does not actually address this use case but points to operation instead :slightly_frowning_face:
<!-- Enter your content here -->
## Using Task
1. Task provides slots for inputs, outputs, and status
6. Allows for synchronous and asynchronous ( e.g., needs human review ) response
7. Allows for rejection, acceptance and "we will get back to you" responses
8. Allows for splitting into subtasks for more complex requests
9. Allow for Client to be updated on the status of of its request and be able to access the data.
### Steps
1. Client POSTS to EHR with inputs ('please add this to my record')
1. multiple inputs possible - some may be more important than others
2. Option to use transaction/batch Bundles as inputs
:::warning
limited by the bundle processing rules to allow rejection, accept in same bundle if resources reference each other
:::
3. EHR updates Task and determines when complete
1. May populate outputs with ?OperationOutcome? or ?sub-Task? for each input
:::warning
how to keep track of which input corresponds to which output?
- for OperationOutcome could use `OperationOutcome.issue.expression` ( e.g. `$this.input[0]`)
- for sub-Task `Task.input` would point to input in Parent Task
:::
2. Could use transaction/batch response Bundles as outputs (see caveat above )
5. Client checks in on Task to get updates on status ('is this stuff added to my record yet')
### Example
Patient A sends weight to Provider B as instructed using a prescribed app. Patient also sends optional Device and Location information
Preconditions/Assumptions:
- Patient is provided an app (gateway) and instruction how to use
- Patient directly writes data to the app (“unsupervised” data)
- a “Data Submission Key” is provided to write to record in fulfillment of this data submission request.
- The patient may send the observation and any relevant context, device information, location, etc
- The server may accept,reject or hold the data for review based on established policy
- in this case, *The provider has established a policy to accept wt data and may accept Device data after review*
- the server will accept the Weight measurement, reject the Location data, and review the Device data before rejecting
#### Sequence Diagram
```plantuml
@startuml
Note over PatientApp: Patient enters Weight, Location and Device data
PatientApp -> PatientApp : App creates Task/123\nfocus = “Data Submission Key” \nstatus = requested\ninputs:\n Observation/123\n Location/123\n Device/123
PatientApp -> EHR: POST Task/123
Note right of EHR: Task.status = received
Note over EHR: Request is reviewed & resolved
alt data acceptance policy applies
EHR->EHR: Task output[0] = "Observation/123 accepted"
else no specific policy, default to rejection
EHR->EHR: Task output[1] = "Location/123 rejected"
else data review policy
EHR->EHR: Task output[2] = "Device/123 pending review"
end
PatientApp ->> EHR: GET Task/123
EHR->>PatientApp: Task.status = pending
Note over EHR: Pending request reviewed & resolved
EHR->EHR: Task output[1] = "Device/123 rejected"\nstatus= completed
PatientApp ->> EHR: GET Task/123
EHR->>PatientApp: Task.status = completed
EHR-->>ProviderClient: !Notify (not standarized)
@enduml
```
## Write Operation `$argo-write` (temporary name)
Needs to meets the same functionality as above, but maybe can abstract the interface and allow for a simpler API.
### Steps
1. Client `POST`s operation to EHR with input Parameters:
- `reosource` containing 1..* Observations to incorporate and supportingInfo (e.g, Device, Provenance), if any ('please add this to my record')
:::warning
would splitting input parameters into observations and supportingInfo be better?
:::
- `submissionKey` 0..1
:::info
A single resource submission could just be a `POST` body (no input Parameters needed!)
:::
2. EHR returns??:
Requirements:
1. url for accepted resources
2. way to check status for those in review
3. way to indicate which ones were rejected and why.
- Option 1: Single single output parameter named 'return' = collection Bundle tracking each submission with *Task*:
* If an existing policy applies (perhaps hinted at by a Data Submission Key from (1))
* EHR can auto-apply the submission, returning a `Task` with completed status; submitted resources will appear on FHIR API
* If a "default to rejection" policy applies
* EHR can reject the submission, returning a `Task` with a rejected status
* If a "default to review queue" policy applies
* EHR can create route for out-of-band review, returning a Task with received status to the app; app can monitor the task to see if it is accepted or rejected, eventually
- Option 2: multiple output *composite* Parameters for each submission in same order (modeled after `Bundle.entry.response` element)????:
3. Client checks in to get updates on status ('is this stuff added to my record yet')
### Example
see [above](#Example) for description and preconditions and assumptions
#### Sequence Diagram Option 1
```plantuml
@startuml
Note over PatientApp: Patient enters Weight, Location and Device data
PatientApp -> PatientApp : App creates Parameter/123\nsubmissionKey = “Data Submission Key” \nresource:\n Observation/123\n Location/123\n Device/123
PatientApp -> EHR: POST $argo-write
EHR -> EHR : App creates Bundle/123\n entries:\n Task\123 status =completed\n Task\456 status=rejected\n Task\789 status =pending\n
PatientApp <- EHR:Http `200`\nresponse body= Bundle/123
PatientApp ->> EHR: GET Task\789
EHR->>PatientApp: Task.status = pending
Note over EHR: Pending request reviewed & resolved
EHR->EHR: Task/789 input = "Device/123 rejected"\nTask/789 status= completed
PatientApp ->> EHR: GET Task/789
EHR->>PatientApp: Task.status = completed
EHR-->>ProviderClient: !Notify (not standarized)
@enduml
```
## Pros/Cons
|Pros|Task|Operation Option A|
|---|---|---|
Uses the FHIR REST API for managing the workflow|:heavy_check_mark:|:X:|
Subscription/polling is targeted to a specific resource instance - much simpler than general subscription/polling infrastructure|:heavy_check_mark:|:heavy_check_mark:
Both Client and EHR can track the state of the workflow|:heavy_check_mark:|:X:|
Can use this approach for request other than just write (e.g. to request updates)|:heavy_check_mark:|:X:|
One submission API that can cover use cases where review is required and use cases where decisions are automated|:heavy_check_mark:|:heavy_check_mark:
There's an ability to negotiate fulfillment - i.e. the ability to say "no" and allows EHR to manage semantics for device management (e.g., decision to link incoming Observations to an existing Device, vs duplication/re-creating the Device for each Observation) |:heavy_check_mark:|:heavy_check_mark:
Explicit acknowledgement that EHR has received and agreed to act on the request|:heavy_check_mark:|:heavy_check_mark:
Client can attempt to cancel task in the event of order cancellation, but no guarantee|:heavy_check_mark:|:X:
EHR has control over whether task can be cancelled|:heavy_check_mark:|:heavy_check_mark:
#### Cons
Additional complexity of using Task
Additional complexity of using subscription or polling
Client and EHR may need to be able to communicate directly (i.e. know each other's respective endpoints)
This could become unmanageable if there are a large (or dynamic) number of Clients and EHRs that need to communicate
Client might not know immediately when EHR system has fulfilled the request, App may need to monitor status if EHR can’t make an in-band decision on how to process
#### Questions:
:thinking_face: Why not just use the FHIR RESTful Create interaction syntax anyway and have it behave like an operation?
:raising_hand:this leaves app unaware of whether data have fully "landed" or are still "in limbo", if the FHIR API is behaving differently for different clients.
{%hackmd 8ffOHhmtSKuk035ydksKiA %}