SNOMED CT (Systematized Nomenclature of Medicine -- Clinical Terms) was installed and configured to provide structured clinical coding across the GP Booking App. This document records what was implemented, how it works, and what remains.
Three core SNOMED tables exist in the sector_gp database (aliased to dsp_clinic / dsp_clinic_dev depending on environment):
| Table | Rows | Source |
|---|---|---|
snomed_concepts |
529,392 | RF2 sct2_Concept_Full_*.txt |
snomed_descriptions |
1,567,909 | RF2 sct2_Description_Full_*.txt |
snomed_relationships |
3,548,588 | RF2 sct2_Relationship_Full_*.txt |
Key relationship type: 116680003 = Is a (attribute) — 628,834 active is_a relationships form the SNOMED hierarchy backbone.
| Table | Purpose | Migration |
|---|---|---|
snomed_descendants |
Pre-computed ancestor→descendant closure for fast hierarchy lookups (257,372 rows across 4 roots) | Manual SQL |
snomed_icd10_map |
SNOMED-to-ICD-10 billing cross-map (20 common mappings seeded) | 0015 |
drug_safety_rules |
Drug-disease contraindication rules (9 rules seeded) | 0016 |
drug_class_members |
Maps individual drug SNOMED IDs to drug class names for safety checks | 0017 |
Built for these hierarchy roots to enable context-aware search:
| Root ID | Label | Descendants |
|---|---|---|
404684003 |
Clinical finding (diagnoses) | 128,201 |
71388002 |
Procedure | 59,893 |
123037004 |
Body structure | 43,562 |
373873005 |
Pharmaceutical / biologic product | 25,716 |
195967001 |
Asthma | 126 |
63449007 |
Peptic ulcer disease | ... |
| (and 7 more safety-rule condition roots) |
What: Context-sensitive SNOMED autocomplete. When a user types in a diagnosis field, results are restricted to Clinical finding descendants. Drug search restricts to Pharmaceutical product descendants.
Files:
clinical_data/views.py → SnomedSearchView, refactored SnomedDrugSearchViewclinical_data/urls.py → snomed/search/, snomed/drugs/search/appointment_form.html, clinicalnote_form.html, prescription_form.html (both apps)API: GET /clinical/snomed/search/?q=<term>&hierarchy=<concept_id>
Status: ✅ Working and deployed. Tested via test-client domain.
What: After selecting a SNOMED concept, the app reads its attributes (Finding site, Laterality, Severity) from snomed_relationships and shows appropriate input fields. Selections are stored as JSON in snomed_attributes field. The clinical note textarea auto-populates with a formatted template.
Files:
clinical_data/views.py → SnomedConceptAttributesViewclinical_data/urls.py → snomed/<int:concept_id>/attributes/clinical_data/models.py → ClinicalNote.snomed_attributes (JSONField)clinicalnote_form.htmlAPI: GET /clinical/snomed/<concept_id>/attributes/
Status: ✅ Attributes panel displays, selections store to DB, textarea populates.
Status: ❌ Not implemented (not requested during this session).
What: Automatic mapping from SNOMED diagnosis codes to ICD-10 billing codes. Uses the snomed_icd10_map table. Displayed in the clinical note form auto-template.
Files:
clinical_data/views.py → SnomedICD10MapViewclinical_data/urls.py → snomed/<int:concept_id>/icd10/clinical_data/models.py → SnomedICD10Mapseed_icd10_mapAPI: GET /clinical/snomed/<concept_id>/icd10/
Status: ✅ API returns mapped codes. Displayed in clinical note template. 20 common mappings pre-seeded.
What: Drug-disease contraindication checking. When a clinician selects a drug on the prescription form, the app checks the patient's SNOMED-coded conditions against safety rules. Uses the drug_safety_rules table and drug_class_members mapping to determine which rules apply.
Files:
clinical_data/views.py → DrugSafetyCheckViewclinical_data/urls.py → drug-safety/check/<patient_id>/clinical_data/models.py → DrugSafetyRule, DrugClassMemberseed_safety_rulesprescription_form.htmlAPI: GET /clinical/drug-safety/check/<patient_id>/?drug_concept_id=<snomed_id>
Status: ⚠️ API and drug class mapping work. Alert displays correctly when patient has a matching disorder concept (not monitoring/finding subtypes — see known issues).
| Migration | Description |
|---|---|
0014_clinicalnote_snomed_attributes |
Adds JSON field to ClinicalNote |
0015_snomedicd10map |
Creates ICD-10 map table |
0016_drugsafetyrule |
Creates drug safety rules table |
0017_drugclassmember |
Creates drug-to-class mapping table |
Updated core/middleware.py to allow RECEPTIONIST role access to /clinical/snomed/ endpoints (needed for autocomplete on the appointment form):
'/clinical/snomed/': ['CLINICIAN', 'RECEPTIONIST', 'PRACTICE_MANAGER', 'ADMIN'],
test-client.gp.veripath.co.ukis_a descendant of Asthma (disorder). Clinical notes should use "Asthma (disorder)" (195967001) as the diagnosis.| Endpoint | Method | Purpose |
|---|---|---|
/clinical/snomed/search/ |
GET | Hierarchy-aware concept search |
/clinical/snomed/drugs/search/ |
GET | Drug product search (hierarchy-scoped) |
/clinical/snomed/<id>/attributes/ |
GET | Concept attribute lookup (Smart Templates) |
/clinical/snomed/<id>/icd10/ |
GET | ICD-10 billing code lookup |
/clinical/drug-safety/check/<patient_id>/ |
GET | Drug-disease safety check |
# Seed ICD-10 mappings
python manage.py seed_icd10_map
# Seed drug safety rules
python manage.py seed_safety_rules
| File | Purpose |
|---|---|
clinical_data/views.py |
All SNOMED API views |
clinical_data/urls.py |
API routes |
clinical_data/models.py |
SNOMED extension models |
clinical_data/forms.py |
ClinicalNoteForm with snomed_attributes |
core/middleware.py |
RBAC rules for /clinical/ paths |
templates/.../clinicalnote_form.html |
Smart Templates UI |
templates/.../appointment_form.html |
SNOMED autocomplete UI |
templates/.../prescription_form.html |
Safety alert UI |
dashboards/views/dashboards.py |
Clinician dashboard (practice context fix) |