Skip to main content

ehds_logging/
lib.rs

1// SPDX-FileCopyrightText: Cadasto B.V.
2// SPDX-License-Identifier: BUSL-1.1
3
4//! The European logging software component of an EHR system (Regulation (EU)
5//! 2025/327 Art 2(2)(o), Art 25(1), Annex II 3.2 to 3.4).
6//!
7//! The Regulation asks an EHR system that gives healthcare providers or
8//! other individuals access to personal electronic health data to record, on
9//! every access event or group of events, who accessed the data, which
10//! natural person, the categories of the data, when, and where the data came
11//! from (Annex II 3.2). This crate is that record and what classifies it:
12//!
13//! - [`record`]: the [`AccessRecord`](record::AccessRecord), with the data
14//!   subject and the purpose of use beside the five points of 3.2;
15//! - [`category`]: the Art 14(1) categories and the national categories a
16//!   deployment declares;
17//! - [`map`] and [`classify`]: the deployment's map from template and
18//!   archetype ids to categories, and the classification of one access by
19//!   the model ids of what it reached;
20//! - [`retention`]: how long a record is kept, by its categories and its
21//!   origins, never under the three years of Art 9(2);
22//! - [`label`]: the security labels a record carries for its categories and
23//!   its origins, so the store that holds it can limit who reads it
24//!   (Annex II 3.4);
25//! - [`emergency`]: the purposes of use a deployment declares as asserting
26//!   an access in the vital interests of the data subject (Art 11(5)), and
27//!   the mark of a record whose accessor declared one;
28//! - [`transformation`]: the record of a semantic transformation an access
29//!   applied, which rides on its access record (eHealth Network General
30//!   Guidelines Release 3.1 Art 6(3));
31//! - [`sink`]: where records go, and why one could not be stored;
32//! - `balp` (feature `balp`): the record written as an IHE BALP `AuditEvent`
33//!   through `ihe-atna`, and the sink over an `ihe-atna` audit recorder.
34//!
35//! The crate depends on no interoperability component and on nothing of the
36//! system that builds the records, so the logging component stays independent
37//! of the interoperability component (Art 2(2)(n), (o)).
38//!
39//! # Examples
40//!
41//! ```
42//! use std::collections::BTreeMap;
43//!
44//! use ehds_logging::category::Category;
45//! use ehds_logging::classify::{Basis, Evidence, RootObject};
46//! use ehds_logging::map::{CategoryMap, Declared};
47//!
48//! let templates = BTreeMap::from([(
49//!     "Example Lab Report.v1".to_owned(),
50//!     Declared::Codes(vec!["Laboratory-Reports".to_owned()]),
51//! )]);
52//! let map = CategoryMap::declare(&[], &templates, &BTreeMap::new())?;
53//! let read = RootObject {
54//!     template_id: Some("Example Lab Report.v1".to_owned()),
55//!     ..RootObject::default()
56//! };
57//! let classified = map.classify(&Evidence::reached(Basis::Returned, vec![read]));
58//! assert!(classified.categories().contains_key(&Category::MedicalTestResult));
59//! assert!(classified.unclassified().is_none());
60//! # Ok::<(), ehds_logging::map::MapError>(())
61//! ```
62
63#![doc(test(attr(deny(warnings))))]
64
65#[cfg(feature = "balp")]
66pub mod balp;
67pub mod category;
68pub mod classify;
69pub mod emergency;
70pub mod label;
71pub mod map;
72pub mod record;
73pub mod retention;
74pub mod sink;
75pub mod transformation;