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//! - [`withheld`]: the holds a product keeps on resources it delays the
33//! person's access to (Art 3(3)), and the person's own access trail (Art 9)
34//! read without the records about a held resource until the hold ends;
35//! - `balp` (feature `balp`): the record written as an IHE BALP `AuditEvent`
36//! through `ihe-atna`, and the sink over an `ihe-atna` audit recorder.
37//!
38//! The crate depends on no interoperability component and on nothing of the
39//! system that builds the records, so the logging component stays independent
40//! of the interoperability component (Art 2(2)(n), (o)).
41//!
42//! # Examples
43//!
44//! ```
45//! use std::collections::BTreeMap;
46//!
47//! use ehds_logging::category::Category;
48//! use ehds_logging::classify::{Basis, Evidence, RootObject};
49//! use ehds_logging::map::{CategoryMap, Declared};
50//!
51//! let templates = BTreeMap::from([(
52//! "Example Lab Report.v1".to_owned(),
53//! Declared::Codes(vec!["Laboratory-Reports".to_owned()]),
54//! )]);
55//! let map = CategoryMap::declare(&[], &templates, &BTreeMap::new())?;
56//! let read = RootObject {
57//! template_id: Some("Example Lab Report.v1".to_owned()),
58//! ..RootObject::default()
59//! };
60//! let classified = map.classify(&Evidence::reached(Basis::Returned, vec![read]));
61//! assert!(classified.categories().contains_key(&Category::MedicalTestResult));
62//! assert!(classified.unclassified().is_none());
63//! # Ok::<(), ehds_logging::map::MapError>(())
64//! ```
65
66#![doc(test(attr(deny(warnings))))]
67
68#[cfg(feature = "balp")]
69pub mod balp;
70pub mod category;
71pub mod classify;
72pub mod emergency;
73pub mod label;
74pub mod map;
75pub mod record;
76pub mod retention;
77pub mod sink;
78pub mod transformation;
79pub mod withheld;