# Common use cases for composable processors

A composable <u>**processor**</u> is a collection of operations you can build to orchestrate your unique workflow. You can reuse a processor for multiple workflows. . [Learn more about orchestration](/basics/data-exchange-with-redox/orchestrate-your-unique-data-workflows).

Check out how processors can enhance your data processing workflow with these high-level use cases, including one detailed use case with code examples at the end.

## Use case 1: Enrich a message with data from another API

<u>Scenario</u>: A message from your connection is missing diagnoses, insurance details, or certain code sets.

<u>Problem</u>: You need the missing data to populate records in your system. 

<u>Goal</u>: Add the missing data from an external API to the message before it reaches your system.

<u>How the processor works</u>:

1. The processor calls an external API to get the missing data.
2. The processor enriches the messages with these details: 
   - Add encounter diagnoses from the EHR system to a `Scheduling` message.
   - Add insurance information to `VisitQuery` results.
   - Add standardized terminology codes to a value set.
3. The processor sends the enriched message to your system.

## Use case 2: Send one message as two

<u>Scenario</u>: You receive order cancellations as HL7v2 messages. 

<u>Problem</u>: To cancel a single order, your system needs two HL7v2 messages that differ only in `ORC.1`. Your connection (i.e., the source system) sends only one `Order.Cancel` message.

<u>Goal</u>: Send two versions of the cancellation, each with the `ORC.1` value that your system expects.

<u>How the processor works</u>:

1. The processor duplicates the `Order.Cancel` message.
2. It tags the copy.
3. Your destination’s config uses the tag to set a different `ORC.1` value on each message.

## Use case 3: Pull a clinical record after discharge

<u>Scenario</u>: An EHR system send discharge notifications to your system. 

<u>Problem</u>: You need the patient’s full clinical record after discharge, but the EHR system only sends a discharge notification. 

<u>Goal</u>: Turn the discharge notification into a complete clinical record for your system.

<u>How the processor works</u>:

1. The processor takes the MRN from the A03 message.
2. It finds the patient in the EHR system.
3. It runs a set of FHIR searches, such as `Encounter`, `Observation`, `Condition`, and `Medications`.
4. It reads any referenced `Location`, `Organization`, and `Practitioner` resources to build the clincial record.
5. It combines everything into one FHIR bundle and sends it to your system.

## Use case 4: Automatically check for new data in HL7v2 feeds

<u>Scenario</u>: You’re receiving an SIU and ADT feed that you filter based on provider ID.  

<u>Problem</u>: The provider ID list is manually maintained and filters have to be updated or paused every time a new provider is added to the network. 

<u>Goal</u>: Automatically check for new providers and get notified about the new provider(s) without having to pause your filters.

<u>How the processor works</u>:

1. The processor polls for new providers. 
2. It notifies your system when a new provider is added so you can update your filter and provider list without pausing.  

## Detailed use case: Split a FHIR bundle into several messages

<u>Scenario</u>: You receive a FHIR bundle with several document entries in one message.

<u>Problem</u>: Your system expects individual documents for easy retrieval. 

<u>Goal</u>: Split the FHIR bundle into individual Document Bundle payloads.

**Example: Input payload for populating a field**

```json
{
  "SCH": {
    ...
    "11": [
      {
        "1": {
          "1": "20240603165602"
        },
        "2": {
          "1": ""
        },
        "3": "",
        "4": {
          "1": "20240603175602"
        }
      }
    ]
  }
}

```

<u>Process operations</u>: Next, build your processor with these operations: 

- `apply-config`: You need to modify the FHIR bundle by applying a Redox base config. [Learn about apply config](https://preview-docs.redoxengine.com/basics/what-is-orchestration/#apply-config).
- `map-collection`: You need to map the split document bundles to new payloads with metadata for each. [Learn about map collection](https://preview-docs.redoxengine.com/basics/what-is-orchestration/#map-collection).
- `build-json`: You need to return each item as a full payload with metadata so it's ready to enqueue at your source. [Learn about build json](https://preview-docs.redoxengine.com/basics/what-is-orchestration/#build-json).

**Example: Split a FHIR bundle processor**

```json
{
  "splitBundle": {
    "name": "Split FHIR Bundle into a Bundle transaction of individual document Bundles",
    "operationType": {
      "key": "apply-config",
      "majorVersion": 1
    },
    "nextOperation": {
      "onSuccess": "Operation.mapPayloads",
      "onError": "Processor.error"
    },
    "inputExpression": {
      "type": "reference",
      "reference": "Payload.initial",
      "includeMetadata": false
    },
    "parameterExpressions": {
      "configVersion": {
        "type": "constant",
        "constant": {
          "structure": "json-object",
          "kind": "redox-config-version",
          "value": {
            "key": "7e2329af-1960-4871-a0ae-ed27f034237e"
          }
        }
      }
    },
    "dataLabels": {
      "output": {
        "onSuccess": {
          "dataModel": {
            "value": "FHIR.Event.Document"
          },
          "eventType": {
            "value": "document-created"
          }
        },
        "onError": {
          "error": {
            "value": "error"
          }
        }
      }
    }
  },
  "mapPayloads": {
    "name": "Map the split document Bundles to new payloads with metadata for each",
    "operationType": {
      "key": "map-collection",
      "majorVersion": 1
    },
    "nextOperation": {
      "onSuccess": "Processor.success",
      "onError": "Processor.error"
    },
    "inputExpression": {
      "type": "reference",
      "reference": "Payload.splitBundle",
      "includeMetadata": false
    },
    "parameterExpressions": {
      "selector": {
        "type": "constant",
        "constant": {
          "structure": "string",
          "kind": "jsonpath-selector",
          "value": "$.entry[*].resource"
        }
      },
      "itemPayloadKey": {
        "type": "constant",
        "constant": {
          "structure": "string",
          "value": "documentBundle"
        }
      },
      "initialOperationKey": {
        "type": "constant",
        "constant": {
          "structure": "string",
          "value": "buildWithMetadata"
        }
      },
      "includeItemMetadata": {
        "type": "constant",
        "constant": {
          "structure": "boolean",
          "value": true
        }
      },
      "operations": {
        "type": "constant",
        "constant": {
          "structure": "json-object",
          "value": {
            "buildWithMetadata": {
              "name": "Simply returns each item as a full Payload (with metadata) so it's ready to enqueue",
              "operationType": {
                "key": "build-json",
                "majorVersion": 1
              },
              "inputExpression": {
                "type": "reference",
                "reference": "Payload.documentBundle",
                "includeMetadata": false
              },
              "parameterExpressions": {
                "schema": {
                  "type": "constant",
                  "constant": {
                    "structure": "json-object",
                    "kind": "config-modifier-schema",
                    "value": {}
                  }
                }
              },
              "nextOperation": {
                "onSuccess": "Processor.success",
                "onError": "Processor.error"
              },
              "dataLabels": {
                "output": {
                  "onSuccess": {
                    "dataModel": {
                      "value": "FHIR.Event.Document"
                    },
                    "eventType": {
                      "value": "document-created"
                    }
                  },
                  "onError": {
                    "error": {
                      "value": "error"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "dataLabels": {
      "output": {
        "onSuccess": {
          "dataModel": {
            "value": "FHIR.Event.Document"
          },
          "eventType": {
            "value": "document-created"
          }
        },
        "onError": {
          "error": {
            "value": "error"
          }
        },
        "onStop": {
          "error": {
            "value": "stop"
          }
        }
      }
    }
  }
}
```
