Skip to content

About

A pure-Rust openEHR form builder and renderer: operational templates in, forms out, validated compositions into any openEHR CDR

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

120 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

FerroCHART

CI CodeQL OpenSSF Scorecard License: BUSL-1.1

A pure-Rust openEHR form builder and renderer. It compiles an operational template into a form definition, renders that form for a clinician, and turns the entered values back into a COMPOSITION committed to an openEHR Clinical Data Repository. It reads compositions back into the same form, so one definition serves data entry, review, and editing.

It runs as its own server beside any openEHR CDR reached over the openEHR ITS-REST API, and uses any FHIR terminology server to expand the value sets behind coded fields.

Status: the round trip runs, and has never met a real CDR

What works today. Point it at an openEHR operational template and it produces a form definition: fields with their permitted units, value sets, date precisions and repeatability, derived from the Reference Model type and the constraint at each node. Both ADL generations are read. Measured against the 123 openEHR CKM templates this repository vendors, 121 read and all 121 derive a form, 2658 fields across 1789 groups.

The server publishes that definition, and a browser renders it. There is a control for every one of the eighteen field kinds the derivation produces, each admitting what its template admits and refusing the rest. A repeatable group adds and removes occurrences, and one the template says may be absent opens with none of it. A field can be given a reason instead of a value, an archetype slot the template left open says so as a place to add content, and a value the template never typed is drawn as a visible hole rather than dropped. What a clinician enters is validated against the operational template before any request is made, built into a COMPOSITION, posted to a CDR over ITS-REST, and read back into the same form.

What does not work yet. The layout overlay, which is half the product.

Its engine is built: the storage, the key normalization, the replay across a template revision, and the report of what matched, moved, disappeared or became ambiguous. Two things are missing. Nobody can author one, because the screen for it is not built. And the browser honours none of it, so the visibility rules the model already carries, the ones that would ask whether a person is deceased before asking when they died, do not reach a form. Until both land, a form is rendered in template order and shows every field the template admits.

The round trip runs against a real CDR on every pull request. The cdr job starts FerroEHR from the release's own compose.yaml, uploads a template to it, commits a COMPOSITION FerroCHART built and validated, reads it back and compares. It is the only lane that can falsify this project's central claim, so it is named in the required check rather than left to a script somebody remembers.

That lane has already earned its place: it found a COMPOSITION whose template identifier sat at the wrong node, which FerroEHR refused for 66 of 66 templates rooted below COMPOSITION while every mock in the suite accepted it.

The design of record is docs/architecture.md, the output of the research program on issue #1, where every decision carries a citation or an explicit note that no specification governs it. Section 14 is the build order, and the milestones track it.

Try it

A release publishes a compose.yaml you can run without cloning anything. FerroCHART talks to an openEHR CDR and a FHIR terminology server, so the default path needs both endpoints; the demo profile starts FerroEHR and FerroTERM alongside it instead. Compose reads both endpoints before it looks at a profile, so the demo still names them, pointing at the services it starts.

curl -LO https://github.com/FerroHEALTH/FerroCHART/releases/latest/download/compose.yaml
FERROCHART_CDR_URL=http://ferroehr:8080/ferroehr/rest/openehr \
FERROCHART_TERM_URL=http://ferroterm:8080/r4 \
  docker compose --profile demo up

The demo profile pulls three separately licensed images and exists for evaluation. Read the header of the file before running it anywhere real.

Every release asset is checksummed and carries a Sigstore attestation, so you can check where a binary came from before you trust it:

gh attestation verify ferrochart-v0.1.1-x86_64-unknown-linux-musl.tar.gz \
  --repo FerroHEALTH/FerroCHART \
  --signer-workflow FerroHEALTH/FerroCHART/.github/workflows/release-build.yml

Why this exists

openEHR separates the clinical model from the software, which is what makes the data outlive the vendor. The cost is that a template is not a screen: something has to turn an operational template into a form a nurse can fill in during a ward round, and turn what they typed back into a valid COMPOSITION.

