> ## Documentation Index
> Fetch the complete documentation index at: https://hmis-docs.derrickmugabwa.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Results relay channel

> Configure OIE to relay normalized laboratory results to HMIS.

## Purpose

`HMIS Laboratory Results Relay` is the single protected boundary between OIE and the HMIS result-ingestion API.

Protocol-specific inbound channels, such as ASTM/TCP and HL7/MLLP, normalize their messages to the common result JSON shape and send them to this channel. This channel does not parse analyzer messages and has no transformer steps.

```mermaid theme={null}
flowchart LR
  A[ASTM or HL7 inbound channel] -->|Normalized JSON| B[HMIS Laboratory Results Relay]
  B -->|Sanctum bearer token| C[HMIS result-ingestion API]
```

## Prerequisites

* A dedicated HMIS Sanctum token with only the `laboratory:results:write` ability.
* The token stored in OIE as a secret or entered in the `Authorization` header during local configuration.
* The HMIS app reachable on the internal Compose network as `app`.

<Warning>
  Do not use a staff login token or a worklist token here. Do not commit a real token in a channel export.
</Warning>

## Channel identity

| Setting                    | Value                           |
| -------------------------- | ------------------------------- |
| OIE version                | `4.5.2`                         |
| Channel name               | `HMIS Laboratory Results Relay` |
| Channel revision at export | `8`                             |
| Channel state              | Started                         |
| Source connector           | HTTP Listener                   |
| Destination connector      | HTTP Sender                     |

## Source: HTTP Listener

Configure the source connector as follows.

| Setting                  | Value                 |
| ------------------------ | --------------------- |
| Local interface          | `0.0.0.0`             |
| Local port               | `6661`                |
| Context path             | `/laboratory/results` |
| Data type                | Raw                   |
| Charset                  | UTF-8                 |
| Authentication           | None                  |
| Response content type    | `text/plain`          |
| Respond after processing | Yes                   |
| Processing threads       | `1`                   |
| Source transformer       | None                  |
| Source filter            | None                  |

The complete OIE endpoint used by inbound channels is:

```text theme={null}
http://oie:6661/laboratory/results/
```

The trailing slash is intentional. It prevents an HTTP redirect from converting a POST into a GET.

## Destination: HTTP Sender

Configure **Destination 1** as follows.

| Setting                          | Value                                              |
| -------------------------------- | -------------------------------------------------- |
| URL                              | `http://app/api/v1/laboratory/integration/results` |
| Method                           | POST                                               |
| Content type                     | `application/json`                                 |
| Data type                        | Text                                               |
| Charset                          | UTF-8                                              |
| Authentication                   | No                                                 |
| Request body                     | `${message.encodedData}`                           |
| Socket timeout                   | `30000` ms                                         |
| Queue enabled                    | No                                                 |
| Destination transformer          | None                                               |
| Destination response transformer | None                                               |

Add these headers using **Use Table**.

| Header          | Value                                |
| --------------- | ------------------------------------ |
| `Authorization` | `Bearer {{LAB_RESULTS_WRITE_TOKEN}}` |
| `Content-Type`  | `application/json`                   |

The Sanctum token is sent as an HTTP header. Leave OIE's Basic/Digest authentication controls disabled.

## Required payload

The relay forwards the input unchanged. Every upstream channel must produce this JSON shape before sending to port `6661`.

```json theme={null}
{
  "message_id": "{{MESSAGE_ID}}",
  "instrument_code": "{{INSTRUMENT_CODE}}",
  "specimen_number": "{{SPECIMEN_NUMBER}}",
  "received_at": "2026-01-01T00:00:00Z",
  "results": [
    {
      "analyzer_test_code": "HGB",
      "value": 13.4,
      "unit": "g/dL",
      "flag": "N",
      "observed_at": "2026-01-01T00:00:00Z"
    }
  ]
}
```

## Save, deploy, and verify

1. Select **Save Changes** in OIE Administrator.
2. Select **Deploy Channel**.
3. Confirm the channel is enabled and started.
4. Send a normalized result through an upstream channel or the mock analyzer's HTTP diagnostic mode.
5. In OIE Dashboard, confirm a successful source and destination message.
6. In HMIS, confirm an integration-message audit record and the imported result entry.

## Expected HMIS outcomes

| Situation                              | Expected behavior                                                                       |
| -------------------------------------- | --------------------------------------------------------------------------------------- |
| Valid new result                       | HMIS imports it and completes the requisition when all required tests are present.      |
| Identical duplicate delivery           | HMIS treats it as idempotent.                                                           |
| Same message ID, changed payload       | HMIS quarantines it as a conflict.                                                      |
| Unknown specimen/test or unit mismatch | HMIS records a reconciliation outcome; it does not silently create or convert a result. |
| Authorized requisition                 | HMIS protects the report from modification.                                             |

## Troubleshooting

| Symptom                             | Check                                                                                                             |
| ----------------------------------- | ----------------------------------------------------------------------------------------------------------------- |
| `Unauthenticated.`                  | Confirm the header is exactly `Authorization: Bearer {{LAB_RESULTS_WRITE_TOKEN}}`, with one space after `Bearer`. |
| HTTP 400 from HMIS                  | Confirm `Content-Type` is `application/json` and the body is `${message.encodedData}`.                            |
| HTTP 302 then empty/invalid request | Use `/laboratory/results/` when calling the OIE listener.                                                         |
| HTTP connection failure to HMIS     | Confirm the destination uses `http://app/...` from inside Compose, not `localhost`.                               |
| Result not visible clinically       | Review the HMIS integration audit and reconciliation queue before resending.                                      |

## Source artifact

The sanitised channel export is stored at:

`oie-channel-exports/HMIS Laboratory Results Relay.xml`
