Upload files to ".Net Capstone Project"

This commit is contained in:
nisha.meshram 2026-08-31 12:08:15 +00:00
parent 50f53dcf7b
commit 81c0622c9c

View File

@ -0,0 +1,317 @@
using ClinicalInsightsPro.API.Data;
using ClinicalInsightsPro.API.DTOs;
using ClinicalInsightsPro.API.Services.Interfaces;
using Microsoft.EntityFrameworkCore;
using System.Text.Json;
namespace ClinicalInsightsPro.API.Services;
public class MedplumFhirService : IMedplumFhirService
{
private readonly ApplicationDbContext _db;
private readonly ILogger<MedplumFhirService> _logger;
public MedplumFhirService(
ApplicationDbContext db,
ILogger<MedplumFhirService> logger)
{
_db = db;
_logger = logger;
}
public Task<List<JsonElement>> GetMedplumResourcesAsync(string resourceType, string? patientId = null)
{
// Offline/demo mode has normalized tables, not the raw Medplum store.
// The unified Medplum browser is intentionally live-only so the UI
// always shows actual FHIR JSON when the feature is enabled.
throw new InvalidOperationException(
"The Medplum resource browser requires Fhir:UseLiveMedplum=true. " +
"Set MEDPLUM_USE_LIVE=true and configure MEDPLUM_BASE_URL, " +
"MEDPLUM_TOKEN_URL, MEDPLUM_CLIENT_ID and MEDPLUM_CLIENT_SECRET.");
}
public async Task<List<PatientSummaryDto>> GetPatientListAsync()
{
var patients = await _db.Patient
.AsNoTracking()
.OrderBy(x => x.GivenName)
.ThenBy(x => x.FamilyName)
.ToListAsync();
return patients.Select(p => new PatientSummaryDto
{
Id = p.Id,
FullName = $"{p.GivenName} {p.FamilyName}",
Age = CalculateAge(p.BirthDate),
Gender = p.Gender,
MedicalRecordNumber = p.MedicalRecordNumber
}).ToList();
}
public async Task<PatientChartDto> GetPatientChartAsync(string patientId)
{
var patient = await _db.Patient
.AsNoTracking()
.FirstOrDefaultAsync(p => p.Id == patientId);
if (patient == null)
{
throw new KeyNotFoundException(
$"Patient '{patientId}' was not found.");
}
var conditions = await _db.Condition
.AsNoTracking()
.Where(x => x.PatientId == patientId)
.OrderByDescending(x => x.RecordedDate)
.ToListAsync();
var observations = await _db.Observation
.AsNoTracking()
.Where(x => x.PatientId == patientId)
.OrderByDescending(x => x.EffectiveDateTime)
.ToListAsync();
var allergies = await _db.AllergyIntolerance
.AsNoTracking()
.Where(x => x.PatientId == patientId)
.ToListAsync();
var medications = await _db.MedicationRequest
.AsNoTracking()
.Where(x => x.PatientId == patientId)
.ToListAsync();
var encounters = await _db.Encounter
.AsNoTracking()
.Where(x => x.PatientId == patientId)
.OrderByDescending(x => x.PeriodStart)
.ToListAsync();
_logger.LogInformation(
"Retrieved chart for patient {PatientId}",
patientId);
return new PatientChartDto
{
PatientId = patient.Id,
FullName = $"{patient.GivenName} {patient.FamilyName}",
Age = CalculateAge(patient.BirthDate),
MedicalRecordNumber = patient.MedicalRecordNumber,
IdentifierSystem = patient.IdentifierSystem,
IdentifierValue = patient.IdentifierValue,
NameUse = patient.NameUse,
Prefix = patient.Prefix,
GivenName = patient.GivenName,
FamilyName = patient.FamilyName,
TelecomSystem = patient.TelecomSystem,
TelecomUse = patient.TelecomUse,
TelecomValue = patient.TelecomValue,
Gender = patient.Gender,
BloodGroup = patient.BloodGroup,
Email = patient.Email,
BirthDate = patient.BirthDate,
AddressUse = patient.AddressUse,
AddressType = patient.AddressType,
AddressLine = patient.AddressLine,
City = patient.City,
State = patient.State,
PostalCode = patient.PostalCode,
MaritalStatusSystem = patient.MaritalStatusSystem,
MaritalStatusCode = patient.MaritalStatusCode,
MaritalStatusDisplay = patient.MaritalStatusDisplay,
ContactNameUse = patient.ContactNameUse,
ContactPrefix = patient.ContactPrefix,
ContactTelecomSystem = patient.ContactTelecomSystem,
ContactTelecomUse = patient.ContactTelecomUse,
ContactTelecomValue = patient.ContactTelecomValue,
ContactAddressUse = patient.ContactAddressUse,
ContactAddressType = patient.ContactAddressType,
ContactAddressLine = patient.ContactAddressLine,
ContactCity = patient.ContactCity,
ContactState = patient.ContactState,
ContactPostalCode = patient.ContactPostalCode,
ContactGender = patient.ContactGender,
ContactOrganizationId = patient.ContactOrganizationId,
ContactPeriodStart = patient.ContactPeriodStart,
ContactPeriodEnd = patient.ContactPeriodEnd,
ManagingOrganizationId = patient.ManagingOrganizationId,
PhotoContentType = patient.PhotoContentType,
PhotoUrl = patient.PhotoUrl,
PhotoTitle = patient.PhotoTitle,
GeneralPractitionerId = patient.GeneralPractitionerId,
Conditions = conditions.Select(c => new ChartConditionDto
{
Id = c.Id,
Code = c.ConditionCode,
Display = c.ConditionDisplay,
ClinicalStatus = c.ClinicalStatusDisplay,
VerificationStatus = c.VerificationStatusDisplay,
Severity = c.SeverityDisplay,
OnsetDate = c.OnsetDateTime,
AbatementDate = c.AbatementDateTime,
RecordedDate = c.RecordedDate
}).ToList(),
Allergies = allergies.Select(a => new ChartAllergyDto
{
Id = a.Id,
Type = a.Type,
ClinicalStatus = a.ClinicalStatus,
VerificationStatus = a.VerificationStatus,
Criticality = a.Criticality,
RecorderPractitionerId = a.RecorderPractitionerId
}).ToList(),
Medications = medications.Select(m => new ChartMedicationDto
{
Id = m.Id,
MedicationCode = m.MedicationCode,
MedicationDisplay = m.MedicationDisplay,
Status = m.Status,
Intent = m.Intent,
Priority = m.Priority
}).ToList(),
Observations = observations.Select(o => new ChartObservationDto
{
Id = o.Id,
Code = o.ObservationCode,
Display = o.ObservationDisplay,
Status = o.Status,
CategoryDisplay = o.CategoryDisplay,
InterpretationCode = o.InterpretationCode,
InterpretationDisplay = o.InterpretationDisplay,
EffectiveDate = o.EffectiveDateTime,
NoteText = o.NoteText
}).ToList(),
Encounters = encounters.Select(e => new ChartEncounterDto
{
Id = e.Id,
Status = e.Status,
ClassCode = e.ClassCode,
ClassDisplay = e.ClassDisplay,
TypeDisplay = e.TypeDisplay,
ServiceTypeDisplay = e.ServiceTypeDisplay,
PeriodStart = e.PeriodStart,
PeriodEnd = e.PeriodEnd
}).ToList()
};
}
private static int CalculateAge(DateTime birthDate)
{
var today = DateTime.UtcNow;
var age = today.Year - birthDate.Year;
if (birthDate.Date > today.AddYears(-age))
{
age--;
}
return age;
}
// ---- Two-way sync additions ----
// This class is the OFFLINE/local implementation (used when
// Fhir:UseLiveMedplum=false) — it reads/writes only the local database
// and never talks to a real Medplum server, so there is nothing to push
// or pull here. These methods exist only so this class still satisfies
// IMedplumFhirService; they throw/no-op with a clear message instead of
// silently pretending to sync. Set MEDPLUM_USE_LIVE=true in .env to
// switch the app over to LiveMedplumFhirService, which implements the
// real sync against Medplum's FHIR API.
public Task<string> CreatePatientInMedplumAsync(Models.Patient patient)
{
_logger.LogWarning(
"CreatePatientInMedplumAsync called while running in offline/local mode " +
"(Fhir:UseLiveMedplum=false) — patient {Id} was saved locally only, not pushed to Medplum. " +
"Set MEDPLUM_USE_LIVE=true in .env to enable Medplum sync.", patient.Id);
return Task.FromResult(string.Empty);
}
public Task UpdatePatientInMedplumAsync(Models.Patient patient)
{
_logger.LogWarning(
"UpdatePatientInMedplumAsync called while running in offline/local mode " +
"(Fhir:UseLiveMedplum=false) — patient {Id} was updated locally only, not pushed to Medplum.", patient.Id);
return Task.CompletedTask;
}
public Task DeletePatientInMedplumAsync(string medplumId)
{
_logger.LogWarning(
"DeletePatientInMedplumAsync called while running in offline/local mode " +
"(Fhir:UseLiveMedplum=false) — nothing was deleted in Medplum.");
return Task.CompletedTask;
}
public Task<List<Models.Patient>> PullAllPatientsFromMedplumAsync()
{
_logger.LogWarning(
"PullAllPatientsFromMedplumAsync called while running in offline/local mode " +
"(Fhir:UseLiveMedplum=false) — returning an empty list. Set MEDPLUM_USE_LIVE=true in .env " +
"to pull real data from Medplum.");
return Task.FromResult(new List<Models.Patient>());
}
// ---- Practitioner two-way sync (offline no-ops, mirrors Patient above) ----
public Task<string> CreatePractitionerInMedplumAsync(Models.Practitioner practitioner)
{
_logger.LogWarning(
"CreatePractitionerInMedplumAsync called while running in offline/local mode " +
"(Fhir:UseLiveMedplum=false) — practitioner {Id} was saved locally only, not pushed to Medplum. " +
"Set MEDPLUM_USE_LIVE=true in .env to enable Medplum sync.", practitioner.Id);
return Task.FromResult(string.Empty);
}
public Task UpdatePractitionerInMedplumAsync(Models.Practitioner practitioner)
{
_logger.LogWarning(
"UpdatePractitionerInMedplumAsync called while running in offline/local mode " +
"(Fhir:UseLiveMedplum=false) — practitioner {Id} was updated locally only, not pushed to Medplum.", practitioner.Id);
return Task.CompletedTask;
}
public Task DeletePractitionerInMedplumAsync(string medplumId)
{
_logger.LogWarning(
"DeletePractitionerInMedplumAsync called while running in offline/local mode " +
"(Fhir:UseLiveMedplum=false) — nothing was deleted in Medplum.");
return Task.CompletedTask;
}
public Task<List<Models.Practitioner>> PullAllPractitionersFromMedplumAsync()
{
_logger.LogWarning(
"PullAllPractitionersFromMedplumAsync called while running in offline/local mode " +
"(Fhir:UseLiveMedplum=false) — returning an empty list. Set MEDPLUM_USE_LIVE=true in .env " +
"to pull real data from Medplum.");
return Task.FromResult(new List<Models.Practitioner>());
}
}