← All scenarios

Worked example — Laboratory and clinical operations

Instruments, partners and approvals held together by scripts

Samples move between an intake system, instruments that take hours to return a result, and partner laboratories — and every hop is a bespoke script nobody can see into.

The situation

A sample is registered, prepared, run on an instrument, reviewed and released. The instrument returns asynchronously, sometimes hours later. Partner laboratories need a stable contract to submit against and to read results from. A release requires a signed approval against a versioned protocol, and when something fails at two in the morning somebody has to be able to see where it stopped and resume it — not re-run the day.

These are illustrative scenarios showing how the products are used, not customer case studies.

Build-versus-buy lens

What this helps you decide

Use the example to find where product configuration ends and custom code begins — and whether the boundary leaves your team with less infrastructure to own.

Model fit
Can the record shape evolve without coordinating a migration, API and UI release?
Workflow fit
Can approvals, exceptions and deadlines move out of application code without losing control?
Integration fit
Can your existing APIs become reusable steps with retries, throttling and visible run history?
Control fit
Can your team reconstruct model changes, workflow runs and human decisions later?

What gets modeled

The structure as it would actually be defined — sections that repeat are marked.

  • Samplerecord type
    • Subject referencetext

      Identifier only, no direct identity

    • Protocolchoice

      Options read live from Protocols

    • Runsrepeating section
      • Instrumentchoice
      • Started atdate and time
      • Resultstructured data

        Written back by the callback

  • Protocolsrecord type

    Versioned; a run stays on the version it started on

How it gets built

In the order somebody would actually do it. Each step names the capability it rests on, so it can be checked against the product pages.

  1. Register the instrument as a set of steps

    Point at the instrument service’s own API description — by URL, by uploading a file, or by probing it — preview what would be imported, and choose only the operations you want as steps. Where there is no description to import, author the action by hand. You are never waiting for somebody else to build a connector.

    What it uses: Import operations from a service’s API description; hand-author when there is none

  2. Say where every value comes from

    Each step’s inputs are mapped from the triggering event, an earlier step’s output, the record itself, a fixed value or a computed one. Defaults come from the catalog, are overridden per record type and again per workflow, with a panel showing the result of all three. Mappings are compiled when the trigger is armed, so what runs is exactly what was checked — and a trigger will not arm until its mappings are complete.

    What it uses: Layered input mapping, compiled at arming time

  3. Hand the long instrument run over and park

    The instrument step hands work across and parks with a deadline rather than holding a connection or polling. The instrument posts its result back when it is done, authenticated with a token issued for that run, and the result is written onto the sample. Run state lives in the database, so a worker restart resumes the run instead of losing track of what was outstanding.

    What it uses: Callback steps with a deadline, and run state held in the database

  4. Give partner laboratories a contract, not an endpoint

    The Sample record type is published with its own REST URL space and an API description generated from the model, plus a schema description per published version. Each partner gets its own key, scoped to particular record types, with its own rate limit, rotated or revoked without touching anyone else — and key holders are always served the published version, never a working draft.

    What it uses: Generated API description, and API keys scoped per record type

  5. Push results out rather than being polled

    Downstream systems subscribe to record events and receive them signed, with retries on a backoff, dead-lettering and a delivery log with per-attempt detail. Deliveries that dead-letter can be redriven in bulk from a console, and a failure rate crossing a threshold raises an alert.

    What it uses: Signed event delivery with retries, dead-lettering and bulk redrive

  6. Release on a signed approval against the right protocol

    Release is a human decision requiring re-authentication at the moment of signing and a reason from your own codes, with the signature chained so alteration is detectable. Because a published workflow version is frozen and a run stays on the version it began on, a sample released today was assessed against the protocol that was current when it started.

    What it uses: Re-authenticated chained signatures, on frozen workflow versions

  7. Recover the two-in-the-morning failure

    Every run is recorded step by step with the inputs, outputs, errors and the path taken, and runs are findable by the sample they concern. Recovery is restarting the single step that failed, rewinding to an earlier completed one, or replaying the run — not repeating the day by hand. A run whose conditions match nothing stops and waits for an operator rather than guessing.

    What it uses: Per-step run history, and restart, rewind, replay and cancel

  8. Turn a degrading partner down without a deploy

    When a partner laboratory or an instrument service degrades, that system — or one single action on it — is paused, stopped or rate-limited while runs are in flight, with a live view of what is currently held back. A step blocked by a rate limit waits and retries without spending a retry attempt.

    What it uses: Live per-system and per-action throttling

Numbers used above, and where they come from

Every figure on this site is counted from the product itself. Nothing here is a performance or customer claim, because there is no measurement to cite for one.

destinations for an event
4destinations for an eventCounted from egav/backend/app/api/v1/egav/lib/webhook/transports — http, sqs, sns, kafka
ways to decide who approves
7ways to decide who approvesCounted from egav-automation/backend/app/api/v1/automation/schemas/hitl_config_schemas.py — HitlAssignmentPolicy
places a choice list can come from
5places a choice list can come fromCounted from egav/backend/app/api/v1/egav/schemas/entity_type_attribute.py — OptionSourceType (file is reserved and not counted)

What changes

Every hop is visible in one place, a slow instrument stops shaping the architecture around it, partners integrate against a description generated from the model, and a failure at two in the morning is a step to restart rather than a day to repeat.

Written for Integration-heavy platforms.

Evaluate it with your real model

Bring the awkward record, the exception-heavy workflow and the integration you do not want to own. We will make the configuration-versus-code boundary explicit.