npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@crvouga/mockingbird-service-odx

v1.0.2

Published

Stateful mock of the (retired) Optimal DX partner API: patients, partner links, HL7 and structured lab imports, Functional Health Reports (JSON/PDF), webhook registrations, and signed PatientTest webhooks.

Readme

@crvouga/mockingbird-service-odx

Stateful mock of the Optimal DX (ODX) partner API for test suites: partner labs and their biomarker elements, practice patients (create, update, delete, partner link, search), lab imports (HL7 v2 ORU and structured results), the Functional Health Report (JSON or PDF), webhook registrations, and the signed PatientTest webhooks ODX posts back.

The vendor was retired 2026-07-22. Our queue paths are gated only by the acme-pdf-enabled flag (default false), so a local stack with no PostHog still calls ODX. The cheaper fix is to turn that flag on through the PostHog mock (@crvouga/mockingbird-service-posthog); use this mock when a suite must exercise the ODX path itself (bio-age webhooks, the Healthie PDF upload, migrations).

  • Operation coverage: SUPPORT.md
  • ODX publishes no spec: openapi.yaml is hand-authored from our consumer's wire shapes (optimal.dx.service.ts, the webhook guard and DTO, and QA's odx-client.ts).

Install

npm install -D @crvouga/mockingbird-service-odx

ESM only. Node >= 22 or Bun >= 1.2. No native dependencies. Serve it with npx mockingbird-odx serve, createServer from ./server (Node), or createRuntime with any Fetch server.

Usage

The real base URL is https://odxinstanceresource.azure-api.net/<partner>; the partner segment is your account's slug. Point OPTIMAL_URL at the mock (it is overridable; no path prefix is needed), keep any OPTIMAL_API_KEY and OPTIMAL_PRACTICE_ID. Pre-register the backend's webhook, or let manageWebhooks register it through POST /v1/webhook as it does in production:

npx mockingbird-odx serve --port 8817 \
  --webhook-url http://127.0.0.1:3000/odx/webhook   # must equal SYSTEM_API_DEPLOYMENT_URL/odx/webhook
import { createRuntime } from "@crvouga/mockingbird-service-odx"

const odx = createRuntime({ webhook: { url: "http://127.0.0.1:3000/odx/webhook" } })
const call = (path: string, body?: unknown) =>
  odx.fetch(
    new Request(`http://odx.test${path}`, {
      method: body === undefined ? "GET" : "POST",
      headers: { ApiKey: "any", "content-type": "application/json" },
      ...(body === undefined ? {} : { body: JSON.stringify(body) }),
    }),
  )

const patient = await (
  await call("/v1/practice/p1/patient", { firstName: "Ada", lastName: "Lovelace", gender: "Female", email: "[email protected]" })
).json()
// …the app posts HL7 to /v1/practice/p1/patient/{patientId}/test; the mock answers the parsed
// PatientTest and posts a signed `Created` webhook to /odx/webhook.

Routes

