npm package: @healthcloudai/hc-cdx
Description: Healthcheck CDX SDK with TypeScript
Author: Healthcheck Systems Inc
Latest version: 0.0.3

# Healthcheck CDX Connector

This connector handles the CDX rapid test flow: fetch a test profile by GTIN, request a screening upload URL, and submit a rapid test scan.
It reuses the authenticated login client together with the shared HTTP client.

## Features

1. Get a test profile by GTIN
2. Request a screening canned upload URL
3. Submit a rapid test scan

## Installation

```sh
npm install @healthcloudai/hc-cdx \
@healthcloudai/hc-login-connector \
@healthcloudai/hc-http
```

## Import

```ts
import { HCTakeTestClient } from "@healthcloudai/hc-cdx";
import { HCLoginClient } from "@healthcloudai/hc-login-connector";
import { FetchClient } from "@healthcloudai/hc-http";
```

## Setup

```ts
const httpClient = new FetchClient();
const loginClient = new HCLoginClient(httpClient);

loginClient.configure("demo-tenant", "dev");
await loginClient.login("john.doe@example.com", "ExamplePassword123!");

const takeTestClient = new HCTakeTestClient(
  httpClient,
  loginClient
);
```

Reuse the same authenticated `HCLoginClient` instance when creating `HCTakeTestClient` so both connectors share the same base URL and auth state.

## Public API

### `getTestProfileByGTIN(gtin)`

Public signature: `takeTestClient.getTestProfileByGTIN(gtin)`

Gets the rapid test profile for a GTIN.
This is an authenticated `GET` call.

```ts
const profileResponse = await takeTestClient.getTestProfileByGTIN(
  "00816862024500"
);
```

#### Full API request

This method performs an authenticated request internally and places the GTIN in the request path.
It does not send a request body.

#### API response

Status:

```txt
200
```

```json
{
  "Data": {
    "ID": "test-profile-id-example",
    "TestName": "WELLlife COVID-19/Influenza A&B Test",
    "CustomTestName": "WELLlife COVID-19/Influenza A&B Test",
    "ShortName": "WELLlife COVID/Flu",
    "VendorName": "Vendor Example",
    "ManufactureName": "Manufacturer Example",
    "CaptureMethod": 0,
    "GS1GTINs": [
      "00816862024500"
    ],
    "Instructions": [
      {
        "Title": "Example collection step",
        "ImageUrl": "https://assets.example.com/instructions/example-step.svg"
      }
    ],
    "Included": [
      "1 Test Cassette",
      "1 Disposable Swab"
    ],
    "Analytes": [
      {
        "Name": "SARS-CoV-2",
        "CasseteCode": "CoV"
      }
    ]
  },
  "ErrorMessage": null,
  "IsOK": true
}
```

### `getScreeningCannedUrl(extension)`

Public signature: `takeTestClient.getScreeningCannedUrl(extension)`

Requests a canned upload URL for the screening image.
The response includes the upload URL and the generated file key.
The package does not upload the file bytes itself.

```ts
const screeningUpload = await takeTestClient.getScreeningCannedUrl("jpg");
```

#### Full API request

```json
{
  "Data": {
    "Extension": "jpg"
  }
}
```

#### API response

Status:

```txt
200
```

```json
{
  "ImageURL": "https://storage.example.com/screeningphoto_example.jpg?signature=example",
  "FileName": "screeningphoto_example.jpg",
  "Extension": "jpg"
}
```

### `scanTest(type, scan)`

Public signature: `takeTestClient.scanTest(type, scan)`

Submits a rapid test scan to the selected test route.
The request body is sent as `{ "Data": scan }`.

```ts
const scanResponse = await takeTestClient.scanTest("rapid", {
  FileID: screeningUpload.FileName,
  GTINID: "00816862024500",
  TestProfileID: "test-profile-id-example",
  HealthServiceID: "health-service-id-example",
  EncounterID: "encounter-id-example",
  LotNumber: "LOT-12345",
  ExpirationDate: "2026-03-31T23:59:59.000Z",
  Outcome: {
    Result: "NEGATIVE",
    Comment: "Example comment"
  }
});
```

#### Full API request

```json
{
  "Data": {
    "FileID": "screeningphoto_example.jpg",
    "GTINID": "00816862024500",
    "TestProfileID": "test-profile-id-example",
    "HealthServiceID": "health-service-id-example",
    "EncounterID": "encounter-id-example",
    "LotNumber": "LOT-12345",
    "ExpirationDate": "2026-03-31T23:59:59.000Z",
    "Outcome": {
      "Result": "NEGATIVE",
      "Comment": "Example comment"
    }
  }
}
```

#### API response

Status:

```txt
200
```

```json
{
  "Data": {
    "Results": [
      {
        "Analyte": "SARS-CoV-2",
        "Result": "NEGATIVE"
      },
      {
        "Analyte": "influenza A",
        "Result": "NEGATIVE"
      },
      {
        "Analyte": "influenza B",
        "Result": "NEGATIVE"
      }
    ]
  },
  "ErrorMessage": null,
  "IsOK": true
}
```


## Flow

Typical integration flow:

1. Call `getTestProfileByGTIN(gtin)` to load the test profile for the scanned GTIN.
2. Call `getScreeningCannedUrl(extension)` to get an upload URL and generated `FileName`.
3. Upload the image file directly to the returned `ImageURL` outside this SDK.
4. Use the returned `FileName` as `FileID`.
5. Call `scanTest(type, scan)` with that `FileID`.

Example:

```ts
const profileResponse = await takeTestClient.getTestProfileByGTIN(
  "00816862024500"
);

const screeningUpload = await takeTestClient.getScreeningCannedUrl("jpg");

// Upload the file directly to screeningUpload.ImageURL outside of this SDK.

const scanResponse = await takeTestClient.scanTest("rapid", {
  FileID: screeningUpload.FileName,
  GTINID: "00816862024500",
  TestProfileID: profileResponse.Data?.ID
});
```

For frontend integrations, the recommended approach is to upload the file directly to the returned canned URL using the AWS SDK. The upload should include `x-amz-acl: public-read`, and the returned file name can then be used in the next API step.



## Notes

- `HCTakeTestClient` is the preferred client name.
- The SDK does not upload the file.
- The `FileName` returned by `getScreeningCannedUrl(...)` must be sent back as `FileID` in the scan request.