Recipe 13.6 Architecture and Implementation: Care Gap Reasoning Engine
Companion to Recipe 13.6: Care Gap Reasoning Engine. This page covers the AWS architecture, services, prerequisites, and pseudocode. For the problem framing and the conceptual approach, start with the main recipe.
The AWS Implementation
Why These Services
Amazon Neptune for the knowledge graph. Neptune is AWS's managed graph database service supporting both property graph (Gremlin/openCypher) and RDF (SPARQL) query models. For care gap reasoning, the RDF/SPARQL model is the better fit because clinical guidelines are naturally expressed as class hierarchies and typed relationships. You define condition hierarchies (coronary artery disease rdfs:subClassOf cardiovascular disease) as RDF triples and traverse them at query time using SPARQL property paths (e.g., rdfs:subClassOf* for transitive closure). Neptune does not perform OWL inference natively. It stores and queries RDF data, but hierarchy traversal requires explicit SPARQL property path expressions rather than a built-in reasoner. For use cases requiring full OWL reasoning (forward-chaining, complex class expressions), you can integrate a third-party reasoner like RDFox to pre-materialize inferred triples and load them into Neptune. For care gap applicability checks, SPARQL property paths handle the hierarchy traversal we need without an external reasoner. Neptune is HIPAA eligible, supports encryption at rest and in transit, and runs within your VPC.
AWS Lambda for patient evaluation orchestration. Each patient evaluation is a bounded, stateless operation: assemble facts, query the graph, score the gaps, return results. Lambda handles the per-patient compute without requiring persistent infrastructure. For batch population evaluation (running all 50,000 patients overnight), Lambda's concurrency model scales naturally.
Amazon S3 for guideline ontology storage and versioning. The guideline ontology (OWL/RDF files) needs versioning, audit trails, and a clean deployment path. S3 with versioning enabled provides all three. When guidelines update annually, you upload the new ontology version, load it into Neptune, and the reasoning automatically reflects the changes.
AWS Step Functions for batch orchestration. Evaluating an entire population requires coordination: partition the patient list, fan out Lambda invocations, collect results, handle failures, and produce summary reports. Step Functions provides the orchestration with built-in retry logic and error handling. Configure the Map state with MaxConcurrency to control Neptune load. Set Retry with exponential backoff for Lambda timeout and Neptune throttling errors. Configure a Catch block that writes failed patient IDs to an SQS dead-letter queue for investigation. After batch completion, report the failure rate; if more than 5% of patients fail evaluation, alert the operations team.
Amazon DynamoDB for gap result storage. The output of the reasoning engine (per-patient gap lists) needs fast point lookups by patient ID for care management workflows and batch scans for population-level reporting. DynamoDB handles both access patterns efficiently.
AWS Glue for patient data assembly. Patient facts come from multiple sources (claims databases, EHR extracts, lab feeds). Glue ETL jobs consolidate these into the fact format the reasoning engine expects, handling deduplication and temporal alignment.
Architecture Diagram
flowchart TD
subgraph Data Sources
A[Claims DB]
B[EHR Extract]
C[Lab Results]
end
subgraph Fact Assembly
D[AWS Glue ETL]
end
subgraph Knowledge Graph
E[Amazon Neptune\nGuideline Ontology +\nCondition Hierarchies]
end
subgraph Reasoning Pipeline
F[Step Functions\nBatch Orchestrator]
G[Lambda\nPatient Evaluator]
end
subgraph Output
H[DynamoDB\nCare Gap Results]
I[S3\nPopulation Reports]
end
A --> D
B --> D
C --> D
D -->|Patient Facts| G
F -->|Fan-out| G
G -->|SPARQL Queries| E
G -->|Write Gaps| H
F -->|Summary| I
J[S3\nOntology Files\nVersioned] -->|Load| E
style E fill:#ff9,stroke:#333
style H fill:#9ff,stroke:#333
style G fill:#f9f,stroke:#333
Here's what you need before you start building:
Prerequisites
| Requirement | Details |
|---|---|
| AWS Services | Amazon Neptune, AWS Lambda, Amazon S3, AWS Step Functions, Amazon DynamoDB, AWS Glue, Amazon SQS (DLQ) |
| IAM Permissions | Evaluation Lambda: neptune-db:ReadDataViaQuery (scoped to cluster ARN). Ontology loader (separate role): neptune-db:WriteDataViaQuery, neptune-db:GetGraphSummary. Both: s3:GetObject, s3:PutObject, dynamodb:PutItem, dynamodb:Query, states:StartExecution, glue:StartJobRun. The evaluation Lambda should never have write access to the knowledge graph. |
| BAA | AWS BAA signed (patient conditions, demographics, and care history are PHI) |
| Encryption | Neptune: encryption at rest enabled at cluster creation (cannot be added later); S3: SSE-KMS; DynamoDB: encryption at rest (default); all connections over TLS |
| VPC | Neptune requires VPC deployment. Ensure VPC has enableDnsHostnames and enableDnsSupport set to true (required for Neptune endpoint resolution). Lambda in same VPC with VPC endpoints for S3, DynamoDB, and CloudWatch Logs. Neptune accessible only via private subnet. Security group on Neptune must allow inbound TCP 8182 from the Lambda security group. Neptune does not need a VPC endpoint because it runs inside your VPC; Lambda connects directly via the private subnet. |
| CloudTrail | Enabled for all API calls. Neptune audit logs enabled for SPARQL query logging. CloudWatch Logs retention for Neptune audit logs: minimum 6 years per HIPAA retention requirements. Consider tiering to S3 Glacier after 90 days for cost optimization. |
| Sample Data | Synthetic patient populations with known conditions. Use CMS Synthetic Medicare data or Synthea-generated records. Never use real PHI in development. |
| Cost Estimate | Neptune db.r5.large: ~$0.58/hr (~$420/month). Lambda: negligible at batch volumes. DynamoDB: on-demand pricing, ~$1.25 per million writes. Total for 50K patient monthly evaluation: ~$450/month. |
Ingredients
| AWS Service | Role |
|---|---|
| Amazon Neptune | Stores guideline ontology, condition hierarchies, and executes reasoning queries via SPARQL |
| AWS Lambda | Evaluates individual patients against the knowledge graph |
| Amazon S3 | Stores versioned ontology files and population-level reports |
| AWS Step Functions | Orchestrates batch population evaluation with fan-out/fan-in |
| Amazon DynamoDB | Stores per-patient care gap results for downstream consumption |
| AWS Glue | Assembles patient facts from heterogeneous data sources |
| Amazon SQS | Dead-letter queue for failed patient evaluations |
| AWS KMS | Manages encryption keys for all data stores |
| Amazon CloudWatch | Metrics, logs, and alarms for pipeline health |
Code
Walkthrough
Step 1: Define the guideline ontology. The foundation of the reasoning engine is the ontology: a formal representation of clinical guidelines as classes, properties, and relationships. Each guideline recommendation becomes a node with typed connections to its preconditions (what must be true about the patient) and its recommended action (what should happen). Condition hierarchies (ICD-10 codes rolling up to condition groups) are modeled as class hierarchies so the reasoner can infer membership automatically. This ontology is authored once per guideline set, updated when guidelines change (typically annually), and loaded into Neptune. Skip this step and you have no knowledge to reason over.
// Ontology structure (RDF/OWL concepts, expressed as pseudocode)
// This defines the "knowledge" that the reasoning engine uses.
DEFINE CLASS Condition
// Represents a clinical condition (e.g., Type 2 Diabetes, Hypertension)
// Conditions form a hierarchy: specific diagnoses are subclasses of broader groups
DEFINE CLASS Recommendation
// A clinical action recommended by a guideline
PROPERTY applies_when: list of Condition // preconditions (patient must have these)
PROPERTY age_minimum: integer // minimum age for applicability (optional)
PROPERTY age_maximum: integer // maximum age for applicability (optional)
PROPERTY sex_applies_to: string // "M", "F", or "all"
PROPERTY recommended_action: Action // what should be done
PROPERTY frequency: Duration // how often (e.g., "every 6 months")
PROPERTY excluded_by: list of Condition // exclusion criteria (if present, skip)
PROPERTY measure_id: string // quality measure reference (e.g., "HEDIS-CDC-HbA1c")
PROPERTY priority: string // "high", "medium", "low"
DEFINE CLASS Action
// A specific clinical action (e.g., "HbA1c Lab Test", "Retinal Exam")
PROPERTY action_type: string // "lab", "procedure", "medication", "referral"
PROPERTY cpt_codes: list of string // CPT codes that satisfy this action
PROPERTY loinc_codes: list of string // LOINC codes for lab-based actions
// Example: Diabetes HbA1c monitoring recommendation
CREATE Recommendation:
id = "rec-diabetes-hba1c"
applies_when = [Type2Diabetes] // patient must have Type 2 Diabetes
recommended_action = HbA1cTest
frequency = "6 months"
excluded_by = [Hospice, TerminalIllness]
measure_id = "HEDIS-CDC-HbA1c"
priority = "high"
// Example: Condition hierarchy
Type2Diabetes subClassOf DiabetesMellitus
DiabetesMellitus subClassOf ChronicCondition
// This means: if a guideline applies to "ChronicCondition", it automatically
// applies to Type2Diabetes patients via inference. No explicit rule needed.
Step 2: Load patient facts into the evaluation context. For each patient being evaluated, assemble their current clinical state from available data sources: active conditions (from claims and problem lists), demographics, current medications, and recent services with dates. This fact set becomes the patient's representation that the reasoner evaluates against the guideline ontology. The key challenge here is temporal: you need to know not just what conditions a patient has, but when their last relevant service occurred. Skip this step and the reasoner has nothing to evaluate.
FUNCTION assemble_patient_facts(patient_id, data_sources):
// Pull the patient's current clinical state from all available sources.
// This becomes the "fact set" that the reasoner evaluates.
facts = empty structure
// Demographics: age and sex drive many guideline applicability rules
facts.demographics = query data_sources.ehr for:
age, sex, enrollment_status
WHERE patient_id matches
// Active conditions: what diagnoses does this patient carry?
// Pull from both claims (ICD-10 codes from encounters) and EHR problem lists.
// Deduplicate: the same condition from both sources counts once.
facts.conditions = query data_sources.claims for:
DISTINCT icd10_codes
WHERE patient_id matches
AND service_date within last 24 months // lookback period per measure specs
UNION query data_sources.ehr_problems for:
active problem list entries (mapped to ICD-10)
WHERE patient_id matches
// Recent services: what has been done, and when?
// This is how we determine whether a recommended action has been completed.
facts.recent_services = query data_sources.claims for:
cpt_code, service_date, loinc_code (if lab)
WHERE patient_id matches
AND service_date within last 24 months
// Current medications: some guidelines recommend starting a medication,
// so we need to know what the patient is already taking.
facts.medications = query data_sources.pharmacy for:
drug_name, ndc_code, fill_date, days_supply
WHERE patient_id matches
AND fill_date within last 12 months // active = filled recently
RETURN facts
Step 3: Determine applicable recommendations. This is where the reasoning happens. For each recommendation in the guideline ontology, evaluate whether its preconditions are satisfied by the patient's fact set. The ontological reasoning handles hierarchy traversal: if the patient has ICD-10 code E11.9 (Type 2 Diabetes without complications), and the recommendation applies to "Diabetes Mellitus" (the parent class), the reasoner resolves applicability through the subclass relationship using SPARQL property paths. Exclusions are checked after inclusions: if any exclusion condition is present, the recommendation is skipped regardless of whether inclusions are met. Skip this step and you're just listing all possible recommendations without knowing which ones actually apply to this patient.
FUNCTION find_applicable_recommendations(patient_facts, knowledge_graph):
// Query the knowledge graph to find all recommendations whose
// preconditions are satisfied by this patient's facts.
applicable = empty list
// SPARQL-style query (conceptual):
// "Find all Recommendations where:
// - The patient has at least one condition that matches (or is a subclass of)
// the recommendation's applies_when conditions
// - The patient's age falls within the recommendation's age range
// - The patient's sex matches (or recommendation applies to all)
// - The patient does NOT have any condition in the excluded_by list"
results = QUERY knowledge_graph:
SELECT recommendation
WHERE recommendation.applies_when CONDITIONS are satisfied by patient_facts.conditions
// This is where ontological inference matters:
// patient has E11.9 (Type 2 Diabetes)
// recommendation applies_when includes DiabetesMellitus
// reasoner infers E11.9 โ Type2Diabetes โ DiabetesMellitus โ
AND patient_facts.demographics.age >= recommendation.age_minimum (if set)
AND patient_facts.demographics.age <= recommendation.age_maximum (if set)
AND patient_facts.demographics.sex IN recommendation.sex_applies_to
AND NONE OF recommendation.excluded_by IN patient_facts.conditions
// Exclusion check: if patient is in hospice, skip all recommendations
// that list Hospice as an exclusion
FOR each recommendation in results:
// Record why this recommendation applies (for clinical justification)
justification = identify which patient conditions triggered applicability
append to applicable: {
recommendation: recommendation,
justification: justification
}
RETURN applicable
Step 4: Identify care gaps. For each applicable recommendation, check whether the recommended action has been completed within the required timeframe. This is the "gap detection" step. A gap exists when a recommendation applies to the patient but the corresponding action (identified by CPT or LOINC codes) has not been performed within the specified frequency window. The output is a concrete list of what's missing, when it was last done (if ever), and how overdue it is. Skip this step and you know what should happen but not what's actually missing.
FUNCTION identify_gaps(applicable_recommendations, patient_facts, evaluation_date):
// For each applicable recommendation, check if the action has been completed
// within the required timeframe. If not, it's a care gap.
gaps = empty list
FOR each item in applicable_recommendations:
rec = item.recommendation
// Determine the lookback window: how far back do we look for completion?
// evaluation_date minus the recommendation's frequency gives us the cutoff.
// Example: if frequency is "6 months" and today is 2026-06-01,
// cutoff is 2025-12-01. Any HbA1c after that date counts.
cutoff_date = evaluation_date MINUS rec.frequency
// Check if any of the patient's recent services satisfy this recommendation.
// A service satisfies the recommendation if its CPT or LOINC code matches
// the recommendation's action codes AND it occurred after the cutoff date.
matching_services = FILTER patient_facts.recent_services WHERE:
(service.cpt_code IN rec.recommended_action.cpt_codes
OR service.loinc_code IN rec.recommended_action.loinc_codes)
AND service.service_date >= cutoff_date
IF matching_services is empty:
// No matching service found within the required window. This is a gap.
// Find the most recent matching service ever (for "last completed" info)
last_completed = FIND most recent service in patient_facts.recent_services
WHERE cpt_code IN rec.recommended_action.cpt_codes
OR loinc_code IN rec.recommended_action.loinc_codes
gap = {
recommendation_id: rec.id,
measure_id: rec.measure_id,
action_needed: rec.recommended_action.description,
priority: rec.priority,
frequency: rec.frequency,
last_completed: last_completed.service_date IF exists ELSE "never",
days_overdue: IF last_completed exists THEN
days_between(last_completed.service_date, evaluation_date) - frequency_in_days
ELSE null,
justification: item.justification,
exclusions_checked: rec.excluded_by // document what was ruled out
}
append to gaps: gap
RETURN gaps
Step 5: Score and prioritize gaps. Not all care gaps carry equal urgency. A missed cancer screening for a high-risk patient is more urgent than a slightly overdue wellness visit. This step assigns a composite priority score based on clinical urgency (from the guideline), how overdue the action is, the patient's risk profile, and the quality measure impact (Star Rating weight, for example). The scored output enables care management teams to focus outreach on the highest-impact gaps first. Skip this step and care managers waste time on low-priority gaps while critical ones go unaddressed.
FUNCTION score_gaps(gaps, patient_facts):
// Assign a composite priority score to each gap for outreach prioritization.
scored_gaps = empty list
FOR each gap in gaps:
// Base priority from the guideline itself (high=3, medium=2, low=1)
base_score = priority_to_numeric(gap.priority)
// Overdue factor: the longer overdue, the more urgent
// Cap at 2.0x to prevent extreme outliers from dominating
overdue_factor = minimum(gap.days_overdue / 90, 2.0)
// Risk factor: patients with more comorbidities get higher priority
// (they have more to lose from missed preventive care)
comorbidity_count = count(patient_facts.conditions)
risk_factor = minimum(comorbidity_count / 3, 2.0)
// Quality measure weight: some measures impact Star Ratings more heavily
// TODO: integrate actual measure weights from quality program specs
measure_weight = lookup_measure_weight(gap.measure_id)
// Composite score (higher = more urgent)
composite_score = base_score * (1 + overdue_factor) * (1 + risk_factor * 0.3) * measure_weight
gap.composite_score = composite_score
append to scored_gaps: gap
// Sort by composite score descending (most urgent first)
SORT scored_gaps by composite_score DESCENDING
RETURN scored_gaps
Step 6: Store results and trigger downstream workflows. Write the scored gap list to the results store, keyed by patient ID and evaluation date. This creates the audit trail (what gaps were identified, when, based on what evidence) and feeds downstream systems: care management platforms for outreach, patient portals for self-service gap closure, and quality reporting dashboards. Include a summary record for population-level analytics.
FUNCTION store_gap_results(patient_id, evaluation_date, scored_gaps):
// Persist the evaluation results for downstream consumption.
record = {
patient_id: patient_id,
evaluation_date: evaluation_date,
gap_count: count(scored_gaps),
gaps: scored_gaps,
evaluated_at: current UTC timestamp,
ontology_version: current_ontology_version() // track which guideline version was used
}
// Write to DynamoDB with patient_id as partition key, evaluation_date as sort key.
// This supports both point lookups (get gaps for patient X) and range queries
// (get all evaluations for patient X over time to track gap closure).
WRITE record TO "care-gap-results" table
// If high-priority gaps exist, publish an event for real-time care management.
// The SNS topic must be encrypted with a KMS CMK. Subscribers must be within
// the same VPC or connected via PrivateLink. Minimize PHI in the event payload;
// consumers query DynamoDB for full details.
IF any gap in scored_gaps has composite_score > HIGH_PRIORITY_THRESHOLD:
PUBLISH event to encrypted SNS topic:
patient_id, high_priority_gap_count
// Omit clinical details from the event; consumers look up full
// gap data from DynamoDB using the patient_id.
RETURN record
Curious how this looks in Python? The pseudocode above covers the concepts. If you'd like to see sample Python code that demonstrates these patterns using boto3, check out the Python Example. It walks through each step with inline comments and notes on what you'd need to change for a real deployment.
Expected Results
Sample output for a 62-year-old diabetic patient with hypertension:
{ "patient_id": "PAT-2026-00482", "evaluation_date": "2026-05-15", "gap_count": 3, "gaps": [ { "recommendation_id": "rec-diabetes-hba1c", "measure_id": "HEDIS-CDC-HbA1c", "action_needed": "HbA1c Lab Test", "priority": "high", "frequency": "6 months", "last_completed": "2025-03-10", "days_overdue": 251, "composite_score": 8.4, "justification": ["Active condition: E11.9 (Type 2 Diabetes)"] }, { "recommendation_id": "rec-diabetes-retinal", "measure_id": "HEDIS-CDC-Eye", "action_needed": "Dilated Retinal Exam", "priority": "medium", "frequency": "12 months", "last_completed": "2024-11-20", "days_overdue": 181, "composite_score": 6.2, "justification": ["Active condition: E11.9 (Type 2 Diabetes)"] }, { "recommendation_id": "rec-ascvd-statin", "measure_id": "HEDIS-SPC", "action_needed": "Statin Therapy Initiation", "priority": "high", "frequency": "ongoing", "last_completed": "never", "days_overdue": null, "composite_score": 9.1, "justification": ["Active conditions: E11.9 (Diabetes), I10 (Hypertension), Age >= 40"] } ], "evaluated_at": "2026-05-15T02:14:33Z", "ontology_version": "guidelines-2026-v2.1" }
Performance benchmarks:
| Metric | Typical Value |
|---|---|
| Per-patient evaluation latency | 200-500ms |
| Batch throughput (50K patients) | ~8-15 minutes with 100 concurrent Lambdas |
| Guideline coverage | Depends on ontology completeness (typically 40-80 HEDIS measures) |
| False positive rate (gaps already closed) | 5-15% (due to claims lag) |
| Ontology update deployment time | < 30 minutes (load new RDF, validate, swap) |
| Cost per patient evaluation | ~$0.002 (Neptune query + Lambda + DynamoDB write) |
Batch throughput note: The ~8-15 minute estimate assumes 500 sequential batches (50K patients / 100 concurrent Lambdas) at 200-500ms per patient, plus Step Functions orchestration overhead. Actual throughput depends on Neptune connection pool saturation and query complexity. Key tuning parameters: set neptune_query_timeout to 30 seconds to prevent individual query hangs from stalling the batch. Monitor SparqlRequestsPerSec and MainRequestQueuePendingRequests CloudWatch metrics to detect bottlenecks. Reuse HTTP connections across invocations (initialize the requests.Session outside the Lambda handler) to avoid TCP/TLS setup costs on every query.
Where it struggles: Patients with complex multi-morbidity where guideline conflicts arise. Claims data lag causing false positive gaps. Exclusion criteria that require clinical judgment (e.g., "patient declined" is often not coded). Guidelines that reference social determinants not captured in structured data.
Why This Isn't Production-Ready
The pseudocode and architecture above demonstrate the reasoning pattern. Here's what's missing before this handles real patients at scale:
No ontology validation pipeline. The guideline ontology is the single most critical input. In production, you need automated validation: load a new ontology version, run it against a set of synthetic patients with known expected gaps, compare outputs, and reject the update if results diverge from expected. Without this, a typo in a condition hierarchy can silently suppress thousands of gap identifications.
No false positive tracking. Claims data lags 30-90 days. A gap flagged today might have been closed last week by a service that hasn't been reported yet. You need a feedback loop: when a care manager confirms a gap is already closed, record it, and track your false positive rate over time. If it exceeds 10-15%, trust erodes and outreach teams stop using the system.
No Neptune connection pooling. The pseudocode makes a fresh SPARQL request per patient. At 100 concurrent Lambdas, that's 100 simultaneous connections to Neptune. Neptune instances have connection limits (varies by instance type). You need connection reuse within Lambda warm starts, backpressure detection via MainRequestQueuePendingRequests, and graceful degradation when Neptune is saturated.
No exclusion completeness testing. Missing an exclusion means incorrectly flagging a gap (a patient in hospice getting flagged for a cancer screening, for example). Production requires a regression test suite specifically for exclusion logic, covering edge cases like temporary exclusions (pregnancy), encounter-type exclusions (hospice enrollment without a diagnosis code), and documentation-based exclusions (patient declined).
No audit trail for reasoning. HIPAA and quality program audits may require you to explain why a specific gap was (or was not) identified for a specific patient. The current output records the justification, but not the full reasoning trace: which SPARQL queries ran, which hierarchy paths were traversed, which exclusions were evaluated. For auditability, log the query and result at each reasoning step.
No multi-program support. Different quality programs (HEDIS, CMS Star Ratings, state Medicaid programs) have overlapping but non-identical measure definitions. A production system needs to evaluate the same patient against multiple program rule sets and deduplicate the output. The ontology needs program-scoped namespaces.
Variations and Extensions
Real-time gap checking at point of care. Instead of batch overnight evaluation, expose the reasoning engine as a synchronous API that clinicians can query during a visit. "What gaps does this patient have right now?" This requires sub-second Neptune query performance (achievable with warm caches and optimized SPARQL) and integration with the EHR workflow. The value is immediate: the clinician can close gaps during the visit rather than requiring a separate outreach.
Patient-facing gap notifications. Surface care gaps in the patient portal with plain-language explanations: "Based on your diabetes diagnosis, you're due for an HbA1c blood test. Your last one was 14 months ago." Include scheduling links. This shifts some gap closure responsibility to the patient, reducing outreach burden. Requires careful UX to avoid alarm without context.
Guideline conflict resolution. Extend the ontology with conflict relationships: "Recommendation A conflicts with Recommendation B when Condition C is present." When the reasoner detects a conflict, surface it to the care team with both recommendations and the clinical context, rather than silently suppressing one. This is particularly important for patients on anticoagulation, those with renal impairment affecting medication choices, and elderly patients where aggressive screening may cause more harm than benefit.
Additional Resources
AWS Documentation:
- Amazon Neptune Developer Guide
- Amazon Neptune SPARQL Reference
- Amazon Neptune SPARQL Property Paths
- AWS Step Functions Developer Guide
- AWS HIPAA Eligible Services
- Amazon Neptune Pricing
AWS Sample Repos:
-
amazon-neptune-samples: Neptune code samples including RDF loading, SPARQL queries, and graph analytics patterns -
amazon-neptune-ontology-example-blog: Demonstrates building and querying ontologies in Neptune with SPARQL property paths (archived, but code samples remain valid)
AWS Solutions and Blogs:
- Building Knowledge Graphs on AWS (Blog): Patterns for knowledge graph construction and querying on Neptune
- Healthcare Data Lake on AWS (Solution): Reference architecture for consolidating healthcare data sources that feed the reasoning engine
Estimated Implementation Time
| Tier | Timeline | What You Get |
|---|---|---|
| Basic | 6-8 weeks | Ontology for 10-15 core measures, batch evaluation, DynamoDB results store |
| Production-ready | 12-16 weeks | Full HEDIS measure set, exclusion logic, false positive tracking, care management integration |
| With variations | 20-24 weeks | Real-time point-of-care API, patient portal integration, conflict resolution, multi-program support |
Tags: knowledge-graph, ontology, care-gaps, quality-measures, HEDIS, reasoning, Neptune, SPARQL, population-health, value-based-care
โ Recipe 13.5: Clinical Pathway Protocol Modeling | Chapter 13 Index | Recipe 13.7: Disease-Gene-Drug Relationship Graph โ
โ Main Recipe 13.6 ยท Python Example ยท Chapter Preface