ehds-logging 0.2.0

The European logging software component of an EHR system under Regulation (EU) 2025/327: the Annex II 3.2 access record, the Article 14(1) categories and the map that classifies an access, and the record written as an IHE BALP AuditEvent
Documentation

ehds-logging

The European logging software component of an EHR system under Regulation (EU) 2025/327 (the European Health Data Space), in Rust: the record of every access to personal electronic health data that Annex II 3.2 asks for, and what classifies it.

  • record: the access record, with (a) the provider and (b) the natural person who accessed the data, (c) the categories, (d) the time and (e) the origins, beside the data subject and the purpose of use.
  • category: the six priority categories of Art 14(1) and the national categories a deployment declares.
  • map and classify: a deployment's map from openEHR template ids and archetype ids to categories (compared exactly, or case-insensitively as openEHR BASE asks, archetype keys held to the ARCHETYPE_ID grammar, every defect of a declaration reported at once), and the classification of one access by the model ids of what it delivered, read or wrote, or by the ids its request constrains its data to. An access the map cannot classify is marked unclassified with its ids as evidence; it is never refused for it.
  • retention: how long a record is kept, in years, in days or without end, per category and per origin, within bounds: never under the three years from each date of access of Art 9(2) inside the Union, over a national floor and under a ceiling the deployment names with their legal ground, and outside the Union over the floor its own law sets, which the record then names in place of Art 9(2). A record is kept for the longest its categories and origins call for, and the longest declared anywhere for an unclassified access. The record states the period, the first date it may be deleted on (none for a record kept without end), what called for it and the ground of its floor, so the store that holds it can apply it.
  • label: the security labels a record carries per category and per origin of the data (Annex II 3.4), by default each category's own code and each origin's endpoint in a code system the deployment names, and every category's label for an unclassified access, so the store that holds the record can limit who reads it.
  • sink: where records go, and the error a sink returns when it cannot store one.
  • balp (feature balp): the record written as an IHE BALP AuditEvent through the audit types of ihe-atna, and a sink over an ihe-atna audit recorder, such as one that spools records for an ATNA Audit Record Repository.

The crate ships no category map: the deployment authors it. It depends on no interoperability component and on no application.

The categories on the wire

Each category is a coded value, a system and a code in it, as a FHIR R4 Coding is. The six priority categories carry the codes of HL7 Europe's EEHRxFDocumentPriorityCategoryCS (hl7.fhir.eu.health-data-api 1.0.0-ballot), in the system http://hl7.eu/fhir/health-data-api/CodeSystem/eehrxf-document-priority-category-cs, version 1.0.0-ballot, compared case-sensitively:

Art 14(1) Code
(a) patient summaries Patient-Summaries
(b) electronic prescriptions Electronic-Prescriptions
(c) electronic dispensations Electronic-Dispensations
(d) medical imaging studies and related imaging reports Medical-Imaging
(e) medical test results, including laboratory and other diagnostic results and related reports Laboratory-Reports
(f) discharge reports Discharge-Reports

A national category (Art 14(1) third subparagraph) is its Member State's code in the absolute URI of that state's code system, held to the FHIR code rules. Where one string carries a category, as a BALP detail value does, it is <system>|<code>, the FHIR search token form, and the record names each code system's version once in ehds-category-version. "No category" and "unclassified" are states of the record, never categories, and the reasons an access is unclassified are a closed set: unmapped, named-nothing, unbound, operation-not-read, format-not-read, body-not-read and no-object-returned.

The integration tests pin this wire form for every product that writes the same record (tests/it/map.rs, tests/it/category.rs, tests/it/balp/), and hold the six codes to the vendored code system.

API stability

The crate is on the 0.x line, so a minor release may change its API. Its public API exposes these types of other crates, each a dependency a consumer must use at a compatible version:

  • jiff 0.2 (Timestamp on the record, Date on its retention), pre-1.0;
  • secrecy 0.10 (SecretString on a patient identifier and on the query text), pre-1.0;
  • async-trait 0.1, whose expansion is the signature of AccessSink, pre-1.0, kept because a trait with an async fn is not object-safe without it;
  • serde 1 (Deserialize on Declared) and url 2 (Url under balp), both stable;
  • ihe-atna (AuditRecorder and Exchange under balp), the sibling crate published from the same repository on the same version line, which this crate pins exactly.

A version of this crate that moves one of these to a new major version changes its own version.

Licence

Business Source License 1.1 (LICENSE in the repository, https://github.com/FerroHEALTH/FerroAUDIT): free for every non-production use and for non-commercial production use; a commercial licence for other production use; Apache License 2.0 four years after each version.