@the-cascade-protocol/cli 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.dockerignore +7 -0
- package/.eslintrc.json +23 -0
- package/.prettierrc +7 -0
- package/DOCKER.md +36 -0
- package/Dockerfile +18 -0
- package/README.md +69 -0
- package/dist/commands/capabilities.d.ts +9 -0
- package/dist/commands/capabilities.d.ts.map +1 -0
- package/dist/commands/capabilities.js +194 -0
- package/dist/commands/capabilities.js.map +1 -0
- package/dist/commands/conformance.d.ts +15 -0
- package/dist/commands/conformance.d.ts.map +1 -0
- package/dist/commands/conformance.js +348 -0
- package/dist/commands/conformance.js.map +1 -0
- package/dist/commands/convert.d.ts +21 -0
- package/dist/commands/convert.d.ts.map +1 -0
- package/dist/commands/convert.js +134 -0
- package/dist/commands/convert.js.map +1 -0
- package/dist/commands/pod/export.d.ts +8 -0
- package/dist/commands/pod/export.d.ts.map +1 -0
- package/dist/commands/pod/export.js +72 -0
- package/dist/commands/pod/export.js.map +1 -0
- package/dist/commands/pod/helpers.d.ts +79 -0
- package/dist/commands/pod/helpers.d.ts.map +1 -0
- package/dist/commands/pod/helpers.js +369 -0
- package/dist/commands/pod/helpers.js.map +1 -0
- package/dist/commands/pod/index.d.ts +20 -0
- package/dist/commands/pod/index.d.ts.map +1 -0
- package/dist/commands/pod/index.js +29 -0
- package/dist/commands/pod/index.js.map +1 -0
- package/dist/commands/pod/info.d.ts +9 -0
- package/dist/commands/pod/info.d.ts.map +1 -0
- package/dist/commands/pod/info.js +196 -0
- package/dist/commands/pod/info.js.map +1 -0
- package/dist/commands/pod/init.d.ts +9 -0
- package/dist/commands/pod/init.d.ts.map +1 -0
- package/dist/commands/pod/init.js +251 -0
- package/dist/commands/pod/init.js.map +1 -0
- package/dist/commands/pod/query.d.ts +9 -0
- package/dist/commands/pod/query.d.ts.map +1 -0
- package/dist/commands/pod/query.js +169 -0
- package/dist/commands/pod/query.js.map +1 -0
- package/dist/commands/pod 2.js +1017 -0
- package/dist/commands/pod.d.ts +28 -0
- package/dist/commands/pod.d.ts 2.map +1 -0
- package/dist/commands/pod.d.ts.map +1 -0
- package/dist/commands/pod.js +1031 -0
- package/dist/commands/pod.js 2.map +1 -0
- package/dist/commands/pod.js.map +1 -0
- package/dist/commands/serve.d.ts +33 -0
- package/dist/commands/serve.d.ts.map +1 -0
- package/dist/commands/serve.js +74 -0
- package/dist/commands/serve.js.map +1 -0
- package/dist/commands/validate.d.ts +18 -0
- package/dist/commands/validate.d.ts.map +1 -0
- package/dist/commands/validate.js +275 -0
- package/dist/commands/validate.js.map +1 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +49 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/fhir-converter/cascade-to-fhir.d.ts +17 -0
- package/dist/lib/fhir-converter/cascade-to-fhir.d.ts.map +1 -0
- package/dist/lib/fhir-converter/cascade-to-fhir.js +358 -0
- package/dist/lib/fhir-converter/cascade-to-fhir.js.map +1 -0
- package/dist/lib/fhir-converter/converters-clinical.d.ts +29 -0
- package/dist/lib/fhir-converter/converters-clinical.d.ts.map +1 -0
- package/dist/lib/fhir-converter/converters-clinical.js +391 -0
- package/dist/lib/fhir-converter/converters-clinical.js.map +1 -0
- package/dist/lib/fhir-converter/converters-demographics.d.ts +20 -0
- package/dist/lib/fhir-converter/converters-demographics.d.ts.map +1 -0
- package/dist/lib/fhir-converter/converters-demographics.js +242 -0
- package/dist/lib/fhir-converter/converters-demographics.js.map +1 -0
- package/dist/lib/fhir-converter/fhir-to-cascade.d.ts +17 -0
- package/dist/lib/fhir-converter/fhir-to-cascade.d.ts.map +1 -0
- package/dist/lib/fhir-converter/fhir-to-cascade.js +63 -0
- package/dist/lib/fhir-converter/fhir-to-cascade.js.map +1 -0
- package/dist/lib/fhir-converter/index.d.ts +36 -0
- package/dist/lib/fhir-converter/index.d.ts.map +1 -0
- package/dist/lib/fhir-converter/index.js +187 -0
- package/dist/lib/fhir-converter/index.js.map +1 -0
- package/dist/lib/fhir-converter/types.d.ts +77 -0
- package/dist/lib/fhir-converter/types.d.ts.map +1 -0
- package/dist/lib/fhir-converter/types.js +236 -0
- package/dist/lib/fhir-converter/types.js.map +1 -0
- package/dist/lib/fhir-converter.d.ts +62 -0
- package/dist/lib/fhir-converter.d.ts.map +1 -0
- package/dist/lib/fhir-converter.js +1474 -0
- package/dist/lib/fhir-converter.js.map +1 -0
- package/dist/lib/mcp/audit.d.ts +24 -0
- package/dist/lib/mcp/audit.d.ts.map +1 -0
- package/dist/lib/mcp/audit.js +85 -0
- package/dist/lib/mcp/audit.js.map +1 -0
- package/dist/lib/mcp/server.d.ts +38 -0
- package/dist/lib/mcp/server.d.ts.map +1 -0
- package/dist/lib/mcp/server.js +172 -0
- package/dist/lib/mcp/server.js.map +1 -0
- package/dist/lib/mcp/tools.d.ts +47 -0
- package/dist/lib/mcp/tools.d.ts.map +1 -0
- package/dist/lib/mcp/tools.js +547 -0
- package/dist/lib/mcp/tools.js.map +1 -0
- package/dist/lib/output.d.ts +26 -0
- package/dist/lib/output.d.ts.map +1 -0
- package/dist/lib/output.js +64 -0
- package/dist/lib/output.js.map +1 -0
- package/dist/lib/shacl-validator.d.ts +53 -0
- package/dist/lib/shacl-validator.d.ts.map +1 -0
- package/dist/lib/shacl-validator.js +245 -0
- package/dist/lib/shacl-validator.js.map +1 -0
- package/dist/lib/turtle-parser.d.ts +64 -0
- package/dist/lib/turtle-parser.d.ts.map +1 -0
- package/dist/lib/turtle-parser.js +236 -0
- package/dist/lib/turtle-parser.js.map +1 -0
- package/dist/shapes/checkup.shapes.ttl +1459 -0
- package/dist/shapes/clinical.shapes.ttl +1350 -0
- package/dist/shapes/clinical.ttl +1369 -0
- package/dist/shapes/core.shapes.ttl +450 -0
- package/dist/shapes/core.ttl +603 -0
- package/dist/shapes/coverage.shapes.ttl +214 -0
- package/dist/shapes/coverage.ttl +182 -0
- package/dist/shapes/health.shapes.ttl +697 -0
- package/dist/shapes/health.ttl +859 -0
- package/dist/shapes/pots.shapes.ttl +481 -0
- package/package.json +54 -0
- package/src/commands/capabilities.ts +235 -0
- package/src/commands/conformance.ts +447 -0
- package/src/commands/convert.ts +164 -0
- package/src/commands/pod/export.ts +85 -0
- package/src/commands/pod/helpers.ts +449 -0
- package/src/commands/pod/index.ts +32 -0
- package/src/commands/pod/info.ts +239 -0
- package/src/commands/pod/init.ts +273 -0
- package/src/commands/pod/query.ts +224 -0
- package/src/commands/serve.ts +92 -0
- package/src/commands/validate.ts +303 -0
- package/src/index.ts +58 -0
- package/src/lib/fhir-converter/cascade-to-fhir.ts +369 -0
- package/src/lib/fhir-converter/converters-clinical.ts +446 -0
- package/src/lib/fhir-converter/converters-demographics.ts +270 -0
- package/src/lib/fhir-converter/fhir-to-cascade.ts +82 -0
- package/src/lib/fhir-converter/index.ts +215 -0
- package/src/lib/fhir-converter/types.ts +318 -0
- package/src/lib/mcp/audit.ts +107 -0
- package/src/lib/mcp/server.ts +192 -0
- package/src/lib/mcp/tools.ts +668 -0
- package/src/lib/output.ts +76 -0
- package/src/lib/shacl-validator.ts +314 -0
- package/src/lib/turtle-parser.ts +277 -0
- package/src/shapes/checkup.shapes.ttl +1459 -0
- package/src/shapes/clinical.shapes.ttl +1350 -0
- package/src/shapes/clinical.ttl +1369 -0
- package/src/shapes/core.shapes.ttl +450 -0
- package/src/shapes/core.ttl +603 -0
- package/src/shapes/coverage.shapes.ttl +214 -0
- package/src/shapes/coverage.ttl +182 -0
- package/src/shapes/health.shapes.ttl +697 -0
- package/src/shapes/health.ttl +859 -0
- package/src/shapes/pots.shapes.ttl +481 -0
- package/test-fixtures/fhir-bundle-example.json +216 -0
- package/test-fixtures/fhir-medication-example.json +18 -0
- package/tests/cli.test.ts +126 -0
- package/tests/fhir-converter.test.ts +874 -0
- package/tests/mcp-server.test.ts +396 -0
- package/tests/pod.test.ts +400 -0
- package/tsconfig.json +24 -0
|
@@ -0,0 +1,1459 @@
|
|
|
1
|
+
@prefix sh: <http://www.w3.org/ns/shacl#> .
|
|
2
|
+
@prefix checkup: <https://ns.cascadeprotocol.org/checkup/v1#> .
|
|
3
|
+
@prefix cascade: <https://ns.cascadeprotocol.org/core/v1#> .
|
|
4
|
+
@prefix health: <https://ns.cascadeprotocol.org/health/v1#> .
|
|
5
|
+
@prefix clinical: <https://ns.cascadeprotocol.org/clinical/v1#> .
|
|
6
|
+
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
|
|
7
|
+
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
|
|
8
|
+
|
|
9
|
+
# ============================================================================
|
|
10
|
+
# CASCADE CHECKUP SHACL SHAPES - ADULT (Ages 18-64)
|
|
11
|
+
# ============================================================================
|
|
12
|
+
# Version: 2.0
|
|
13
|
+
# Created: 2026-01-03
|
|
14
|
+
# Modified: 2026-02-18 (v2.0: Shapes for v1.5-v2.0 ontology classes)
|
|
15
|
+
#
|
|
16
|
+
# SEVERITY LEVELS:
|
|
17
|
+
# - sh:Violation = Must fix (blocks export) - e.g., missing patient name
|
|
18
|
+
# - sh:Warning = Should address (shown prominently) - e.g., no allergies listed
|
|
19
|
+
# - sh:Info = Nice to have (suggestions) - e.g., incomplete family history
|
|
20
|
+
#
|
|
21
|
+
# PHASE 7 ADDITIONS:
|
|
22
|
+
# - Extended MedicationSummaryShape with episode linkage and patient meaning fields
|
|
23
|
+
# - Added SupplementSummaryShape with regulatory classification requirements
|
|
24
|
+
# - Added hasSupplement validation to IntakeFormData
|
|
25
|
+
#
|
|
26
|
+
# v1.6 ADDITIONS:
|
|
27
|
+
# - Added IntakeQuestionnaireResponseShape with LOINC panel code validation
|
|
28
|
+
# - Added ResponseItemShape with question text validation
|
|
29
|
+
# - Added hasQuestionnaireResponse validation to IntakeFormData
|
|
30
|
+
#
|
|
31
|
+
# v2.0 ADDITIONS (WS8 - Shapes for v1.5-v2.0 ontology classes):
|
|
32
|
+
# - Added DailyCheckInShape with SelfReport inheritance via sh:node
|
|
33
|
+
# - Added ImmunizationSummaryShape with vaccine validation
|
|
34
|
+
# - Added LabResultSummaryShape with mixed namespace (clinical:/checkup:)
|
|
35
|
+
# - Added ProcedureSummaryShape with mixed namespace (clinical:/checkup:)
|
|
36
|
+
# - Added DiscussionTopicShape with category and relevance validation
|
|
37
|
+
# - Added hasDailyCheckIn, hasDiscussionTopic, hasImmunization,
|
|
38
|
+
# hasLabResult, hasProcedure aggregate links to IntakeFormDataShape
|
|
39
|
+
# - Added health: and clinical: prefix declarations
|
|
40
|
+
# ============================================================================
|
|
41
|
+
|
|
42
|
+
# ============================================================================
|
|
43
|
+
# INTAKE FORM DATA SHAPE (Top-level validation)
|
|
44
|
+
# ============================================================================
|
|
45
|
+
|
|
46
|
+
checkup:IntakeFormDataShape a sh:NodeShape ;
|
|
47
|
+
sh:targetClass checkup:IntakeFormData ;
|
|
48
|
+
rdfs:label "Intake Form Data Validation" ;
|
|
49
|
+
rdfs:comment "Validates completeness of intake form data for adult patients (18-64)" ;
|
|
50
|
+
|
|
51
|
+
# Required: Patient Profile
|
|
52
|
+
sh:property [
|
|
53
|
+
sh:path checkup:hasPatientProfile ;
|
|
54
|
+
sh:minCount 1 ;
|
|
55
|
+
sh:maxCount 1 ;
|
|
56
|
+
sh:node checkup:PatientProfileShape ;
|
|
57
|
+
sh:severity sh:Violation ;
|
|
58
|
+
sh:message "Patient profile is required for intake forms"
|
|
59
|
+
] ;
|
|
60
|
+
|
|
61
|
+
# Required: Schema version
|
|
62
|
+
sh:property [
|
|
63
|
+
sh:path checkup:schemaVersion ;
|
|
64
|
+
sh:minCount 1 ;
|
|
65
|
+
sh:datatype xsd:string ;
|
|
66
|
+
sh:severity sh:Violation ;
|
|
67
|
+
sh:message "Schema version is required"
|
|
68
|
+
] ;
|
|
69
|
+
|
|
70
|
+
# Required: Generation timestamp
|
|
71
|
+
sh:property [
|
|
72
|
+
sh:path checkup:generatedAt ;
|
|
73
|
+
sh:minCount 1 ;
|
|
74
|
+
sh:datatype xsd:dateTime ;
|
|
75
|
+
sh:severity sh:Violation ;
|
|
76
|
+
sh:message "Generation timestamp is required"
|
|
77
|
+
] ;
|
|
78
|
+
|
|
79
|
+
# Warning: Medications
|
|
80
|
+
sh:property [
|
|
81
|
+
sh:path checkup:hasMedication ;
|
|
82
|
+
sh:minCount 0 ;
|
|
83
|
+
sh:node checkup:MedicationSummaryShape ;
|
|
84
|
+
sh:severity sh:Warning ;
|
|
85
|
+
sh:message "Medication list helps providers avoid drug interactions. Add your current medications or confirm 'None'."
|
|
86
|
+
] ;
|
|
87
|
+
|
|
88
|
+
# Info: Supplements (Phase 3 - separate from medications)
|
|
89
|
+
sh:property [
|
|
90
|
+
sh:path checkup:hasSupplement ;
|
|
91
|
+
sh:minCount 0 ;
|
|
92
|
+
sh:node checkup:SupplementSummaryShape ;
|
|
93
|
+
sh:severity sh:Info ;
|
|
94
|
+
sh:message "Supplements and OTC products can interact with medications. Consider listing supplements separately from prescription medications."
|
|
95
|
+
] ;
|
|
96
|
+
|
|
97
|
+
# Warning: Allergies
|
|
98
|
+
sh:property [
|
|
99
|
+
sh:path checkup:hasAllergy ;
|
|
100
|
+
sh:minCount 0 ;
|
|
101
|
+
sh:node checkup:AllergySummaryShape ;
|
|
102
|
+
sh:severity sh:Warning ;
|
|
103
|
+
sh:message "Allergy information helps prevent adverse reactions. Add allergies or confirm 'No Known Drug Allergies (NKDA)'."
|
|
104
|
+
] ;
|
|
105
|
+
|
|
106
|
+
# Warning: Insurance
|
|
107
|
+
sh:property [
|
|
108
|
+
sh:path checkup:hasInsurance ;
|
|
109
|
+
sh:minCount 0 ;
|
|
110
|
+
sh:maxCount 1 ;
|
|
111
|
+
sh:node checkup:InsuranceInfoShape ;
|
|
112
|
+
sh:severity sh:Warning ;
|
|
113
|
+
sh:message "Insurance information is usually required for office visits. Add insurance or select 'Self-Pay'."
|
|
114
|
+
] ;
|
|
115
|
+
|
|
116
|
+
# Warning: Conditions
|
|
117
|
+
sh:property [
|
|
118
|
+
sh:path checkup:hasCondition ;
|
|
119
|
+
sh:minCount 0 ;
|
|
120
|
+
sh:node checkup:ConditionSummaryShape ;
|
|
121
|
+
sh:severity sh:Warning ;
|
|
122
|
+
sh:message "Active conditions help providers understand your health history. Add conditions or confirm 'None'."
|
|
123
|
+
] ;
|
|
124
|
+
|
|
125
|
+
# Info: Family History
|
|
126
|
+
sh:property [
|
|
127
|
+
sh:path checkup:hasFamilyHistory ;
|
|
128
|
+
sh:minCount 0 ;
|
|
129
|
+
sh:node checkup:FamilyHistoryEntryShape ;
|
|
130
|
+
sh:severity sh:Info ;
|
|
131
|
+
sh:message "Family history helps assess risk for certain conditions. Consider adding health history for parents and siblings."
|
|
132
|
+
] ;
|
|
133
|
+
|
|
134
|
+
# Info: Vital Signs Trends
|
|
135
|
+
sh:property [
|
|
136
|
+
sh:path checkup:hasVitalsTrend ;
|
|
137
|
+
sh:minCount 0 ;
|
|
138
|
+
sh:node checkup:VitalSignsTrendShape ;
|
|
139
|
+
sh:severity sh:Info ;
|
|
140
|
+
sh:message "Recent vital signs provide context for your current health status."
|
|
141
|
+
] ;
|
|
142
|
+
|
|
143
|
+
# Info: Screening Status
|
|
144
|
+
sh:property [
|
|
145
|
+
sh:path checkup:hasScreening ;
|
|
146
|
+
sh:minCount 0 ;
|
|
147
|
+
sh:node checkup:ScreeningStatusShape ;
|
|
148
|
+
sh:severity sh:Info ;
|
|
149
|
+
sh:message "Tracking preventive screenings helps you stay current with recommended care."
|
|
150
|
+
] ;
|
|
151
|
+
|
|
152
|
+
# Info: Visit Issues
|
|
153
|
+
sh:property [
|
|
154
|
+
sh:path checkup:hasVisitIssue ;
|
|
155
|
+
sh:minCount 0 ;
|
|
156
|
+
sh:node checkup:VisitIssueShape ;
|
|
157
|
+
sh:severity sh:Info ;
|
|
158
|
+
sh:message "Adding issues you want to discuss helps you make the most of your appointment."
|
|
159
|
+
] ;
|
|
160
|
+
|
|
161
|
+
# Info: Diagnostic Results
|
|
162
|
+
sh:property [
|
|
163
|
+
sh:path checkup:hasDiagnosticResult ;
|
|
164
|
+
sh:minCount 0 ;
|
|
165
|
+
sh:node checkup:DiagnosticTestResultShape ;
|
|
166
|
+
sh:severity sh:Info ;
|
|
167
|
+
sh:message "Including recent diagnostic tests gives your provider valuable context."
|
|
168
|
+
] ;
|
|
169
|
+
|
|
170
|
+
# Info: Intake Questionnaires (v1.6)
|
|
171
|
+
sh:property [
|
|
172
|
+
sh:path checkup:hasQuestionnaireResponse ;
|
|
173
|
+
sh:minCount 0 ;
|
|
174
|
+
sh:node checkup:IntakeQuestionnaireResponseShape ;
|
|
175
|
+
sh:severity sh:Info ;
|
|
176
|
+
sh:message "Consider completing intake questionnaires for a more complete health profile."
|
|
177
|
+
] ;
|
|
178
|
+
|
|
179
|
+
# Info: Daily Check-ins (v2.0)
|
|
180
|
+
sh:property [
|
|
181
|
+
sh:path checkup:hasDailyCheckIn ;
|
|
182
|
+
sh:minCount 0 ;
|
|
183
|
+
sh:node checkup:DailyCheckInShape ;
|
|
184
|
+
sh:severity sh:Info ;
|
|
185
|
+
sh:message "Daily medication check-ins help track adherence patterns for your provider."
|
|
186
|
+
] ;
|
|
187
|
+
|
|
188
|
+
# Info: Discussion Topics (v2.0)
|
|
189
|
+
sh:property [
|
|
190
|
+
sh:path checkup:hasDiscussionTopic ;
|
|
191
|
+
sh:minCount 0 ;
|
|
192
|
+
sh:node checkup:DiscussionTopicShape ;
|
|
193
|
+
sh:severity sh:Info ;
|
|
194
|
+
sh:message "Discussion topics help prioritize what to cover during your appointment."
|
|
195
|
+
] ;
|
|
196
|
+
|
|
197
|
+
# Info: Immunizations (v2.0)
|
|
198
|
+
sh:property [
|
|
199
|
+
sh:path checkup:hasImmunization ;
|
|
200
|
+
sh:minCount 0 ;
|
|
201
|
+
sh:node checkup:ImmunizationSummaryShape ;
|
|
202
|
+
sh:severity sh:Info ;
|
|
203
|
+
sh:message "Including immunization records helps your provider review your vaccination status."
|
|
204
|
+
] ;
|
|
205
|
+
|
|
206
|
+
# Info: Lab Results (v2.0)
|
|
207
|
+
sh:property [
|
|
208
|
+
sh:path checkup:hasLabResult ;
|
|
209
|
+
sh:minCount 0 ;
|
|
210
|
+
sh:node checkup:LabResultSummaryShape ;
|
|
211
|
+
sh:severity sh:Info ;
|
|
212
|
+
sh:message "Recent lab results give your provider context about your current health status."
|
|
213
|
+
] ;
|
|
214
|
+
|
|
215
|
+
# Info: Procedures (v2.0)
|
|
216
|
+
sh:property [
|
|
217
|
+
sh:path checkup:hasProcedure ;
|
|
218
|
+
sh:minCount 0 ;
|
|
219
|
+
sh:node checkup:ProcedureSummaryShape ;
|
|
220
|
+
sh:severity sh:Info ;
|
|
221
|
+
sh:message "Procedure history helps your provider understand your surgical and diagnostic background."
|
|
222
|
+
] .
|
|
223
|
+
|
|
224
|
+
# ============================================================================
|
|
225
|
+
# PATIENT PROFILE SHAPE (Critical - blocks export if invalid)
|
|
226
|
+
# ============================================================================
|
|
227
|
+
|
|
228
|
+
checkup:PatientProfileShape a sh:NodeShape ;
|
|
229
|
+
sh:targetClass checkup:PatientProfile ;
|
|
230
|
+
rdfs:label "Patient Profile Validation" ;
|
|
231
|
+
rdfs:comment "Validates required patient demographics" ;
|
|
232
|
+
|
|
233
|
+
# VIOLATION: Patient name required
|
|
234
|
+
sh:property [
|
|
235
|
+
sh:path checkup:patientName ;
|
|
236
|
+
sh:minCount 1 ;
|
|
237
|
+
sh:datatype xsd:string ;
|
|
238
|
+
sh:minLength 2 ;
|
|
239
|
+
sh:severity sh:Violation ;
|
|
240
|
+
sh:message "Patient name is required for intake forms"
|
|
241
|
+
] ;
|
|
242
|
+
|
|
243
|
+
# VIOLATION: Date of birth required
|
|
244
|
+
sh:property [
|
|
245
|
+
sh:path checkup:dateOfBirth ;
|
|
246
|
+
sh:minCount 1 ;
|
|
247
|
+
sh:datatype xsd:date ;
|
|
248
|
+
sh:severity sh:Violation ;
|
|
249
|
+
sh:message "Date of birth is required for intake forms"
|
|
250
|
+
] ;
|
|
251
|
+
|
|
252
|
+
# VIOLATION: Biological sex required (for screening recommendations)
|
|
253
|
+
sh:property [
|
|
254
|
+
sh:path checkup:biologicalSex ;
|
|
255
|
+
sh:minCount 1 ;
|
|
256
|
+
sh:datatype xsd:string ;
|
|
257
|
+
sh:in ( "male" "female" "intersex" ) ;
|
|
258
|
+
sh:severity sh:Violation ;
|
|
259
|
+
sh:message "Biological sex is required for medical screening recommendations"
|
|
260
|
+
] ;
|
|
261
|
+
|
|
262
|
+
# WARNING: Contact phone recommended
|
|
263
|
+
sh:property [
|
|
264
|
+
sh:path checkup:contactPhone ;
|
|
265
|
+
sh:minCount 0 ;
|
|
266
|
+
sh:datatype xsd:string ;
|
|
267
|
+
sh:severity sh:Warning ;
|
|
268
|
+
sh:message "Contact phone number is typically required by healthcare providers"
|
|
269
|
+
] ;
|
|
270
|
+
|
|
271
|
+
# INFO: Emergency contact suggested
|
|
272
|
+
sh:property [
|
|
273
|
+
sh:path checkup:emergencyContact ;
|
|
274
|
+
sh:minCount 0 ;
|
|
275
|
+
sh:datatype xsd:string ;
|
|
276
|
+
sh:severity sh:Info ;
|
|
277
|
+
sh:message "Consider adding an emergency contact"
|
|
278
|
+
] ;
|
|
279
|
+
|
|
280
|
+
# Computed age must be valid integer
|
|
281
|
+
sh:property [
|
|
282
|
+
sh:path checkup:computedAge ;
|
|
283
|
+
sh:datatype xsd:integer ;
|
|
284
|
+
sh:minInclusive 18 ;
|
|
285
|
+
sh:maxInclusive 64 ;
|
|
286
|
+
sh:severity sh:Warning ;
|
|
287
|
+
sh:message "Age should be between 18-64 for adult shapes (use senior shapes for 65+)"
|
|
288
|
+
] ;
|
|
289
|
+
|
|
290
|
+
# Age group must be valid
|
|
291
|
+
sh:property [
|
|
292
|
+
sh:path checkup:ageGroup ;
|
|
293
|
+
sh:in ( "young_adult" "adult" ) ;
|
|
294
|
+
sh:severity sh:Info ;
|
|
295
|
+
sh:message "Age group should be young_adult (18-39) or adult (40-64)"
|
|
296
|
+
] ;
|
|
297
|
+
|
|
298
|
+
# Gender identity is optional but validated if present
|
|
299
|
+
sh:property [
|
|
300
|
+
sh:path checkup:genderIdentity ;
|
|
301
|
+
sh:in ( "woman" "man" "non_binary" "other" "prefer_not_to_say" ) ;
|
|
302
|
+
sh:severity sh:Info ;
|
|
303
|
+
sh:message "Gender identity must be a valid option if provided"
|
|
304
|
+
] .
|
|
305
|
+
|
|
306
|
+
# ============================================================================
|
|
307
|
+
# INSURANCE INFO SHAPE
|
|
308
|
+
# ============================================================================
|
|
309
|
+
|
|
310
|
+
checkup:InsuranceInfoShape a sh:NodeShape ;
|
|
311
|
+
sh:targetClass checkup:InsuranceInfo ;
|
|
312
|
+
rdfs:label "Insurance Information Validation" ;
|
|
313
|
+
rdfs:comment "Validates insurance details for intake forms" ;
|
|
314
|
+
|
|
315
|
+
# WARNING: Provider name required if insurance section exists
|
|
316
|
+
sh:property [
|
|
317
|
+
sh:path checkup:insuranceProvider ;
|
|
318
|
+
sh:minCount 1 ;
|
|
319
|
+
sh:datatype xsd:string ;
|
|
320
|
+
sh:severity sh:Warning ;
|
|
321
|
+
sh:message "Insurance provider name is required"
|
|
322
|
+
] ;
|
|
323
|
+
|
|
324
|
+
# WARNING: Member ID required
|
|
325
|
+
sh:property [
|
|
326
|
+
sh:path checkup:memberId ;
|
|
327
|
+
sh:minCount 1 ;
|
|
328
|
+
sh:datatype xsd:string ;
|
|
329
|
+
sh:severity sh:Warning ;
|
|
330
|
+
sh:message "Member ID / Policy number is required for insurance verification"
|
|
331
|
+
] ;
|
|
332
|
+
|
|
333
|
+
# Coverage type must be valid
|
|
334
|
+
sh:property [
|
|
335
|
+
sh:path checkup:coverageType ;
|
|
336
|
+
sh:in ( "hmo" "ppo" "epo" "pos" "medicare" "medicaid" "tricare" "self_pay" "other" ) ;
|
|
337
|
+
sh:severity sh:Info ;
|
|
338
|
+
sh:message "Coverage type should be a recognized plan type"
|
|
339
|
+
] ;
|
|
340
|
+
|
|
341
|
+
# INFO: PCP recommended
|
|
342
|
+
sh:property [
|
|
343
|
+
sh:path checkup:primaryCareProvider ;
|
|
344
|
+
sh:minCount 0 ;
|
|
345
|
+
sh:datatype xsd:string ;
|
|
346
|
+
sh:severity sh:Info ;
|
|
347
|
+
sh:message "Primary care provider name is helpful for care coordination"
|
|
348
|
+
] .
|
|
349
|
+
|
|
350
|
+
# ============================================================================
|
|
351
|
+
# MEDICATION SUMMARY SHAPE (Extended v1.2 - Phase 3 Medication Ontology)
|
|
352
|
+
# ============================================================================
|
|
353
|
+
|
|
354
|
+
checkup:MedicationSummaryShape a sh:NodeShape ;
|
|
355
|
+
sh:targetClass checkup:MedicationSummary ;
|
|
356
|
+
rdfs:label "Medication Summary Validation" ;
|
|
357
|
+
rdfs:comment "Validates medication entries with adherence data and episode linkage (Phase 3 extended)" ;
|
|
358
|
+
|
|
359
|
+
# WARNING: Medication name required
|
|
360
|
+
sh:property [
|
|
361
|
+
sh:path checkup:medicationName ;
|
|
362
|
+
sh:minCount 1 ;
|
|
363
|
+
sh:datatype xsd:string ;
|
|
364
|
+
sh:minLength 2 ;
|
|
365
|
+
sh:severity sh:Warning ;
|
|
366
|
+
sh:message "Medication name is required"
|
|
367
|
+
] ;
|
|
368
|
+
|
|
369
|
+
# INFO: Dose recommended
|
|
370
|
+
sh:property [
|
|
371
|
+
sh:path checkup:dose ;
|
|
372
|
+
sh:minCount 0 ;
|
|
373
|
+
sh:datatype xsd:string ;
|
|
374
|
+
sh:severity sh:Info ;
|
|
375
|
+
sh:message "Including the dose helps prevent medication errors"
|
|
376
|
+
] ;
|
|
377
|
+
|
|
378
|
+
# INFO: Frequency recommended
|
|
379
|
+
sh:property [
|
|
380
|
+
sh:path checkup:frequency ;
|
|
381
|
+
sh:in ( "once_daily" "twice_daily" "three_times_daily" "four_times_daily" "as_needed" "weekly" "monthly" "other" ) ;
|
|
382
|
+
sh:severity sh:Info ;
|
|
383
|
+
sh:message "Frequency should be a recognized dosing schedule"
|
|
384
|
+
] ;
|
|
385
|
+
|
|
386
|
+
# Adherence status must be valid if present
|
|
387
|
+
sh:property [
|
|
388
|
+
sh:path checkup:adherenceStatus ;
|
|
389
|
+
sh:in ( "taking_as_prescribed" "usually_take" "sometimes_miss" "often_miss" "stopped" ) ;
|
|
390
|
+
sh:severity sh:Info ;
|
|
391
|
+
sh:message "Adherence status must be a recognized value"
|
|
392
|
+
] ;
|
|
393
|
+
|
|
394
|
+
# Adherence barrier must be valid if present
|
|
395
|
+
sh:property [
|
|
396
|
+
sh:path checkup:adherenceBarrier ;
|
|
397
|
+
sh:in ( "cost" "side_effects" "forgetfulness" "access" "complexity" "other" "none" ) ;
|
|
398
|
+
sh:severity sh:Info ;
|
|
399
|
+
sh:message "Adherence barrier must be a recognized value"
|
|
400
|
+
] ;
|
|
401
|
+
|
|
402
|
+
# Effectiveness must be valid if present
|
|
403
|
+
sh:property [
|
|
404
|
+
sh:path checkup:perceivedEffectiveness ;
|
|
405
|
+
sh:in ( "very_effective" "somewhat_effective" "not_sure" "not_effective" ) ;
|
|
406
|
+
sh:severity sh:Info ;
|
|
407
|
+
sh:message "Perceived effectiveness must be a recognized value"
|
|
408
|
+
] ;
|
|
409
|
+
|
|
410
|
+
# Phase 3: Episode linkage (recommended for traceability)
|
|
411
|
+
sh:property [
|
|
412
|
+
sh:path checkup:episodeId ;
|
|
413
|
+
sh:datatype xsd:string ;
|
|
414
|
+
sh:maxCount 1 ;
|
|
415
|
+
sh:severity sh:Info ;
|
|
416
|
+
sh:name "Episode ID" ;
|
|
417
|
+
sh:message "Linking to MedicationUseEpisode enables longitudinal tracking"
|
|
418
|
+
] ;
|
|
419
|
+
|
|
420
|
+
# Phase 3: Start date
|
|
421
|
+
sh:property [
|
|
422
|
+
sh:path checkup:startDate ;
|
|
423
|
+
sh:datatype xsd:date ;
|
|
424
|
+
sh:maxCount 1 ;
|
|
425
|
+
sh:severity sh:Info ;
|
|
426
|
+
sh:name "Start Date" ;
|
|
427
|
+
sh:message "Start date helps track medication duration"
|
|
428
|
+
] ;
|
|
429
|
+
|
|
430
|
+
# Phase 3: Indication (why patient takes it)
|
|
431
|
+
sh:property [
|
|
432
|
+
sh:path checkup:indication ;
|
|
433
|
+
sh:datatype xsd:string ;
|
|
434
|
+
sh:maxCount 1 ;
|
|
435
|
+
sh:severity sh:Info ;
|
|
436
|
+
sh:name "Indication" ;
|
|
437
|
+
sh:message "Understanding why patient takes medication improves clinical context"
|
|
438
|
+
] ;
|
|
439
|
+
|
|
440
|
+
# Phase 3: Patient cost
|
|
441
|
+
sh:property [
|
|
442
|
+
sh:path checkup:patientCost ;
|
|
443
|
+
sh:datatype xsd:decimal ;
|
|
444
|
+
sh:maxCount 1 ;
|
|
445
|
+
sh:minInclusive 0 ;
|
|
446
|
+
sh:severity sh:Info ;
|
|
447
|
+
sh:name "Patient Cost" ;
|
|
448
|
+
sh:message "Cost tracking helps identify financial barriers"
|
|
449
|
+
] ;
|
|
450
|
+
|
|
451
|
+
# Phase 3: Cost frequency
|
|
452
|
+
sh:property [
|
|
453
|
+
sh:path checkup:costFrequency ;
|
|
454
|
+
sh:in ( "per_month" "per_refill" "per_dose" "per_bottle" "annual" ) ;
|
|
455
|
+
sh:maxCount 1 ;
|
|
456
|
+
sh:severity sh:Info ;
|
|
457
|
+
sh:name "Cost Frequency" ;
|
|
458
|
+
sh:message "Cost frequency should be a recognized value"
|
|
459
|
+
] ;
|
|
460
|
+
|
|
461
|
+
# Phase 3: Functional impact
|
|
462
|
+
sh:property [
|
|
463
|
+
sh:path checkup:functionalImpact ;
|
|
464
|
+
sh:datatype xsd:string ;
|
|
465
|
+
sh:maxCount 1 ;
|
|
466
|
+
sh:severity sh:Info ;
|
|
467
|
+
sh:name "Functional Impact" ;
|
|
468
|
+
sh:message "How medication helps patient functionally (e.g., 'helps me sleep')"
|
|
469
|
+
] ;
|
|
470
|
+
|
|
471
|
+
# Phase 3: Concerns for doctor
|
|
472
|
+
sh:property [
|
|
473
|
+
sh:path checkup:concernsForDoctor ;
|
|
474
|
+
sh:datatype xsd:string ;
|
|
475
|
+
sh:maxCount 1 ;
|
|
476
|
+
sh:severity sh:Info ;
|
|
477
|
+
sh:name "Concerns For Doctor" ;
|
|
478
|
+
sh:message "Concerns patient wants to discuss with provider"
|
|
479
|
+
] .
|
|
480
|
+
|
|
481
|
+
# ============================================================================
|
|
482
|
+
# SUPPLEMENT SUMMARY SHAPE (v1.1 - Phase 3 Medication Ontology)
|
|
483
|
+
# ============================================================================
|
|
484
|
+
|
|
485
|
+
checkup:SupplementSummaryShape a sh:NodeShape ;
|
|
486
|
+
sh:targetClass checkup:SupplementSummary ;
|
|
487
|
+
rdfs:label "Supplement Summary Validation" ;
|
|
488
|
+
rdfs:comment "Validates supplement entries with regulatory classification. Explicitly separate from medications per Cascade Protocol." ;
|
|
489
|
+
|
|
490
|
+
# WARNING: Supplement name required
|
|
491
|
+
sh:property [
|
|
492
|
+
sh:path checkup:supplementName ;
|
|
493
|
+
sh:minCount 1 ;
|
|
494
|
+
sh:datatype xsd:string ;
|
|
495
|
+
sh:minLength 2 ;
|
|
496
|
+
sh:severity sh:Warning ;
|
|
497
|
+
sh:message "Supplement name is required"
|
|
498
|
+
] ;
|
|
499
|
+
|
|
500
|
+
# REQUIRED: Regulatory status (distinguishes from FDA-approved medications)
|
|
501
|
+
sh:property [
|
|
502
|
+
sh:path checkup:regulatoryStatus ;
|
|
503
|
+
sh:minCount 1 ;
|
|
504
|
+
sh:in ( "dietarySupplement" "otcDrug" "homeopathic" "herbalRemedy" "unknown" ) ;
|
|
505
|
+
sh:severity sh:Warning ;
|
|
506
|
+
sh:name "Regulatory Status" ;
|
|
507
|
+
sh:message "Regulatory status is required to distinguish supplements from FDA-approved medications"
|
|
508
|
+
] ;
|
|
509
|
+
|
|
510
|
+
# INFO: Dose recommended
|
|
511
|
+
sh:property [
|
|
512
|
+
sh:path checkup:supplementDose ;
|
|
513
|
+
sh:minCount 0 ;
|
|
514
|
+
sh:datatype xsd:string ;
|
|
515
|
+
sh:severity sh:Info ;
|
|
516
|
+
sh:message "Including the dose helps track supplement intake"
|
|
517
|
+
] ;
|
|
518
|
+
|
|
519
|
+
# INFO: Frequency recommended
|
|
520
|
+
sh:property [
|
|
521
|
+
sh:path checkup:supplementFrequency ;
|
|
522
|
+
sh:in ( "once_daily" "twice_daily" "three_times_daily" "four_times_daily" "as_needed" "weekly" "monthly" "other" ) ;
|
|
523
|
+
sh:severity sh:Info ;
|
|
524
|
+
sh:message "Frequency should be a recognized dosing schedule"
|
|
525
|
+
] ;
|
|
526
|
+
|
|
527
|
+
# Optional: Brand
|
|
528
|
+
sh:property [
|
|
529
|
+
sh:path checkup:supplementBrand ;
|
|
530
|
+
sh:datatype xsd:string ;
|
|
531
|
+
sh:maxCount 1 ;
|
|
532
|
+
sh:severity sh:Info ;
|
|
533
|
+
sh:message "Brand helps identify specific products"
|
|
534
|
+
] ;
|
|
535
|
+
|
|
536
|
+
# Optional: Form
|
|
537
|
+
sh:property [
|
|
538
|
+
sh:path checkup:supplementForm ;
|
|
539
|
+
sh:in ( "capsule" "tablet" "softgel" "liquid" "powder" "gummy" "spray" "patch" "tea" "tincture" "other" ) ;
|
|
540
|
+
sh:maxCount 1 ;
|
|
541
|
+
sh:severity sh:Info ;
|
|
542
|
+
sh:message "Physical form should be a recognized value"
|
|
543
|
+
] ;
|
|
544
|
+
|
|
545
|
+
# Optional: Evidence strength
|
|
546
|
+
sh:property [
|
|
547
|
+
sh:path checkup:evidenceStrength ;
|
|
548
|
+
sh:in ( "strongEvidence" "moderateEvidence" "limitedEvidence" "traditionalUse" "noEvidence" "unknown" ) ;
|
|
549
|
+
sh:maxCount 1 ;
|
|
550
|
+
sh:severity sh:Info ;
|
|
551
|
+
sh:name "Evidence Strength" ;
|
|
552
|
+
sh:message "Evidence strength helps set expectations about supplement efficacy"
|
|
553
|
+
] ;
|
|
554
|
+
|
|
555
|
+
# Optional: Reason for use
|
|
556
|
+
sh:property [
|
|
557
|
+
sh:path checkup:reasonForUse ;
|
|
558
|
+
sh:datatype xsd:string ;
|
|
559
|
+
sh:maxCount 1 ;
|
|
560
|
+
sh:severity sh:Info ;
|
|
561
|
+
sh:message "Reason for use helps providers understand patient goals"
|
|
562
|
+
] ;
|
|
563
|
+
|
|
564
|
+
# Optional: Start date
|
|
565
|
+
sh:property [
|
|
566
|
+
sh:path checkup:supplementStartDate ;
|
|
567
|
+
sh:datatype xsd:date ;
|
|
568
|
+
sh:maxCount 1 ;
|
|
569
|
+
sh:severity sh:Info ;
|
|
570
|
+
sh:message "Start date helps track supplement duration"
|
|
571
|
+
] ;
|
|
572
|
+
|
|
573
|
+
# Optional: Is active
|
|
574
|
+
sh:property [
|
|
575
|
+
sh:path checkup:supplementIsActive ;
|
|
576
|
+
sh:datatype xsd:boolean ;
|
|
577
|
+
sh:maxCount 1 ;
|
|
578
|
+
sh:severity sh:Info ;
|
|
579
|
+
sh:message "Active status indicates if currently taking"
|
|
580
|
+
] ;
|
|
581
|
+
|
|
582
|
+
# Optional: DSLD ID (NIH identifier)
|
|
583
|
+
sh:property [
|
|
584
|
+
sh:path checkup:dsldId ;
|
|
585
|
+
sh:datatype xsd:string ;
|
|
586
|
+
sh:maxCount 1 ;
|
|
587
|
+
sh:severity sh:Info ;
|
|
588
|
+
sh:name "DSLD ID" ;
|
|
589
|
+
sh:message "NIH Dietary Supplement Label Database identifier for product lookup"
|
|
590
|
+
] ;
|
|
591
|
+
|
|
592
|
+
# Optional: Doctor aware
|
|
593
|
+
sh:property [
|
|
594
|
+
sh:path checkup:doctorAware ;
|
|
595
|
+
sh:datatype xsd:boolean ;
|
|
596
|
+
sh:maxCount 1 ;
|
|
597
|
+
sh:severity sh:Info ;
|
|
598
|
+
sh:name "Doctor Aware" ;
|
|
599
|
+
sh:message "Indicates if healthcare provider knows about this supplement"
|
|
600
|
+
] ;
|
|
601
|
+
|
|
602
|
+
# Optional: Patient cost
|
|
603
|
+
sh:property [
|
|
604
|
+
sh:path checkup:patientCost ;
|
|
605
|
+
sh:datatype xsd:decimal ;
|
|
606
|
+
sh:maxCount 1 ;
|
|
607
|
+
sh:minInclusive 0 ;
|
|
608
|
+
sh:severity sh:Info ;
|
|
609
|
+
sh:message "Cost tracking helps identify financial barriers"
|
|
610
|
+
] ;
|
|
611
|
+
|
|
612
|
+
# Optional: Cost frequency
|
|
613
|
+
sh:property [
|
|
614
|
+
sh:path checkup:costFrequency ;
|
|
615
|
+
sh:in ( "per_month" "per_refill" "per_dose" "per_bottle" "annual" ) ;
|
|
616
|
+
sh:maxCount 1 ;
|
|
617
|
+
sh:severity sh:Info ;
|
|
618
|
+
sh:message "Cost frequency should be a recognized value"
|
|
619
|
+
] .
|
|
620
|
+
|
|
621
|
+
# ============================================================================
|
|
622
|
+
# ALLERGY SUMMARY SHAPE
|
|
623
|
+
# ============================================================================
|
|
624
|
+
|
|
625
|
+
checkup:AllergySummaryShape a sh:NodeShape ;
|
|
626
|
+
sh:targetClass checkup:AllergySummary ;
|
|
627
|
+
rdfs:label "Allergy Summary Validation" ;
|
|
628
|
+
rdfs:comment "Validates allergy entries with reaction details" ;
|
|
629
|
+
|
|
630
|
+
# WARNING: Allergen name required
|
|
631
|
+
sh:property [
|
|
632
|
+
sh:path checkup:allergen ;
|
|
633
|
+
sh:minCount 1 ;
|
|
634
|
+
sh:datatype xsd:string ;
|
|
635
|
+
sh:minLength 2 ;
|
|
636
|
+
sh:severity sh:Warning ;
|
|
637
|
+
sh:message "Allergen name is required"
|
|
638
|
+
] ;
|
|
639
|
+
|
|
640
|
+
# INFO: Reaction type recommended
|
|
641
|
+
sh:property [
|
|
642
|
+
sh:path checkup:reaction ;
|
|
643
|
+
sh:in ( "hives" "rash" "swelling" "difficulty_breathing" "anaphylaxis" "nausea" "diarrhea" "headache" "other" "unknown" ) ;
|
|
644
|
+
sh:severity sh:Info ;
|
|
645
|
+
sh:message "Reaction type should be a recognized value"
|
|
646
|
+
] ;
|
|
647
|
+
|
|
648
|
+
# INFO: Severity recommended
|
|
649
|
+
sh:property [
|
|
650
|
+
sh:path checkup:allergySeverity ;
|
|
651
|
+
sh:in ( "mild" "moderate" "severe" "life_threatening" ) ;
|
|
652
|
+
sh:severity sh:Info ;
|
|
653
|
+
sh:message "Knowing allergy severity helps providers assess risk"
|
|
654
|
+
] ;
|
|
655
|
+
|
|
656
|
+
# Category must be valid if present
|
|
657
|
+
sh:property [
|
|
658
|
+
sh:path checkup:allergyCategory ;
|
|
659
|
+
sh:in ( "medication" "food" "environmental" "latex" "contrast" "insect" "other" ) ;
|
|
660
|
+
sh:severity sh:Info ;
|
|
661
|
+
sh:message "Allergy category should be a recognized value"
|
|
662
|
+
] .
|
|
663
|
+
|
|
664
|
+
# ============================================================================
|
|
665
|
+
# CONDITION SUMMARY SHAPE
|
|
666
|
+
# ============================================================================
|
|
667
|
+
|
|
668
|
+
checkup:ConditionSummaryShape a sh:NodeShape ;
|
|
669
|
+
sh:targetClass checkup:ConditionSummary ;
|
|
670
|
+
rdfs:label "Condition Summary Validation" ;
|
|
671
|
+
rdfs:comment "Validates health condition entries" ;
|
|
672
|
+
|
|
673
|
+
# WARNING: Condition name required
|
|
674
|
+
sh:property [
|
|
675
|
+
sh:path checkup:conditionName ;
|
|
676
|
+
sh:minCount 1 ;
|
|
677
|
+
sh:datatype xsd:string ;
|
|
678
|
+
sh:minLength 2 ;
|
|
679
|
+
sh:severity sh:Warning ;
|
|
680
|
+
sh:message "Condition name is required"
|
|
681
|
+
] ;
|
|
682
|
+
|
|
683
|
+
# Status must be valid
|
|
684
|
+
sh:property [
|
|
685
|
+
sh:path checkup:conditionStatus ;
|
|
686
|
+
sh:in ( "active" "resolved" "remission" "recurrence" "inactive" ) ;
|
|
687
|
+
sh:severity sh:Info ;
|
|
688
|
+
sh:message "Condition status should be a recognized value"
|
|
689
|
+
] ;
|
|
690
|
+
|
|
691
|
+
# ICD-10 code pattern if present
|
|
692
|
+
sh:property [
|
|
693
|
+
sh:path checkup:icd10Code ;
|
|
694
|
+
sh:datatype xsd:string ;
|
|
695
|
+
sh:pattern "^[A-Z][0-9]{2}(\\.[0-9A-Z]{1,4})?$" ;
|
|
696
|
+
sh:severity sh:Info ;
|
|
697
|
+
sh:message "ICD-10 code should follow standard format (e.g., I10, E11.9)"
|
|
698
|
+
] .
|
|
699
|
+
|
|
700
|
+
# ============================================================================
|
|
701
|
+
# FAMILY HISTORY ENTRY SHAPE
|
|
702
|
+
# ============================================================================
|
|
703
|
+
|
|
704
|
+
checkup:FamilyHistoryEntryShape a sh:NodeShape ;
|
|
705
|
+
sh:targetClass checkup:FamilyHistoryEntry ;
|
|
706
|
+
rdfs:label "Family History Entry Validation" ;
|
|
707
|
+
rdfs:comment "Validates family health history entries" ;
|
|
708
|
+
|
|
709
|
+
# INFO: Relative type required
|
|
710
|
+
sh:property [
|
|
711
|
+
sh:path checkup:relativeType ;
|
|
712
|
+
sh:minCount 1 ;
|
|
713
|
+
sh:in ( "mother" "father" "sibling" "maternal_grandmother" "maternal_grandfather" "paternal_grandmother" "paternal_grandfather" "aunt" "uncle" "child" ) ;
|
|
714
|
+
sh:severity sh:Info ;
|
|
715
|
+
sh:message "Relative type is required for family history entries"
|
|
716
|
+
] ;
|
|
717
|
+
|
|
718
|
+
# INFO: Condition required
|
|
719
|
+
sh:property [
|
|
720
|
+
sh:path checkup:familyCondition ;
|
|
721
|
+
sh:minCount 1 ;
|
|
722
|
+
sh:datatype xsd:string ;
|
|
723
|
+
sh:severity sh:Info ;
|
|
724
|
+
sh:message "Health condition is required for family history entries"
|
|
725
|
+
] ;
|
|
726
|
+
|
|
727
|
+
# Age at diagnosis should be reasonable
|
|
728
|
+
sh:property [
|
|
729
|
+
sh:path checkup:ageAtDiagnosis ;
|
|
730
|
+
sh:datatype xsd:integer ;
|
|
731
|
+
sh:minInclusive 0 ;
|
|
732
|
+
sh:maxInclusive 120 ;
|
|
733
|
+
sh:severity sh:Info ;
|
|
734
|
+
sh:message "Age at diagnosis should be between 0 and 120"
|
|
735
|
+
] ;
|
|
736
|
+
|
|
737
|
+
# Age at death should be reasonable
|
|
738
|
+
sh:property [
|
|
739
|
+
sh:path checkup:ageAtDeath ;
|
|
740
|
+
sh:datatype xsd:integer ;
|
|
741
|
+
sh:minInclusive 0 ;
|
|
742
|
+
sh:maxInclusive 120 ;
|
|
743
|
+
sh:severity sh:Info ;
|
|
744
|
+
sh:message "Age at death should be between 0 and 120"
|
|
745
|
+
] .
|
|
746
|
+
|
|
747
|
+
# ============================================================================
|
|
748
|
+
# VITAL SIGNS TREND SHAPE
|
|
749
|
+
# ============================================================================
|
|
750
|
+
|
|
751
|
+
checkup:VitalSignsTrendShape a sh:NodeShape ;
|
|
752
|
+
sh:targetClass checkup:VitalSignsTrend ;
|
|
753
|
+
rdfs:label "Vital Signs Trend Validation" ;
|
|
754
|
+
rdfs:comment "Validates vital signs with trend analysis" ;
|
|
755
|
+
|
|
756
|
+
# Vital type must be valid
|
|
757
|
+
sh:property [
|
|
758
|
+
sh:path checkup:vitalType ;
|
|
759
|
+
sh:minCount 1 ;
|
|
760
|
+
sh:in ( "blood_pressure" "systolic_bp" "diastolic_bp" "heart_rate" "weight" "height" "bmi" "temperature" "respiratory_rate" "oxygen_saturation" ) ;
|
|
761
|
+
sh:severity sh:Info ;
|
|
762
|
+
sh:message "Vital type must be a recognized measurement type"
|
|
763
|
+
] ;
|
|
764
|
+
|
|
765
|
+
# Current value required
|
|
766
|
+
sh:property [
|
|
767
|
+
sh:path checkup:currentValue ;
|
|
768
|
+
sh:minCount 1 ;
|
|
769
|
+
sh:severity sh:Info ;
|
|
770
|
+
sh:message "Current value is required for vital signs"
|
|
771
|
+
] ;
|
|
772
|
+
|
|
773
|
+
# Trend direction must be valid
|
|
774
|
+
sh:property [
|
|
775
|
+
sh:path checkup:trendDirection ;
|
|
776
|
+
sh:in ( "increasing" "decreasing" "stable" ) ;
|
|
777
|
+
sh:severity sh:Info ;
|
|
778
|
+
sh:message "Trend direction should be increasing, decreasing, or stable"
|
|
779
|
+
] ;
|
|
780
|
+
|
|
781
|
+
# Data source must be valid
|
|
782
|
+
sh:property [
|
|
783
|
+
sh:path checkup:dataSource ;
|
|
784
|
+
sh:in ( "apple_health" "ehr" "manual" "device" "imported" ) ;
|
|
785
|
+
sh:severity sh:Info ;
|
|
786
|
+
sh:message "Data source should be a recognized value"
|
|
787
|
+
] .
|
|
788
|
+
|
|
789
|
+
# ============================================================================
|
|
790
|
+
# SCREENING STATUS SHAPE
|
|
791
|
+
# ============================================================================
|
|
792
|
+
|
|
793
|
+
checkup:ScreeningStatusShape a sh:NodeShape ;
|
|
794
|
+
sh:targetClass checkup:ScreeningStatus ;
|
|
795
|
+
rdfs:label "Screening Status Validation" ;
|
|
796
|
+
rdfs:comment "Validates preventive screening status" ;
|
|
797
|
+
|
|
798
|
+
# Screening type must be valid
|
|
799
|
+
sh:property [
|
|
800
|
+
sh:path checkup:screeningType ;
|
|
801
|
+
sh:minCount 1 ;
|
|
802
|
+
sh:in ( "mammogram" "colonoscopy" "colorectal" "pap_smear" "psa" "bone_density" "aaa_ultrasound" "lung_ct" "diabetes_a1c" "lipid_panel" "hepatitis_c" "hiv" "std" "skin_cancer" ) ;
|
|
803
|
+
sh:severity sh:Info ;
|
|
804
|
+
sh:message "Screening type must be a recognized preventive screening"
|
|
805
|
+
] ;
|
|
806
|
+
|
|
807
|
+
# Status must be valid
|
|
808
|
+
sh:property [
|
|
809
|
+
sh:path checkup:screeningStatus ;
|
|
810
|
+
sh:in ( "not_due" "due" "overdue" "completed" "declined" "not_applicable" ) ;
|
|
811
|
+
sh:severity sh:Info ;
|
|
812
|
+
sh:message "Screening status must be a recognized value"
|
|
813
|
+
] ;
|
|
814
|
+
|
|
815
|
+
# Guideline source should be recognized
|
|
816
|
+
sh:property [
|
|
817
|
+
sh:path checkup:guidelineSource ;
|
|
818
|
+
sh:in ( "USPSTF" "ACS" "AAP" "ACOG" "ADA" "ACC_AHA" "other" ) ;
|
|
819
|
+
sh:severity sh:Info ;
|
|
820
|
+
sh:message "Guideline source should be a recognized organization"
|
|
821
|
+
] ;
|
|
822
|
+
|
|
823
|
+
# Grade level for USPSTF
|
|
824
|
+
sh:property [
|
|
825
|
+
sh:path checkup:gradeLevel ;
|
|
826
|
+
sh:in ( "A" "B" "C" "D" "I" ) ;
|
|
827
|
+
sh:severity sh:Info ;
|
|
828
|
+
sh:message "USPSTF grade should be A, B, C, D, or I"
|
|
829
|
+
] .
|
|
830
|
+
|
|
831
|
+
# ============================================================================
|
|
832
|
+
# VISIT ISSUE SHAPE
|
|
833
|
+
# ============================================================================
|
|
834
|
+
|
|
835
|
+
checkup:VisitIssueShape a sh:NodeShape ;
|
|
836
|
+
sh:targetClass checkup:VisitIssue ;
|
|
837
|
+
rdfs:label "Visit Issue Validation" ;
|
|
838
|
+
rdfs:comment "Validates chief complaints / issues to discuss" ;
|
|
839
|
+
|
|
840
|
+
# Category must be valid
|
|
841
|
+
sh:property [
|
|
842
|
+
sh:path checkup:issueCategory ;
|
|
843
|
+
sh:minCount 1 ;
|
|
844
|
+
sh:in ( "pain" "skin" "digestive" "respiratory" "cardiovascular" "mental_health" "neurological" "musculoskeletal" "urinary" "reproductive" "endocrine" "medication" "screening" "general" "other" ) ;
|
|
845
|
+
sh:severity sh:Info ;
|
|
846
|
+
sh:message "Issue category must be a recognized value"
|
|
847
|
+
] ;
|
|
848
|
+
|
|
849
|
+
# Description required
|
|
850
|
+
sh:property [
|
|
851
|
+
sh:path checkup:issueDescription ;
|
|
852
|
+
sh:minCount 1 ;
|
|
853
|
+
sh:datatype xsd:string ;
|
|
854
|
+
sh:minLength 5 ;
|
|
855
|
+
sh:severity sh:Info ;
|
|
856
|
+
sh:message "Issue description is required and should be at least 5 characters"
|
|
857
|
+
] ;
|
|
858
|
+
|
|
859
|
+
# Duration must be valid
|
|
860
|
+
sh:property [
|
|
861
|
+
sh:path checkup:issueDuration ;
|
|
862
|
+
sh:in ( "hours" "days" "weeks" "months" "years" ) ;
|
|
863
|
+
sh:severity sh:Info ;
|
|
864
|
+
sh:message "Duration should be hours, days, weeks, months, or years"
|
|
865
|
+
] ;
|
|
866
|
+
|
|
867
|
+
# Severity must be valid
|
|
868
|
+
sh:property [
|
|
869
|
+
sh:path checkup:issueSeverity ;
|
|
870
|
+
sh:in ( "mild" "moderate" "severe" ) ;
|
|
871
|
+
sh:severity sh:Info ;
|
|
872
|
+
sh:message "Severity should be mild, moderate, or severe"
|
|
873
|
+
] ;
|
|
874
|
+
|
|
875
|
+
# Frequency must be valid
|
|
876
|
+
sh:property [
|
|
877
|
+
sh:path checkup:issueFrequency ;
|
|
878
|
+
sh:in ( "constant" "intermittent" "occasional" "rare" ) ;
|
|
879
|
+
sh:severity sh:Info ;
|
|
880
|
+
sh:message "Frequency should be constant, intermittent, occasional, or rare"
|
|
881
|
+
] ;
|
|
882
|
+
|
|
883
|
+
# Priority must be 1-10
|
|
884
|
+
sh:property [
|
|
885
|
+
sh:path checkup:issuePriority ;
|
|
886
|
+
sh:datatype xsd:integer ;
|
|
887
|
+
sh:minInclusive 1 ;
|
|
888
|
+
sh:maxInclusive 10 ;
|
|
889
|
+
sh:severity sh:Info ;
|
|
890
|
+
sh:message "Priority should be between 1 (highest) and 10 (lowest)"
|
|
891
|
+
] .
|
|
892
|
+
|
|
893
|
+
# ============================================================================
|
|
894
|
+
# DIAGNOSTIC TEST RESULT SHAPE
|
|
895
|
+
# ============================================================================
|
|
896
|
+
|
|
897
|
+
checkup:DiagnosticTestResultShape a sh:NodeShape ;
|
|
898
|
+
sh:targetClass checkup:DiagnosticTestResult ;
|
|
899
|
+
rdfs:label "Diagnostic Test Result Validation" ;
|
|
900
|
+
rdfs:comment "Validates external diagnostic test results" ;
|
|
901
|
+
|
|
902
|
+
# Test type must be valid
|
|
903
|
+
sh:property [
|
|
904
|
+
sh:path checkup:testType ;
|
|
905
|
+
sh:minCount 1 ;
|
|
906
|
+
sh:in ( "pots_check" "blood_pressure_series" "glucose_series" "ecg" "sleep_analysis" "hearing_test" "vision_test" "other" ) ;
|
|
907
|
+
sh:severity sh:Info ;
|
|
908
|
+
sh:message "Test type must be a recognized diagnostic test"
|
|
909
|
+
] ;
|
|
910
|
+
|
|
911
|
+
# Test date required
|
|
912
|
+
sh:property [
|
|
913
|
+
sh:path checkup:testDate ;
|
|
914
|
+
sh:minCount 1 ;
|
|
915
|
+
sh:datatype xsd:dateTime ;
|
|
916
|
+
sh:severity sh:Info ;
|
|
917
|
+
sh:message "Test date is required for diagnostic results"
|
|
918
|
+
] ;
|
|
919
|
+
|
|
920
|
+
# Source app required
|
|
921
|
+
sh:property [
|
|
922
|
+
sh:path checkup:sourceApp ;
|
|
923
|
+
sh:minCount 1 ;
|
|
924
|
+
sh:datatype xsd:string ;
|
|
925
|
+
sh:severity sh:Info ;
|
|
926
|
+
sh:message "Source app name is required for provenance"
|
|
927
|
+
] ;
|
|
928
|
+
|
|
929
|
+
# Result summary required
|
|
930
|
+
sh:property [
|
|
931
|
+
sh:path checkup:resultSummary ;
|
|
932
|
+
sh:minCount 1 ;
|
|
933
|
+
sh:datatype xsd:string ;
|
|
934
|
+
sh:minLength 10 ;
|
|
935
|
+
sh:severity sh:Info ;
|
|
936
|
+
sh:message "Result summary is required and should be descriptive"
|
|
937
|
+
] .
|
|
938
|
+
|
|
939
|
+
# ============================================================================
|
|
940
|
+
# SUGGESTED QUESTION SHAPE
|
|
941
|
+
# ============================================================================
|
|
942
|
+
|
|
943
|
+
checkup:SuggestedQuestionShape a sh:NodeShape ;
|
|
944
|
+
sh:targetClass checkup:SuggestedQuestion ;
|
|
945
|
+
rdfs:label "Suggested Question Validation" ;
|
|
946
|
+
rdfs:comment "Validates AI-generated or template questions" ;
|
|
947
|
+
|
|
948
|
+
# Question text required
|
|
949
|
+
sh:property [
|
|
950
|
+
sh:path checkup:questionText ;
|
|
951
|
+
sh:minCount 1 ;
|
|
952
|
+
sh:datatype xsd:string ;
|
|
953
|
+
sh:minLength 10 ;
|
|
954
|
+
sh:severity sh:Info ;
|
|
955
|
+
sh:message "Question text is required and should be meaningful"
|
|
956
|
+
] ;
|
|
957
|
+
|
|
958
|
+
# Category must be valid
|
|
959
|
+
sh:property [
|
|
960
|
+
sh:path checkup:questionCategory ;
|
|
961
|
+
sh:in ( "treatment_options" "side_effects" "prevention" "lifestyle" "referral" "diagnosis" "prognosis" "medication" "screening" "general" ) ;
|
|
962
|
+
sh:severity sh:Info ;
|
|
963
|
+
sh:message "Question category must be a recognized value"
|
|
964
|
+
] .
|
|
965
|
+
|
|
966
|
+
# ============================================================================
|
|
967
|
+
# INTAKE QUESTIONNAIRE RESPONSE SHAPE (v1.6)
|
|
968
|
+
# ============================================================================
|
|
969
|
+
|
|
970
|
+
checkup:IntakeQuestionnaireResponseShape a sh:NodeShape ;
|
|
971
|
+
sh:targetClass checkup:IntakeQuestionnaireResponse ;
|
|
972
|
+
rdfs:label "Intake Questionnaire Response Validation" ;
|
|
973
|
+
rdfs:comment "Validates intake questionnaire responses using LOINC panel codes" ;
|
|
974
|
+
|
|
975
|
+
# VIOLATION: Questionnaire ID (LOINC panel code) required
|
|
976
|
+
sh:property [
|
|
977
|
+
sh:path checkup:questionnaireId ;
|
|
978
|
+
sh:minCount 1 ;
|
|
979
|
+
sh:datatype xsd:string ;
|
|
980
|
+
sh:minLength 1 ;
|
|
981
|
+
sh:severity sh:Violation ;
|
|
982
|
+
sh:message "Questionnaire ID (LOINC panel code) is required"
|
|
983
|
+
] ;
|
|
984
|
+
|
|
985
|
+
# VIOLATION: Questionnaire title required
|
|
986
|
+
sh:property [
|
|
987
|
+
sh:path checkup:questionnaireTitle ;
|
|
988
|
+
sh:minCount 1 ;
|
|
989
|
+
sh:datatype xsd:string ;
|
|
990
|
+
sh:severity sh:Violation ;
|
|
991
|
+
sh:message "Questionnaire title is required"
|
|
992
|
+
] ;
|
|
993
|
+
|
|
994
|
+
# WARNING: At least one response item
|
|
995
|
+
sh:property [
|
|
996
|
+
sh:path checkup:responseItem ;
|
|
997
|
+
sh:minCount 1 ;
|
|
998
|
+
sh:node checkup:ResponseItemShape ;
|
|
999
|
+
sh:severity sh:Warning ;
|
|
1000
|
+
sh:message "Questionnaire should have at least one response item"
|
|
1001
|
+
] ;
|
|
1002
|
+
|
|
1003
|
+
# INFO: Completion timestamp
|
|
1004
|
+
sh:property [
|
|
1005
|
+
sh:path checkup:completedAt ;
|
|
1006
|
+
sh:datatype xsd:dateTime ;
|
|
1007
|
+
sh:maxCount 1 ;
|
|
1008
|
+
sh:severity sh:Info ;
|
|
1009
|
+
sh:message "Consider adding completion timestamp"
|
|
1010
|
+
] .
|
|
1011
|
+
|
|
1012
|
+
# ============================================================================
|
|
1013
|
+
# RESPONSE ITEM SHAPE (v1.6)
|
|
1014
|
+
# ============================================================================
|
|
1015
|
+
|
|
1016
|
+
checkup:ResponseItemShape a sh:NodeShape ;
|
|
1017
|
+
sh:targetClass checkup:ResponseItem ;
|
|
1018
|
+
rdfs:label "Response Item Validation" ;
|
|
1019
|
+
rdfs:comment "Validates individual question-answer pairs within a questionnaire response" ;
|
|
1020
|
+
|
|
1021
|
+
# VIOLATION: Question text required
|
|
1022
|
+
sh:property [
|
|
1023
|
+
sh:path checkup:itemText ;
|
|
1024
|
+
sh:minCount 1 ;
|
|
1025
|
+
sh:datatype xsd:string ;
|
|
1026
|
+
sh:minLength 1 ;
|
|
1027
|
+
sh:severity sh:Violation ;
|
|
1028
|
+
sh:message "Question text is required for each response item"
|
|
1029
|
+
] ;
|
|
1030
|
+
|
|
1031
|
+
# INFO: Item link ID (LOINC code)
|
|
1032
|
+
sh:property [
|
|
1033
|
+
sh:path checkup:itemLinkId ;
|
|
1034
|
+
sh:datatype xsd:string ;
|
|
1035
|
+
sh:maxCount 1 ;
|
|
1036
|
+
sh:severity sh:Info ;
|
|
1037
|
+
sh:message "LOINC item code helps standardize questionnaire items"
|
|
1038
|
+
] ;
|
|
1039
|
+
|
|
1040
|
+
# INFO: Answer text
|
|
1041
|
+
sh:property [
|
|
1042
|
+
sh:path checkup:itemAnswer ;
|
|
1043
|
+
sh:datatype xsd:string ;
|
|
1044
|
+
sh:severity sh:Info ;
|
|
1045
|
+
sh:message "Consider providing an answer for this item"
|
|
1046
|
+
] ;
|
|
1047
|
+
|
|
1048
|
+
# INFO: Answer code (SNOMED CT or LOINC answer)
|
|
1049
|
+
sh:property [
|
|
1050
|
+
sh:path checkup:itemAnswerCode ;
|
|
1051
|
+
sh:datatype xsd:string ;
|
|
1052
|
+
sh:severity sh:Info ;
|
|
1053
|
+
sh:message "Coded answer enables interoperability with clinical systems"
|
|
1054
|
+
] ;
|
|
1055
|
+
|
|
1056
|
+
# INFO: Answer code system URI
|
|
1057
|
+
sh:property [
|
|
1058
|
+
sh:path checkup:itemAnswerCodeSystem ;
|
|
1059
|
+
sh:datatype xsd:anyURI ;
|
|
1060
|
+
sh:severity sh:Info ;
|
|
1061
|
+
sh:message "Code system URI identifies the terminology (e.g., SNOMED CT, LOINC)"
|
|
1062
|
+
] ;
|
|
1063
|
+
|
|
1064
|
+
# Nested child items (recursive structure)
|
|
1065
|
+
sh:property [
|
|
1066
|
+
sh:path checkup:childItem ;
|
|
1067
|
+
sh:node checkup:ResponseItemShape ;
|
|
1068
|
+
sh:severity sh:Info ;
|
|
1069
|
+
sh:message "Child items support hierarchical questionnaire structures"
|
|
1070
|
+
] .
|
|
1071
|
+
|
|
1072
|
+
# ============================================================================
|
|
1073
|
+
# DAILY CHECK-IN SHAPE (v2.0 - SelfReport subclass)
|
|
1074
|
+
# ============================================================================
|
|
1075
|
+
|
|
1076
|
+
checkup:DailyCheckInShape a sh:NodeShape ;
|
|
1077
|
+
sh:targetClass checkup:DailyCheckIn ;
|
|
1078
|
+
rdfs:label "Daily Check-in Validation" ;
|
|
1079
|
+
rdfs:comment "Validates daily medication adherence check-ins. Inherits base SelfReport validation via sh:node." ;
|
|
1080
|
+
|
|
1081
|
+
# Inherit SelfReport base validation (reportDate, reportType, completionStatus)
|
|
1082
|
+
sh:node health:SelfReportShape ;
|
|
1083
|
+
|
|
1084
|
+
# VIOLATION: Check-in date required
|
|
1085
|
+
sh:property [
|
|
1086
|
+
sh:path checkup:checkInDate ;
|
|
1087
|
+
sh:minCount 1 ;
|
|
1088
|
+
sh:datatype xsd:dateTime ;
|
|
1089
|
+
sh:severity sh:Violation ;
|
|
1090
|
+
sh:message "Check-in date is required"
|
|
1091
|
+
] ;
|
|
1092
|
+
|
|
1093
|
+
# VIOLATION: Adherence response required
|
|
1094
|
+
sh:property [
|
|
1095
|
+
sh:path checkup:checkInResponse ;
|
|
1096
|
+
sh:minCount 1 ;
|
|
1097
|
+
sh:in ( "allTaken" "missedSome" "skippedToday" ) ;
|
|
1098
|
+
sh:severity sh:Violation ;
|
|
1099
|
+
sh:message "Check-in response is required and must be allTaken, missedSome, or skippedToday"
|
|
1100
|
+
] ;
|
|
1101
|
+
|
|
1102
|
+
# INFO: Missed medication IDs (relevant when response is missedSome)
|
|
1103
|
+
sh:property [
|
|
1104
|
+
sh:path checkup:missedMedicationIds ;
|
|
1105
|
+
sh:datatype xsd:string ;
|
|
1106
|
+
sh:severity sh:Info ;
|
|
1107
|
+
sh:message "Consider identifying which medications were missed for better adherence tracking"
|
|
1108
|
+
] ;
|
|
1109
|
+
|
|
1110
|
+
# INFO: Notes
|
|
1111
|
+
sh:property [
|
|
1112
|
+
sh:path checkup:checkInNotes ;
|
|
1113
|
+
sh:datatype xsd:string ;
|
|
1114
|
+
sh:severity sh:Info ;
|
|
1115
|
+
sh:message "Notes can help explain adherence barriers or side effects"
|
|
1116
|
+
] ;
|
|
1117
|
+
|
|
1118
|
+
# INFO: Submission timestamp
|
|
1119
|
+
sh:property [
|
|
1120
|
+
sh:path checkup:submittedAt ;
|
|
1121
|
+
sh:datatype xsd:dateTime ;
|
|
1122
|
+
sh:severity sh:Info ;
|
|
1123
|
+
sh:message "Submission timestamp helps track check-in timing patterns"
|
|
1124
|
+
] .
|
|
1125
|
+
|
|
1126
|
+
# ============================================================================
|
|
1127
|
+
# IMMUNIZATION SUMMARY SHAPE (v2.0)
|
|
1128
|
+
# ============================================================================
|
|
1129
|
+
|
|
1130
|
+
checkup:ImmunizationSummaryShape a sh:NodeShape ;
|
|
1131
|
+
sh:targetClass checkup:ImmunizationSummary ;
|
|
1132
|
+
rdfs:label "Immunization Summary Validation" ;
|
|
1133
|
+
rdfs:comment "Validates immunization records for intake forms" ;
|
|
1134
|
+
|
|
1135
|
+
# VIOLATION: Vaccine name required
|
|
1136
|
+
sh:property [
|
|
1137
|
+
sh:path checkup:vaccineName ;
|
|
1138
|
+
sh:minCount 1 ;
|
|
1139
|
+
sh:datatype xsd:string ;
|
|
1140
|
+
sh:minLength 1 ;
|
|
1141
|
+
sh:severity sh:Violation ;
|
|
1142
|
+
sh:message "Vaccine name is required"
|
|
1143
|
+
] ;
|
|
1144
|
+
|
|
1145
|
+
# VIOLATION: Administration date required
|
|
1146
|
+
sh:property [
|
|
1147
|
+
sh:path checkup:administrationDate ;
|
|
1148
|
+
sh:minCount 1 ;
|
|
1149
|
+
sh:datatype xsd:dateTime ;
|
|
1150
|
+
sh:severity sh:Violation ;
|
|
1151
|
+
sh:message "Vaccine administration date is required"
|
|
1152
|
+
] ;
|
|
1153
|
+
|
|
1154
|
+
# WARNING: Immunization status
|
|
1155
|
+
sh:property [
|
|
1156
|
+
sh:path checkup:immunizationStatus ;
|
|
1157
|
+
sh:in ( "completed" "entered-in-error" "not-done" ) ;
|
|
1158
|
+
sh:severity sh:Warning ;
|
|
1159
|
+
sh:message "Immunization status should be completed, entered-in-error, or not-done"
|
|
1160
|
+
] ;
|
|
1161
|
+
|
|
1162
|
+
# WARNING: Vaccine code (CVX)
|
|
1163
|
+
sh:property [
|
|
1164
|
+
sh:path checkup:vaccineCode ;
|
|
1165
|
+
sh:datatype xsd:string ;
|
|
1166
|
+
sh:severity sh:Warning ;
|
|
1167
|
+
sh:message "CVX vaccine code helps standardize immunization records"
|
|
1168
|
+
] ;
|
|
1169
|
+
|
|
1170
|
+
# WARNING: Vaccine category
|
|
1171
|
+
sh:property [
|
|
1172
|
+
sh:path checkup:vaccineCategory ;
|
|
1173
|
+
sh:in ( "routine" "travel" "occupational" "other" ) ;
|
|
1174
|
+
sh:severity sh:Warning ;
|
|
1175
|
+
sh:message "Vaccine category should be routine, travel, occupational, or other"
|
|
1176
|
+
] ;
|
|
1177
|
+
|
|
1178
|
+
# INFO: Manufacturer
|
|
1179
|
+
sh:property [
|
|
1180
|
+
sh:path checkup:manufacturer ;
|
|
1181
|
+
sh:datatype xsd:string ;
|
|
1182
|
+
sh:severity sh:Info ;
|
|
1183
|
+
sh:message "Vaccine manufacturer helps identify specific products"
|
|
1184
|
+
] ;
|
|
1185
|
+
|
|
1186
|
+
# INFO: Lot number
|
|
1187
|
+
sh:property [
|
|
1188
|
+
sh:path checkup:lotNumber ;
|
|
1189
|
+
sh:datatype xsd:string ;
|
|
1190
|
+
sh:severity sh:Info ;
|
|
1191
|
+
sh:message "Lot number supports vaccine recall tracking"
|
|
1192
|
+
] ;
|
|
1193
|
+
|
|
1194
|
+
# INFO: Dose number in series
|
|
1195
|
+
sh:property [
|
|
1196
|
+
sh:path checkup:doseNumber ;
|
|
1197
|
+
sh:datatype xsd:integer ;
|
|
1198
|
+
sh:minInclusive 1 ;
|
|
1199
|
+
sh:severity sh:Info ;
|
|
1200
|
+
sh:message "Dose number tracks progress in multi-dose vaccine series"
|
|
1201
|
+
] ;
|
|
1202
|
+
|
|
1203
|
+
# INFO: Notes
|
|
1204
|
+
sh:property [
|
|
1205
|
+
sh:path checkup:immunizationNotes ;
|
|
1206
|
+
sh:datatype xsd:string ;
|
|
1207
|
+
sh:severity sh:Info ;
|
|
1208
|
+
sh:message "Additional notes about the immunization"
|
|
1209
|
+
] .
|
|
1210
|
+
|
|
1211
|
+
# ============================================================================
|
|
1212
|
+
# LAB RESULT SUMMARY SHAPE (v2.0 - mixed namespace: clinical:/checkup:)
|
|
1213
|
+
# ============================================================================
|
|
1214
|
+
|
|
1215
|
+
checkup:LabResultSummaryShape a sh:NodeShape ;
|
|
1216
|
+
sh:targetClass checkup:LabResultSummary ;
|
|
1217
|
+
rdfs:label "Lab Result Summary Validation" ;
|
|
1218
|
+
rdfs:comment "Validates lab result records using mixed namespace pattern: clinical: for standardized data, checkup: for app-layer categorization" ;
|
|
1219
|
+
|
|
1220
|
+
# VIOLATION: Test name required (clinical: namespace)
|
|
1221
|
+
sh:property [
|
|
1222
|
+
sh:path clinical:testName ;
|
|
1223
|
+
sh:minCount 1 ;
|
|
1224
|
+
sh:datatype xsd:string ;
|
|
1225
|
+
sh:minLength 1 ;
|
|
1226
|
+
sh:severity sh:Violation ;
|
|
1227
|
+
sh:message "Lab test name is required"
|
|
1228
|
+
] ;
|
|
1229
|
+
|
|
1230
|
+
# WARNING: Result value
|
|
1231
|
+
sh:property [
|
|
1232
|
+
sh:path clinical:resultValue ;
|
|
1233
|
+
sh:datatype xsd:string ;
|
|
1234
|
+
sh:severity sh:Warning ;
|
|
1235
|
+
sh:message "Lab result value helps providers interpret results"
|
|
1236
|
+
] ;
|
|
1237
|
+
|
|
1238
|
+
# WARNING: Lab category for intake display
|
|
1239
|
+
sh:property [
|
|
1240
|
+
sh:path checkup:labCategory ;
|
|
1241
|
+
sh:in ( "metabolic" "hematology" "lipid" "thyroid" "vitamin" "other" ) ;
|
|
1242
|
+
sh:severity sh:Warning ;
|
|
1243
|
+
sh:message "Lab category should be metabolic, hematology, lipid, thyroid, vitamin, or other"
|
|
1244
|
+
] ;
|
|
1245
|
+
|
|
1246
|
+
# INFO: Result unit
|
|
1247
|
+
sh:property [
|
|
1248
|
+
sh:path clinical:resultUnit ;
|
|
1249
|
+
sh:datatype xsd:string ;
|
|
1250
|
+
sh:severity sh:Info ;
|
|
1251
|
+
sh:message "Result unit helps interpret the lab value"
|
|
1252
|
+
] ;
|
|
1253
|
+
|
|
1254
|
+
# INFO: Reference range
|
|
1255
|
+
sh:property [
|
|
1256
|
+
sh:path clinical:referenceRange ;
|
|
1257
|
+
sh:datatype xsd:string ;
|
|
1258
|
+
sh:severity sh:Info ;
|
|
1259
|
+
sh:message "Reference range provides context for the result"
|
|
1260
|
+
] ;
|
|
1261
|
+
|
|
1262
|
+
# INFO: Result date
|
|
1263
|
+
sh:property [
|
|
1264
|
+
sh:path clinical:resultDate ;
|
|
1265
|
+
sh:datatype xsd:dateTime ;
|
|
1266
|
+
sh:severity sh:Info ;
|
|
1267
|
+
sh:message "Result date helps establish the timeline of lab work"
|
|
1268
|
+
] ;
|
|
1269
|
+
|
|
1270
|
+
# INFO: Interpretation
|
|
1271
|
+
sh:property [
|
|
1272
|
+
sh:path clinical:interpretation ;
|
|
1273
|
+
sh:datatype xsd:string ;
|
|
1274
|
+
sh:severity sh:Info ;
|
|
1275
|
+
sh:message "Interpretation (normal, abnormal, critical) helps providers triage results"
|
|
1276
|
+
] ;
|
|
1277
|
+
|
|
1278
|
+
# INFO: Notes
|
|
1279
|
+
sh:property [
|
|
1280
|
+
sh:path clinical:notes ;
|
|
1281
|
+
sh:datatype xsd:string ;
|
|
1282
|
+
sh:severity sh:Info ;
|
|
1283
|
+
sh:message "Additional clinical notes about the lab result"
|
|
1284
|
+
] .
|
|
1285
|
+
|
|
1286
|
+
# ============================================================================
|
|
1287
|
+
# PROCEDURE SUMMARY SHAPE (v2.0 - mixed namespace: clinical:/checkup:)
|
|
1288
|
+
# ============================================================================
|
|
1289
|
+
|
|
1290
|
+
checkup:ProcedureSummaryShape a sh:NodeShape ;
|
|
1291
|
+
sh:targetClass checkup:ProcedureSummary ;
|
|
1292
|
+
rdfs:label "Procedure Summary Validation" ;
|
|
1293
|
+
rdfs:comment "Validates procedure records using mixed namespace pattern: checkup: for app-layer fields, clinical: for standardized clinical data" ;
|
|
1294
|
+
|
|
1295
|
+
# VIOLATION: Procedure name required
|
|
1296
|
+
sh:property [
|
|
1297
|
+
sh:path checkup:procedureName ;
|
|
1298
|
+
sh:minCount 1 ;
|
|
1299
|
+
sh:datatype xsd:string ;
|
|
1300
|
+
sh:minLength 1 ;
|
|
1301
|
+
sh:severity sh:Violation ;
|
|
1302
|
+
sh:message "Procedure name is required"
|
|
1303
|
+
] ;
|
|
1304
|
+
|
|
1305
|
+
# WARNING: Procedure status (clinical: namespace)
|
|
1306
|
+
sh:property [
|
|
1307
|
+
sh:path clinical:procedureStatus ;
|
|
1308
|
+
sh:datatype xsd:string ;
|
|
1309
|
+
sh:severity sh:Warning ;
|
|
1310
|
+
sh:message "Procedure status helps providers know if the procedure was completed"
|
|
1311
|
+
] ;
|
|
1312
|
+
|
|
1313
|
+
# WARNING: Performed date (clinical: namespace)
|
|
1314
|
+
sh:property [
|
|
1315
|
+
sh:path clinical:performedDate ;
|
|
1316
|
+
sh:datatype xsd:dateTime ;
|
|
1317
|
+
sh:severity sh:Warning ;
|
|
1318
|
+
sh:message "Performed date helps establish the timeline of procedures"
|
|
1319
|
+
] ;
|
|
1320
|
+
|
|
1321
|
+
# INFO: Procedure category
|
|
1322
|
+
sh:property [
|
|
1323
|
+
sh:path checkup:procedureCategory ;
|
|
1324
|
+
sh:in ( "surgical" "diagnostic" "therapeutic" "other" ) ;
|
|
1325
|
+
sh:severity sh:Info ;
|
|
1326
|
+
sh:message "Procedure category should be surgical, diagnostic, therapeutic, or other"
|
|
1327
|
+
] ;
|
|
1328
|
+
|
|
1329
|
+
# INFO: Procedure location
|
|
1330
|
+
sh:property [
|
|
1331
|
+
sh:path checkup:procedureLocation ;
|
|
1332
|
+
sh:datatype xsd:string ;
|
|
1333
|
+
sh:severity sh:Info ;
|
|
1334
|
+
sh:message "Facility or location where the procedure was performed"
|
|
1335
|
+
] ;
|
|
1336
|
+
|
|
1337
|
+
# INFO: Body site
|
|
1338
|
+
sh:property [
|
|
1339
|
+
sh:path clinical:bodySite ;
|
|
1340
|
+
sh:datatype xsd:string ;
|
|
1341
|
+
sh:severity sh:Info ;
|
|
1342
|
+
sh:message "Body site provides specificity about where the procedure was performed"
|
|
1343
|
+
] ;
|
|
1344
|
+
|
|
1345
|
+
# INFO: Performer
|
|
1346
|
+
sh:property [
|
|
1347
|
+
sh:path clinical:performer ;
|
|
1348
|
+
sh:datatype xsd:string ;
|
|
1349
|
+
sh:severity sh:Info ;
|
|
1350
|
+
sh:message "Performer name supports care coordination"
|
|
1351
|
+
] ;
|
|
1352
|
+
|
|
1353
|
+
# INFO: Outcome
|
|
1354
|
+
sh:property [
|
|
1355
|
+
sh:path clinical:outcome ;
|
|
1356
|
+
sh:datatype xsd:string ;
|
|
1357
|
+
sh:severity sh:Info ;
|
|
1358
|
+
sh:message "Outcome description provides context about the procedure result"
|
|
1359
|
+
] .
|
|
1360
|
+
|
|
1361
|
+
# ============================================================================
|
|
1362
|
+
# DISCUSSION TOPIC SHAPE (v2.0)
|
|
1363
|
+
# ============================================================================
|
|
1364
|
+
|
|
1365
|
+
checkup:DiscussionTopicShape a sh:NodeShape ;
|
|
1366
|
+
sh:targetClass checkup:DiscussionTopic ;
|
|
1367
|
+
rdfs:label "Discussion Topic Validation" ;
|
|
1368
|
+
rdfs:comment "Validates AI-generated or user-created visit discussion topics" ;
|
|
1369
|
+
|
|
1370
|
+
# VIOLATION: Topic text required
|
|
1371
|
+
sh:property [
|
|
1372
|
+
sh:path checkup:topicText ;
|
|
1373
|
+
sh:minCount 1 ;
|
|
1374
|
+
sh:datatype xsd:string ;
|
|
1375
|
+
sh:minLength 1 ;
|
|
1376
|
+
sh:severity sh:Violation ;
|
|
1377
|
+
sh:message "Discussion topic text is required"
|
|
1378
|
+
] ;
|
|
1379
|
+
|
|
1380
|
+
# WARNING: Topic category
|
|
1381
|
+
sh:property [
|
|
1382
|
+
sh:path checkup:topicCategory ;
|
|
1383
|
+
sh:in ( "durationBased" "recentChange" "adherenceConcern" "sideEffectReport" "multipleForSame" "supplementDoctor" "interactionRisk" "refillDue" "effectivenessConcern" "costConcern" "custom" ) ;
|
|
1384
|
+
sh:severity sh:Warning ;
|
|
1385
|
+
sh:message "Topic category must be a recognized value"
|
|
1386
|
+
] ;
|
|
1387
|
+
|
|
1388
|
+
# INFO: Topic source
|
|
1389
|
+
sh:property [
|
|
1390
|
+
sh:path checkup:topicSource ;
|
|
1391
|
+
sh:datatype xsd:string ;
|
|
1392
|
+
sh:severity sh:Info ;
|
|
1393
|
+
sh:message "Topic source indicates how the topic was generated (medication, supplement, adherencePattern, custom)"
|
|
1394
|
+
] ;
|
|
1395
|
+
|
|
1396
|
+
# INFO: Relevance score
|
|
1397
|
+
sh:property [
|
|
1398
|
+
sh:path checkup:relevanceScore ;
|
|
1399
|
+
sh:datatype xsd:double ;
|
|
1400
|
+
sh:minInclusive 0.0 ;
|
|
1401
|
+
sh:maxInclusive 1.0 ;
|
|
1402
|
+
sh:severity sh:Info ;
|
|
1403
|
+
sh:message "Relevance score should be between 0.0 and 1.0"
|
|
1404
|
+
] ;
|
|
1405
|
+
|
|
1406
|
+
# INFO: Is selected for next visit
|
|
1407
|
+
sh:property [
|
|
1408
|
+
sh:path checkup:isSelected ;
|
|
1409
|
+
sh:datatype xsd:boolean ;
|
|
1410
|
+
sh:severity sh:Info ;
|
|
1411
|
+
sh:message "Selection status indicates if topic is active for the next visit"
|
|
1412
|
+
] .
|
|
1413
|
+
|
|
1414
|
+
# ============================================================================
|
|
1415
|
+
# CHANGELOG
|
|
1416
|
+
# ============================================================================
|
|
1417
|
+
#
|
|
1418
|
+
# v2.0 (2026-02-18): WS8 - Shapes for v1.5-v2.0 ontology classes
|
|
1419
|
+
# - Added health: and clinical: prefix declarations for cross-namespace shapes
|
|
1420
|
+
# - Added 5 new NodeShapes:
|
|
1421
|
+
# - DailyCheckInShape: SelfReport subclass with sh:node health:SelfReportShape
|
|
1422
|
+
# inheritance, checkInDate/checkInResponse required (Violation), missedMedicationIds/
|
|
1423
|
+
# checkInNotes/submittedAt optional (Info)
|
|
1424
|
+
# - ImmunizationSummaryShape: vaccineName/administrationDate required (Violation),
|
|
1425
|
+
# immunizationStatus/vaccineCode/vaccineCategory warnings, manufacturer/lotNumber/
|
|
1426
|
+
# doseNumber/immunizationNotes info
|
|
1427
|
+
# - LabResultSummaryShape: mixed namespace — clinical:testName required (Violation),
|
|
1428
|
+
# clinical:resultValue warning, checkup:labCategory warning, clinical info properties
|
|
1429
|
+
# - ProcedureSummaryShape: mixed namespace — checkup:procedureName required (Violation),
|
|
1430
|
+
# clinical:procedureStatus/performedDate warnings, checkup:procedureCategory/
|
|
1431
|
+
# procedureLocation and clinical:bodySite/performer/outcome info
|
|
1432
|
+
# - DiscussionTopicShape: topicText required (Violation), topicCategory warning,
|
|
1433
|
+
# topicSource/relevanceScore/isSelected info
|
|
1434
|
+
# - Added 5 new aggregate link properties to IntakeFormDataShape:
|
|
1435
|
+
# hasDailyCheckIn, hasDiscussionTopic, hasImmunization, hasLabResult, hasProcedure
|
|
1436
|
+
# - Total shapes: 20 (was 15)
|
|
1437
|
+
#
|
|
1438
|
+
# v1.6 (2026-02-09): Intake Questionnaire SHACL Shapes
|
|
1439
|
+
# - Added IntakeQuestionnaireResponseShape with LOINC panel code validation
|
|
1440
|
+
# - Added ResponseItemShape with question text validation and nested child items
|
|
1441
|
+
# - Added hasQuestionnaireResponse validation to IntakeFormDataShape
|
|
1442
|
+
# - Total shapes: 15 (was 13)
|
|
1443
|
+
#
|
|
1444
|
+
# v1.3 (2026-01-17): Phase 7 Medication Ontology Extensions
|
|
1445
|
+
# - Extended MedicationSummaryShape with episode linkage (episodeId, startDate,
|
|
1446
|
+
# indication) and patient meaning fields (patientCost, costFrequency,
|
|
1447
|
+
# functionalImpact, concernsForDoctor)
|
|
1448
|
+
# - Added SupplementSummaryShape with regulatoryStatus requirement
|
|
1449
|
+
# - Added hasSupplement validation to IntakeFormDataShape
|
|
1450
|
+
#
|
|
1451
|
+
# v1.0 (2026-01-03): Initial release
|
|
1452
|
+
# - 10 core shapes: IntakeFormData, PatientProfile, InsuranceInfo,
|
|
1453
|
+
# MedicationSummary, AllergySummary, ConditionSummary, FamilyHistoryEntry,
|
|
1454
|
+
# VitalSignsTrend, ScreeningStatus, VisitIssue, DiagnosticTestResult,
|
|
1455
|
+
# SuggestedQuestion
|
|
1456
|
+
#
|
|
1457
|
+
# ============================================================================
|
|
1458
|
+
# END OF ADULT SHAPES
|
|
1459
|
+
# ============================================================================
|