| Route | Behaviour | | --- | --- | | GET /v1/partner/labs | [{labId, name, isCurrentLab}]: AHA (1), Quest (2), LabCorp (3). | | GET /v1/elements/{labId} | The element corpus (ELEMENTS) for the lab: elementId, elementName, elementGenderType, cuUnit, siUnit, cuToSiConversionFactor, elementReferences[{elementCode}] (LOINC codes HL7 OBX-3 is mapped by). Includes the nine phenotypic-age inputs (ids 494, 496, 506, 511, 537/538, 556, 564, 568, 571). Unknown lab → 404 {Message}. | | POST /v1/practice/{pid}/patient | Creates an OdxPatient with a numeric patientId (100001…). firstName, lastName, email required, else ASP.NET problem details 400. dateOfBirth becomes YYYY-MM-DDT00:00:00; gender is normalized to Male/Female/Unknown. | | PUT /v1/practice/{pid}/patient/{id} | Replaces the patient; 404 {Message} when unknown in that practice. | | DELETE /v1/practice/{pid}/patient/{id} | 204; drops its tests (QA teardown). | | POST /v1/practice/{pid}/patient/{id}/partner/{localUserId} | Body is the literal false; stores our user id (admin-visible). Answers true. | | GET /v1/practice/{pid}/patients | All patients; with any of email, firstName, lastName, dateOfBirth it is a case-insensitive search that answers 404 when nothing matches (our client passes ignore404). | | POST …/patient/{id}/test | HL7 import: {labProfileId, labId, testDate, unitType, userId, externalReference, externalMessageControlId?, externalPatientTestId, menstrualPhase, isFasting, hl7}. OBX-3 code^text maps to an element by lab code, EL<id>, or name (hs-CRP picks the patient's sex); OBX-5 values like <0.2 become comparison: "<". Unmapped / non-numeric observations land in importLogs. Emits Created. A message without MSH or OBX is a 400. | | PUT …/patient/{id}/test/{testId} | Re-import; emits Updated (ODX sends a Created+Updated pair with identical data). | | POST …/patient/{id}/testresults | Structured import (results[{elementId, value, comparison}]); emits Created. | | GET …/patient/{id}/tests | The patient's tests, oldest first. | | POST /v1/reports/FunctionalHealthReport | outputType: Json → {metadata, labs, elements, sections} with the sections our storeHealthData reads (groups, above/below optimal, "Functional Body Systems" conditions, health concerns); Pdf → a valid single-page application/pdf. Unknown test → 404. | | GET /v1/webhooks | [{partnerWebhookId, signingKey, createDate, entityEvents: {PatientTest}, webhookUrl}] — our guard calls this on every inbound webhook to fetch the key. | | POST /v1/webhook, PUT /v1/webhook/{id} | Register / update (manageWebhooks). |

Errors: missing / unknown ApiKey → 401 {statusCode, message} (Azure API Management's shape); ODX errors → {Message}; validation → ASP.NET problem details {title, status, errors}.

Webhooks

Every test import or re-import posts {entityType: "PatientTest", eventType, data: <PatientTest>} to each registered webhook URL subscribed to that event, with optimaldx-signature: <UPPERCASE hex HMAC-SHA256(signingKey, rawBody)>. data is the full PatientTest (results[].comparison is always a string, as our receiver's zod DTO requires). Non-2xx answers are retried (immediately, 5 s, 5 min, 30 min, 2 h). GET /__admin/webhooks, /__admin/webhooks/events, POST /__admin/webhooks/flush and …/replay work as usual.

Admin (beyond the standard contract)

| Route | Effect | | --- | --- | | POST /__admin/tests/:id/webhook | {eventType?: Created\|Updated\|Deleted, signature?: valid\|short\|bad}: emit a webhook for a stored test. | | DELETE /__admin/tests/:id | Emit Deleted and drop the test. | | GET /__admin/patients, GET /__admin/tests | The namespace's records (patients include partnerUserId; the HL7 text is never stored). | | GET/PUT /__admin/settings | {apiKeys?: string[]} (empty accepts any key). |

Fault presets (POST /__admin/faults {"preset": "<name>", "count"?: n}): wrong_length_signature, bad_signature, empty_success, no_content, not_found, server_error, slow, webhook_duplicate, webhook_reorder, webhook_drop.

Namespaces

x-mockingbird-namespace, a /ns/<name> prefix on OPTIMAL_URL, or by API key: PUT /__admin/credentials {"credentials": {"<OPTIMAL_API_KEY>": "<namespace>"}}.

Known consumer bugs

  • Wrong-length signature → 500. OdxSignatureGuard.verifyHmac calls crypto.timingSafeEqual on buffers of different lengths, which throws RangeError instead of returning false, so a truncated optimaldx-signature is a 500 (ODX then retries) rather than a 403. The wrong_length_signature preset sends a 32-character signature to reproduce it.
  • manageWebhooks "updates" a stale registration with its own old URL (a no-op), then registers the new one, so stale registrations accumulate.
  • updateWebhook passes the method as 'Put'; Node's fetch normalizes it (Bun's does not — the consumer port normalizes, as the app runs on Node).

Deliberately not modelled

  • Clinical logic: report conditions and health concerns are derived only from which results fall outside their optimal range; bio-age is not computed.
  • The real element catalog (thousands of elements, lab-specific codes): a 13-element corpus covers our consumer's needs. HL7 segments other than MSH/OBX are ignored; PID is never stored.
  • Report themes, recipients beyond the metadata label, and PDF content.
  • No official SDK exists, so there is no SDK drop-in test.

API

| Export | Kind | Description | | --- | --- | --- | | OdxAPI | class | The in-process mock: fetch(request), reset(), emit(testId, eventType, signature?), patients(), tests(). Options: sqlite, now, namespace, settings, onWebhook. | | createRuntime | function | The mock with the full service contract. Options: webhook: {url, signingKey?}, settings, retryDelaysMs, fetch, clock, seed, adminKey, onLog. | | ODX_PRESETS | object | Every named fault preset. | | ODX_NAMESPACE | string | The service name, "odx". | | SIGNATURE_HEADER | string | "optimaldx-signature". | | signOdx | function | (signingKey, body) → UPPERCASE hex HMAC-SHA256. | | apiKeyCredential | function | The ApiKey header (how credentials map to namespaces). | | ELEMENTS, LABS | arrays | The element corpus and partner labs. | | matchElement, parseObservations | functions | HL7 OBX parsing and code → element mapping. | | DEFAULT_SETTINGS | object | Per-namespace defaults. | | document, operationIds, supportedOperationIds | values | The vendored OpenAPI contract and its operation ids. | | createServer, serveTarget, DEFAULT_PORT (./server) | Node | Serve over node:http; the serve CLI target; port 8817. |

Part of mockingbird.