π₯ More Healthcare IT Projects by the Author
Two independent healthcare IT projects built by the author. They are not built on top of this library β they simply live in the same healthcare interoperability space.
- Clinic FHIR Server β a multi-tenant FHIR R4 server for clinics and community health centers: tenant-isolated FHIR storage, role-based access control, audit logging, and PHI encryption. Live demo β
- XBridge β a Prior Authorization toolkit that validates X12 278 transactions against payer Companion Guide rules and converts between X12 and FHIR R4, running 100% in your local browser. Live demo β
Installation
Install the HealthData.Interop.Fhir NuGet package into your .NET project:
# Via .NET CLI
dotnet add package HealthData.Interop.Fhir
# Via Package Manager Console
Install-Package HealthData.Interop.Fhir
# Via Paket
paket add HealthData.Interop.Fhir
Quick Start
Get up and running with FHIR R4 client operations:
using HealthDataInteropSharedLibrary.BasicClient;
using HealthDataInteropSharedLibrary.ResourceValidator;
var client = new FhirBasicService("https://your-fhir-server/fhir");
// Search patients by name
var results = await client.SearchPatientsByNameAsync("Doe");
foreach (var patient in results)
{
Console.WriteLine($"Patient: {FhirBasicService.FormatPatientName(patient)}");
}
// Create a patient
var created = await client.CreatePatientAsync(
new[] { "John" }, "Doe", "male", "1985-01-15", "MRN-1234");
// Validate a Patient resource against the R4 specification
var validator = new ResourceValidationService();
if (results.Count > 0)
{
bool valid = validator.Validate(results[0]);
Console.WriteLine(valid ? "Valid against FHIR R4." : "Validation found issues.");
}
What This Project Demonstrates
This repository is an application-layer toolkit and reference implementation for HL7 FHIR R4 interoperability on .NET, built on the Firely .NET SDK. It does not replace a FHIR server, and it does not by itself provide certified HIPAA or ONC compliance. It is a set of working patterns you can read, run, and adapt:
- FHIR client patterns β Patient create/search and chained-parameter search with
_include/_revinclude, wrapped in small testable services on top of the Firely .NET SDK. - FHIR resource validation β Firely SDK validation against the FHIR R4 specification, plus a US Core profile-declaration check (
Meta.Profile) β not full US Core IG conformance. - CSV β FHIR ETL β legacy CSV to
Patientmapping with idempotent upserts (search-then-Conditional-PUT), compile-time mapping via Mapperly. - SMART on FHIR β OAuth2/OIDC client-credentials flow with token caching, plus a SMART-style ETL import.
- Local LLM normalization β a local model (Ollama) normalizes messy records, with deterministic guardrails rejecting invalid output; designed for local inference without sending data to a cloud LLM.
- HIPAA Security Ruleβoriented examples β RBAC, consent validation, audit logging, PHI masking (45 CFR Β§164.312-style controls) β illustrative examples, not a compliance certification.
- Data drift detection β read-only reconciliation between a legacy source and the synced FHIR copy.
It is intended as a reference implementation and educational resource β see the License section below.
Modules & What They Demonstrate
Each numbered module is a small console app exercising one scenario:
| Module | What it does | What it demonstrates |
|---|---|---|
| 01 Basic FHIR Client | Patient create + search against a FHIR R4 server | The basic pattern: point a FhirClient at a server, create and search Patient resources. |
| 02 Advanced Query | Chained search; _include/_revinclude |
Fetching related resources in a single query instead of multiple round-trips. |
| 03 FHIR Resource Validation | Firely SDK validation + US Core profile check | Validation against the FHIR R4 specification (works offline), and checking that a Patient declares a US Core profile URI in Meta.Profile β profile-declaration checking, not full IG conformance. |
| 04 Data Mapping / ETL | CSV β FHIR Patient mapping pipeline |
Idempotent upserts: search by business identifier first, then Conditional PUT (ETag) or create, batched in a transaction bundle β re-running updates instead of duplicating. |
| 05 SMART on FHIR | OAuth2/OIDC client-credentials + SMART-style ETL | Token acquisition with caching/refresh, an authenticated FhirClient, and scope-based access patterns (openid profile patient/*.read). |
| 06 AI-Assisted Data Mapping | Local LLM (Ollama) record normalization | A local model normalizes messy records into a small DTO; deterministic guardrails reject invalid output. Designed for local inference β data does not need to go to a cloud LLM. |
| 07 HIPAA Technical Safeguards Demo | RBAC, consent, audit, PHI masking | Walks one simulated PHI access request through RBAC β consent (purpose of use) β audit log, with PHI-masked console output. A technical-safeguards demo, not a compliance product. |
| 08 Data Drift Detector | Read-only reconciliation, legacy source vs. FHIR copy | Field-by-field comparison with explicit outcomes: in sync / field-level drift / missing on server. Detection only β it never writes. |
API Reference
BasicClient.FhirBasicService
// Constructor: FHIR server base URL
var service = new FhirBasicService("https://your-fhir-server/fhir");
// Key methods:
var patients = await service.SearchPatientsByNameAsync("Doe");
var created = await service.CreatePatientAsync(
new[] { "John" }, "Doe", "male", "1985-01-15", "MRN-1234");
Console.WriteLine(FhirBasicService.FormatPatientName(patients[0]));
ResourceValidator.ResourceValidationService
var validator = new ResourceValidationService();
bool isValid = validator.Validate(patient);
var issues = validator.GetValidationIssues(patient);
ResourceValidator.UsCoreConformanceChecker
// Check if a Patient resource declares a US Core profile
var result = UsCoreConformanceChecker.CheckPatientConformance(patient);
Console.WriteLine(result.IsUsCoreConformant); // true or false
// Ensure Patient has a US Core profile in Meta
bool added = UsCoreConformanceChecker.EnsureUsCoreProfile(patient);
Compliance.HipaaComplianceOrchestrator
// RBAC PHI access check (8 roles) β synchronous, returns bool
var orchestrator = new HipaaComplianceOrchestrator();
bool allowed = orchestrator.ExecutePhiAccessRequest(
userId: "u-1001",
role: FhirUserRole.Physician,
ipAddress: "10.0.0.5",
patientId: "123",
accessPurpose: "Clinical review");
// PHI encryption service (AES-256-GCM; supply your own 32-byte key)
var key = new byte[32]; // key management is your responsibility
var phi = new PhiEncryptionService(key);
var (ciphertext, nonce, tag) = phi.Encrypt(sensitiveData);
var plaintext = phi.Decrypt(ciphertext, nonce, tag);
// Audit log
AuditLog.Record(
userId: "u-1001", role: "Physician", ipAddress: "10.0.0.5",
resourceType: "Patient", resourceId: "123", action: "READ");
Etl.EtlPipelineService
// CSV to FHIR Patient mapping pipeline
var mapper = new FhirPatientMapper(addTestDataTag: true, testNameMarkers: true);
var service = new EtlPipelineService(fhirClient, mapper);
var (created, updated) = await service.RunAsync("data/legacy_patients.csv");
AIDataValidator.AiValidatorService
// Requires Ollama running locally with the llama3 model.
// The AI provider is injected as a plain Func<string, Task<string>>,
// so you can point it at any local model endpoint.
var validator = new AiValidatorService(prompt => OllamaChatAsync(prompt));
var patient = await validator.ProcessRawRecordAsync("Mmale, Jhon Doe, 1990-05-14");
Security Notice
HEALTHDATA_INSECURE_SKIP_TLS=1. It must never be enabled in production (conflicts with HIPAA Β§164.312(e)(1) transmission-security requirements). Application logging is PHI-masked: SSN, patient name, DOB, phone and email are redacted before reaching the log sink. Always use valid certificates and enforce TLS 1.2+ for all FHIR server connections.
License & Disclaimer
This project is licensed under the MIT License.
NO WARRANTY / NO MAINTENANCE:
This project is provided as a reference implementation and educational resource. The author provides NO FUTURE MAINTENANCE, bug fixes, feature updates, or support. You are expected to use this code entirely at your own risk.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY ARISING FROM THE USE OF THIS SOFTWARE.
π Support this work
If this work is helpful to you, feel free to send a small gift β it helps support my work and keep the project maintained.
Alipay
Scan with Alipay to pay