UI はローカライズ済みです。スキルの紹介と説明文書は選択した言語へ AI が自動翻訳し、コード・コマンド・パス・専門用語は原文のままです。原作者の文書が優先されます。
スキルを探す
データ・研究 · SKILL.md

ehr-integration

ehr-integration

Integrate with Electronic Health Record (EHR) systems including Epic, Cerner, and other FHIR-compliant platforms. Covers FHIR R4 APIs, SMART on FHIR authentication, patient data access, clinical workflows, and HIPAA compliance.

Independent GitHub snapshot · Automated classification · Original documentation governs

スキルの説明

GitHub

name: ehr-integration description: "Integrate with Electronic Health Record (EHR) systems including Epic, Cerner, and other FHIR-compliant platforms. Covers FHIR R4 APIs, SMART on FHIR authentication, patient data access, clinical workflows, and HIPAA compliance." license: Apache 2.0 tags: ["ehr", "epic", "cerner", "fhir", "healthcare", "hipaa", "clinical", "health-it"] difficulty: advanced time_to_master: "14-24 weeks" version: "1.0.0"

EHR Integration

Overview

Electronic Health Record (EHR) systems — primarily Epic (38% market share) and Oracle Health/Cerner (22%) — manage patient data for hospitals and health systems. The HL7 FHIR (Fast Healthcare Interoperability Resources) standard provides a modern REST API for accessing patient demographics, clinical observations, medications, allergies, and care plans. Integrating with EHR systems enables AI-powered clinical decision support, care coordination, and administrative automation.

When to Use This Skill

  • Building FHIR-compliant integrations with Epic or Cerner
  • Implementing SMART on FHIR authentication for healthcare apps
  • Creating patient data access workflows (demographics, conditions, medications)
  • Building clinical decision support tools
  • Automating healthcare administrative workflows (scheduling, referrals)

Core Concepts

EHR Platform Landscape

PlatformMarket ShareFHIR SupportAuthCertification
Epic38%FHIR R4SMART on FHIRONC-certified
Oracle Health (Cerner)22%FHIR R4SMART on FHIRONC-certified
MEDITECH16%FHIR R4SMART on FHIRONC-certified
Allscripts5%FHIR R4OAuth 2.0ONC-certified

FHIR Resource Types

Patient ──────────► Demographics (name, DOB, address, contact)
  │
  ├── Condition ──► Diagnoses (ICD-10 codes, onset, status)
  │
  ├── Observation ► Vitals, lab results (LOINC codes)
  │
  ├── MedicationRequest ► Prescriptions (RxNorm codes)
  │
  ├── AllergyIntolerance ► Allergies & drug sensitivities
  │
  ├── Procedure ──► Surgical/clinical procedures (CPT codes)
  │
  ├── Encounter ──► Visits, admissions, appointments
  │
  ├── DocumentReference ► Clinical notes, reports
  │
  └── CarePlan ───► Treatment plans with goals and activities

SMART on FHIR Authentication

┌──────────┐     ┌──────────────┐     ┌──────────┐
│  App     │────►│ EHR Auth     │────►│ Launch   │
│          │     │ Endpoint     │     │ Context  │
└──────────┘     └──────────────┘     └────┬─────┘
                                          │
     ┌─────────────────────────────────────┘
     │ authorization_code + launch context
     ▼
┌──────────┐     ┌──────────────┐
│ Token    │────►│ FHIR Server  │
│ Exchange │     │ (with token) │
└──────────┘     └──────────────┘

Implementation Guide

FHIR Client Setup

import FHIR from "fhirclient";

// SMART on FHIR launch
FHIR.oauth2.authorize({
  clientId: process.env.FHIR_CLIENT_ID,
  scope: "launch patient/Patient.read patient/Observation.read patient/Condition.read patient/MedicationRequest.read",
  redirectUri: "/callback",
});

// After authorization - query patient data
const client = await FHIR.oauth2.ready();

// Get patient demographics
const patient = await client.patient.read();
console.log(`Patient: ${patient.name[0].given.join(" ")} ${patient.name[0].family}`);
console.log(`DOB: ${patient.birthDate}`);
console.log(`MRN: ${patient.identifier.find(i => i.type?.coding?.[0]?.code === "MR")?.value}`);