The tooling that does this well is commercial. The open source options are thin enough that people running openEHR in a hospital build their own, one form at a time, or go without. That gap is the reason for this project, and it was named by the openEHR community rather than invented here.

What is decided

  • A form is compiled from its operational template. Field kinds come from the Reference Model type at each node: DV_QUANTITY becomes a number with a unit, DV_CODED_TEXT becomes a selection bound to a value set, a CLUSTER that may repeat becomes a repeatable group. No form is hand-written per template, and no field is hand-coded per archetype.
  • Hand-authored layout lives in a separate overlay, keyed by node identity. Templates get revised, and the layout, labels, help text, and visibility rules a person spent hours on must survive the revision. Recompile from the new template, replay the overlay, and report what matched, what disappeared, what moved and what became ambiguous. An editor that loses that work on a template update is the failure mode this design exists to avoid, and no tool surveyed for this project reports it.
  • Both ADL generations are read, and they normalize into one internal constraint model, so the field derivation is written once rather than once per generation.
  • The openEHR model comes from the published openehr-* crates, which are generated from the openEHR BMM schemas, rather than from a generator here.
  • Any CDR, over ITS-REST. FerroCHART is a client of the openEHR REST API, never a compile-time dependency of a CDR. It works against the CDR a hospital already runs. A form builder that works with only one CDR is no use to the people who asked for this.
  • Validation belongs on the server. Form data is validated against the operational template before a COMPOSITION is built, so a clinician gets an error on the field they got wrong rather than one rejection for the whole document.
  • Pure Rust. No JVM, and a single binary, like the rest of the family.
  • Business Source License 1.1. Free for non-commercial use, a commercial licence for production use in a business. See below.

Every decision above, with the reasoning and the citations behind it, is in docs/architecture.md §15, the decision register.

Licensing

FerroCHART is source-available under the Business Source License 1.1 (LICENSE, NOTICE), with no open-core tier: the compiler, the renderer, the server, and the tools are in this repository under the one licence, and nothing is held back to be sold back to you.

The licence lets you read, build, modify, and redistribute the source without a fee and without asking anyone, and it covers every non-production use: development, testing, evaluation, and prototyping. Production use is free for Non-Commercial Purposes, which the licence defines as personal use, academic or scientific research, teaching, and use by a non-profit organisation or public body that is not in the course of a business, does not deliver a service for payment, and is not for commercial advantage. Any other production use needs a commercial licence from the Licensor: a hospital, clinic, or care provider running FerroCHART for its patients needs one, and so does a vendor, integrator, or any company running it in production. Offering FerroCHART, or a work derived from it, to third parties as a hosted, managed, or embedded service that builds, renders, or captures health data, and selling, sublicensing, or otherwise distributing it for a fee on its own or inside another product, need a commercial licence in every case. Each version becomes Apache License 2.0 four years after that version is published. A commercial licence is arranged with Cadasto B.V., the Licensor, which handles the business side of FerroCHART: write to info@cadasto.com or use https://www.cadasto.com/contact/. Technical questions go to the maintainer named in MAINTAINERS.md.

Contributions carry the terms in CONTRIBUTING.md: you keep your copyright, and you grant the Licensor the relicensing right that keeps the work one work under one licensor. There is no separate agreement to sign. Vendored specifications and third-party material keep their upstream terms, recorded beside them.

The family

FerroCHART is one of the FerroHEALTH servers: FerroEHR stores the data, FerroTERM answers the terminology questions, FerroBRIDGE moves it to FHIR and OMOP, and FerroCHART is how it gets entered in the first place. Each runs on its own and against other people's servers.

Contributing

CONTRIBUTING.md has the rules, and the open issues are the worklist. While the engine is being built the most useful contribution is evidence: a specification citation, a measurement, or first-hand experience building and running clinical forms over openEHR. If you have watched a clinician use a form and seen where it failed them, that is worth more here than a pull request.

About

A pure-Rust openEHR form builder and renderer: operational templates in, forms out, validated compositions into any openEHR CDR

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages