Clinical Safety Rules Engine
Relevant source files
The following files were used as context for generating this wiki page:The Clinical Safety Rules Engine manages prescription safety by enforcing a catalogue of clinical rules (SR-01 to SR-22). It identifies potential hazards such as drug-drug interactions, allergies, and incorrect dosages during the consultation process. The engine categorizes risks by severity and determines if a clinical reason is required to override specific alerts.
Sources: README.md:32-32, packages/safety/src/catalogue.ts:1-7
Rule Catalogue and Severity
The engine utilizes a predefined catalogue of 22 safety rules. Each rule possesses a title, a severity level, an override requirement, and a tuning capability for clinics.
Severity Levels
The engine classifies alerts into three severity levels:
- block: Prevents the prescription from being finalized unless resolved or specifically overridden (if allowed).
- warn: Displays a warning to the clinician, often requiring a justification for the record.
- info: Provides supplemental information without interrupting the clinical workflow.
Sources: packages/safety/src/catalogue.ts:8-8, packages/safety/src/safety.test.ts:36-40
Detailed Safety Rules (SR-01 to SR-22)
| ID | Title | Severity | Reason Required | Clinic Tuning |
|---|---|---|---|---|
| SR-01 | Allergy — direct molecule match | block | override_not_allowed | no |
| SR-02 | Allergy — same drug class | block | override_not_allowed | no |
| SR-04 | Drug–drug interaction: contraindicated | block | if_overridable | no |
| SR-05 | Drug–drug interaction: major | warn | yes | no |
| SR-06 | Drug–drug interaction: moderate / minor | info | no | visibility_only |
| SR-09 | Drug–condition | warn | yes | no |
| SR-10 | Pregnancy — contraindicated | block | if_overridable | no |
| SR-12 | Child weight missing for weight-based drug | block | no | no |
| SR-14 | Maximum daily dose exceeded | block | if_overridable | no |
| SR-18 | Telemedicine: Prohibited list | block | never | no |
| SR-20 | Completeness: missing dose/freq/duration | block | never | no |
| SR-22 | Free-text medicine (not in master) | warn | no | no |
Sources: packages/safety/src/catalogue.ts:24-122
Resolution and Override Logic
The engine evaluates if clinical blocks are resolved before allowing a consultation to proceed. It distinguishes between overridable blocks and absolute blocks that cannot be bypassed.
Validation Flow
The hasUnresolvedBlock function determines if any active alerts prevent progress. If a block is overridable, the engine checks if the clinician provided an alertKey to signal an override. Non-overridable blocks (e.g., SR-01) persist even if an override is attempted.
This diagram shows how the engine processes alerts to decide if a clinician can proceed with a prescription.
Sources: packages/safety/src/safety.test.ts:36-52, packages/safety/src/catalogue.ts:127-135
Locked Rules
Specific rules are designated as "locked," meaning the system architecture prevents clinics from disabling or downgrading them. These rules typically represent critical safety violations, such as direct molecule allergy matches (SR-01) or telemedicine prohibitions (SR-18).
Sources: packages/safety/src/catalogue.ts:127-135, packages/safety/src/safety.test.ts:16-24
System Architecture
The safety engine is implemented as a standalone package (@dhc/safety) within the monorepo. This allows shared logic between the API and the web/mobile clients.
Component Interaction
During a consultation, the API routes handle requests for patient charts and consultation notes. The ClinicalService interacts with the safety rules to validate the inputs before saving encrypted clinical data.
The sequence diagram illustrates the validation handshake between the clinical service and the safety engine during note saving.
Sources: apps/api/src/modules/clinical/routes.ts:80-84, apps/api/test/clinical.int.test.ts:88-100, README.md:32-32
Data Structures
The engine relies on specific metadata types to define rule behavior.
| Type | Description | Values |
|---|---|---|
Severity | The impact level of the rule alert. | block, warn, info |
ReasonRequired | Determines when a clinician must justify an action. | override_not_allowed, if_overridable, yes, no, etc. |
ClinicTuning | Defines if a clinic can change rule settings. | no, visibility_only |
Sources: packages/safety/src/catalogue.ts:8-16
Implementation Details
The engine does not store hardcoded drug facts (e.g., specific interactions or pregnancy categories). It provides the structure for interpreting such data retrieved from a licensed drug database at runtime.
Key Functions
getSafetyRule(id): Retrieves the metadata for a specific rule ID.isLockedRule(id): Returns true if the rule cannot be modified by clinic settings.hasUnresolvedBlock(alerts, overrides): Logic to block or allow progress based on current alerts and user-provided overrides.
Sources: packages/safety/src/catalogue.ts:137-145, packages/safety/src/safety.test.ts:36-45