Querying Clinical Data

// Get active conditions (diagnoses)
const conditions = await client.request(
  `Condition?patient=${patientId}&clinical-status=active&_sort=-onset-date&_count=20`
);

// Get recent lab results
const labs = await client.request(
  `Observation?patient=${patientId}&category=laboratory&_sort=-date&_count=20`
);

// Get current medications
const medications = await client.request(
  `MedicationRequest?patient=${patientId}&status=active&_include=MedicationRequest:medication`
);

// Get allergies
const allergies = await client.request(
  `AllergyIntolerance?patient=${patientId}&clinical-status=active`
);

// Search patients by identifier or name
const patients = await client.request(
  `Patient?family=Smith&given=John&birthdate=1985-03-15`
);

Patient Summary Builder

async function buildPatientSummary(client, patientId) {
  // Fetch all relevant data in parallel
  const [patient, conditions, meds, allergies, vitals] = await Promise.all([
    client.request(`Patient/${patientId}`),
    client.request(`Condition?patient=${patientId}&clinical-status=active`),
    client.request(`MedicationRequest?patient=${patientId}&status=active`),
    client.request(`AllergyIntolerance?patient=${patientId}`),
    client.request(`Observation?patient=${patientId}&category=vital-signs&_sort=-date&_count=10`),
  ]);

  return {
    demographics: {
      name: formatName(patient.name[0]),
      dob: patient.birthDate,
      gender: patient.gender,
      mrn: getMRN(patient),
    },
    activeConditions: conditions.entry?.map(e => ({
      condition: e.resource.code.text || e.resource.code.coding[0].display,
      icd10: e.resource.code.coding.find(c => c.system.includes("icd"))?.code,
      onset: e.resource.onsetDateTime,
    })) || [],
    medications: meds.entry?.map(e => ({
      medication: e.resource.medicationCodeableConcept?.text || "Unknown",
      dosage: e.resource.dosageInstruction?.[0]?.text,
      prescriber: e.resource.requester?.display,
    })) || [],
    allergies: allergies.entry?.map(e => ({
      substance: e.resource.code.text,
      reaction: e.resource.reaction?.[0]?.manifestation?.[0]?.text,
      severity: e.resource.reaction?.[0]?.severity,
    })) || [],
    recentVitals: vitals.entry?.map(e => ({
      type: e.resource.code.text,
      value: `${e.resource.valueQuantity?.value} ${e.resource.valueQuantity?.unit}`,
      date: e.resource.effectiveDateTime,
    })) || [],
  };
}

Clinical Terminology

SystemPurposeExample
ICD-10DiagnosesE11.9 (Type 2 Diabetes)
LOINCLab tests/vitals2339-0 (Blood Glucose)
RxNormMedications860975 (Metformin 500mg)
CPTProcedures99213 (Office Visit)
SNOMED CTClinical terms44054006 (Diabetes mellitus)

HIPAA Compliance Requirements

RequirementImplementation
Minimum NecessaryOnly request FHIR resources needed for the use case
Access LoggingLog every FHIR API call with user, patient, resource, timestamp
Encryption at RestEncrypt stored PHI with AES-256
Encryption in TransitTLS 1.2+ for all API calls
Access ControlsRole-based access, session timeouts, MFA
Audit TrailImmutable log of all PHI access and modifications
BAAExecute Business Associate Agreement before accessing PHI
De-identificationRemove 18 HIPAA identifiers for research/analytics use

Best Practices

  1. Always use SMART on FHIR — don't build custom auth for EHR access
  2. Minimize data access — only request the FHIR resources you need
  3. Cache nothing containing PHI — or encrypt with strict TTLs
  4. Use _include to reduce round trips — fetch related resources in one call
  5. Handle pagination — FHIR bundles use link[rel=next] for pagination
  6. Test in sandbox first — both Epic and Cerner provide FHIR sandboxes
  7. Map clinical codes carefully — always cross-reference ICD-10, LOINC, RxNorm

Resources

Changelog

VersionDateChanges
1.0.02026-03-31Initial documentation
保存したスキル