Files
vigilcare-clinical/VigilCareClinicalAPI.Tests/GapAnalysisFixTests.cs
T

622 lines
26 KiB
C#

using System.Net;
using System.Net.Http.Json;
using System.Text.Json;
using FluentAssertions;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using StackExchange.Redis;
/// <summary>
/// Tests for gap-analysis fixes: MRN sequence, sepsis bundle idempotency,
/// trend alert exact match, order→bundle transaction, FHIR bundle rollback,
/// patient update endpoint, new list endpoints, and new validators.
/// </summary>
[Collection("Integration")]
public class GapAnalysisFixTests : IAsyncLifetime
{
private readonly ApiFixture _fixture;
private readonly HttpClient _client;
public GapAnalysisFixTests(ApiFixture fixture)
{
_fixture = fixture;
_client = fixture.CreateClient();
}
public async Task InitializeAsync()
{
using var scope = _fixture.Services.CreateScope();
var db = scope.ServiceProvider.GetRequiredService<AppDbContext>();
await DbResetHelper.ResetAsync(db);
var redis = scope.ServiceProvider.GetRequiredService<IConnectionMultiplexer>();
await DataSeeder.SeedThresholdsOnlyAsync(db, redis);
}
public Task DisposeAsync() => Task.CompletedTask;
// -------------------------------------------------------------------------
// P0 — MRN generation uses sequence (no duplicates on concurrent registration)
// -------------------------------------------------------------------------
[Fact]
public async Task MrnGeneration_SequentialRegistrations_ProduceUniqueMrns()
{
var resp1 = await _client.PostAsJsonAsync("/api/v1/patients",
new RegisterPatientRequest("Alice", "One", new DateOnly(1990, 1, 1), "F"));
var resp2 = await _client.PostAsJsonAsync("/api/v1/patients",
new RegisterPatientRequest("Bob", "Two", new DateOnly(1991, 2, 2), "M"));
resp1.StatusCode.Should().Be(HttpStatusCode.Created);
resp2.StatusCode.Should().Be(HttpStatusCode.Created);
var p1 = (await resp1.Content.ReadFromJsonAsync<JsonElement>())
.GetProperty("data").GetProperty("mrn").GetString();
var p2 = (await resp2.Content.ReadFromJsonAsync<JsonElement>())
.GetProperty("data").GetProperty("mrn").GetString();
p1.Should().StartWith("MRN-");
p2.Should().StartWith("MRN-");
p1.Should().NotBe(p2);
}
[Fact]
public async Task MrnGeneration_FormatMatchesConfiguredPattern()
{
var resp = await _client.PostAsJsonAsync("/api/v1/patients",
new RegisterPatientRequest("Format", "Test", new DateOnly(1985, 5, 5), "F"));
resp.StatusCode.Should().Be(HttpStatusCode.Created);
var mrn = (await resp.Content.ReadFromJsonAsync<JsonElement>())
.GetProperty("data").GetProperty("mrn").GetString()!;
mrn.Should().MatchRegex(@"^MRN-\d{6}$");
}
// -------------------------------------------------------------------------
// P0 — Trend alert uses exact observation_code match
// -------------------------------------------------------------------------
[Fact]
public async Task TrendAlert_StoresObservationCode()
{
using var scope = _fixture.Services.CreateScope();
var db = scope.ServiceProvider.GetRequiredService<AppDbContext>();
var detector = scope.ServiceProvider.GetRequiredService<TrendDetector>();
var patient = new Patient
{
Id = Guid.NewGuid(), Mrn = "MRN-TREND-OC", FirstName = "OC", LastName = "Test",
DateOfBirth = new DateOnly(1970, 1, 1), Gender = "M",
CreatedAt = DateTimeOffset.UtcNow
};
var encounter = new Encounter
{
Id = Guid.NewGuid(), PatientId = patient.Id, EncounterType = EncounterType.Inpatient,
Status = EncounterStatus.Active, Department = Department.Icu,
AttendingPhysician = "Dr. OC", AdmittedAt = DateTimeOffset.UtcNow,
CreatedAt = DateTimeOffset.UtcNow
};
db.Patients.Add(patient);
db.Encounters.Add(encounter);
await db.SaveChangesAsync();
var redis = scope.ServiceProvider.GetRequiredService<IConnectionMultiplexer>();
foreach (var key in TrendCalculator.AllHistoryKeys(encounter.Id))
await redis.GetDatabase().KeyDeleteAsync(key);
var baseTime = new DateTimeOffset(2026, 6, 20, 10, 0, 0, TimeSpan.Zero);
await detector.ProcessObservationAsync(
encounter.Id, patient.Id, "HEART_RATE", 72m, baseTime);
var result = await detector.ProcessObservationAsync(
encounter.Id, patient.Id, "HEART_RATE", 95m, baseTime.AddMinutes(10));
result.Outcome.Should().Be(TrendOutcome.RapidDeterioration);
var alert = await db.ClinicalAlerts.SingleAsync(a =>
a.EncounterId == encounter.Id && a.AlertType == AlertType.RapidDeterioration);
alert.ObservationCode.Should().Be("HEART_RATE");
}
// -------------------------------------------------------------------------
// P1 — Order→Bundle spanning transaction
// -------------------------------------------------------------------------
[Fact]
public async Task OrderResult_UpdatesBundleElement_InSameTransaction()
{
using var scope = _fixture.Services.CreateScope();
var db = scope.ServiceProvider.GetRequiredService<AppDbContext>();
var handler = scope.ServiceProvider.GetRequiredService<SepsisAlertHandler>();
var bundleService = scope.ServiceProvider.GetRequiredService<ISepsisBundleService>();
var patient = new Patient
{
Id = Guid.NewGuid(), Mrn = "MRN-TX-001", FirstName = "Tx", LastName = "Test",
DateOfBirth = new DateOnly(1960, 1, 1), Gender = "M",
CreatedAt = DateTimeOffset.UtcNow
};
var encounter = new Encounter
{
Id = Guid.NewGuid(), PatientId = patient.Id, EncounterType = EncounterType.Inpatient,
Status = EncounterStatus.Active, Department = Department.Icu,
AttendingPhysician = "Dr. Tx", AdmittedAt = DateTimeOffset.UtcNow,
CreatedAt = DateTimeOffset.UtcNow
};
db.Patients.Add(patient);
db.Encounters.Add(encounter);
var alertId = Guid.NewGuid();
db.ClinicalAlerts.Add(new ClinicalAlert
{
Id = alertId, EncounterId = encounter.Id, PatientId = patient.Id,
AlertType = AlertType.SofaSepsis, Severity = AlertSeverity.Critical,
Details = "SOFA delta +2", Status = AlertStatus.Open,
TriggeredAt = DateTimeOffset.UtcNow
});
await db.SaveChangesAsync();
await handler.OnSepsisAlertCreatedAsync(
encounter.Id, alertId, AlertType.SofaSepsis, CancellationToken.None);
var element = await db.SepsisBundleElements
.Include(e => e.Order)
.FirstAsync(e => e.ElementType == SepsisBundleElementType.SerumLactate);
var orderService = scope.ServiceProvider.GetRequiredService<IOrderService>();
var order = element.Order!;
order.Status = OrderStatus.InProgress;
await db.SaveChangesAsync();
await orderService.RecordResultAsync(order.Id,
new RecordOrderResultRequest("Lactate 1.5 mmol/L"));
var updatedOrder = await db.Orders.AsNoTracking().FirstAsync(o => o.Id == order.Id);
var updatedElement = await db.SepsisBundleElements.AsNoTracking()
.FirstAsync(e => e.Id == element.Id);
updatedOrder.Status.Should().Be(OrderStatus.Resulted);
updatedElement.Status.Should().Be(SepsisBundleElementStatus.Completed);
}
// -------------------------------------------------------------------------
// P4 — Patient update endpoint (PATCH)
// -------------------------------------------------------------------------
[Fact]
public async Task PatientUpdate_PartialFields_UpdatesOnlyProvided()
{
var createResp = await _client.PostAsJsonAsync("/api/v1/patients",
new RegisterPatientRequest("Original", "Name", new DateOnly(1990, 1, 1), "F"));
createResp.StatusCode.Should().Be(HttpStatusCode.Created);
var patientId = (await createResp.Content.ReadFromJsonAsync<JsonElement>())
.GetProperty("data").GetProperty("id").GetGuid();
var patchResp = await _client.PatchAsJsonAsync($"/api/v1/patients/{patientId}",
new { lastName = "Updated", allergies = "Penicillin" });
patchResp.StatusCode.Should().Be(HttpStatusCode.OK);
var getResp = await _client.GetFromJsonAsync<JsonElement>($"/api/v1/patients/{patientId}");
var data = getResp.GetProperty("data");
data.GetProperty("firstName").GetString().Should().Be("Original");
data.GetProperty("lastName").GetString().Should().Be("Updated");
data.GetProperty("allergies").GetString().Should().Be("Penicillin");
}
[Fact]
public async Task PatientUpdate_NonExistent_Returns404()
{
var resp = await _client.PatchAsJsonAsync($"/api/v1/patients/{Guid.NewGuid()}",
new { firstName = "Ghost" });
resp.StatusCode.Should().Be(HttpStatusCode.NotFound);
}
[Fact]
public async Task PatientUpdate_CreatesAuditLog()
{
var createResp = await _client.PostAsJsonAsync("/api/v1/patients",
new RegisterPatientRequest("Audit", "Before", new DateOnly(1985, 3, 3), "M"));
var patientId = (await createResp.Content.ReadFromJsonAsync<JsonElement>())
.GetProperty("data").GetProperty("id").GetGuid();
await _client.PatchAsJsonAsync($"/api/v1/patients/{patientId}",
new { lastName = "After" });
var auditResp = await _client.GetFromJsonAsync<JsonElement>(
$"/api/v1/audit-logs?entityType=Patient&entityId={patientId}");
var logs = auditResp.GetProperty("data").GetProperty("items");
logs.EnumerateArray().Should().Contain(log =>
log.GetProperty("action").GetString() == "PATIENT_UPDATED");
}
// -------------------------------------------------------------------------
// P4 — Sepsis bundle list endpoint
// -------------------------------------------------------------------------
[Fact]
public async Task SepsisBundleList_ReturnsPagedResults()
{
using var scope = _fixture.Services.CreateScope();
var db = scope.ServiceProvider.GetRequiredService<AppDbContext>();
var handler = scope.ServiceProvider.GetRequiredService<SepsisAlertHandler>();
var patient = new Patient
{
Id = Guid.NewGuid(), Mrn = "MRN-LIST-001", FirstName = "List", LastName = "Test",
DateOfBirth = new DateOnly(1970, 1, 1), Gender = "F",
CreatedAt = DateTimeOffset.UtcNow
};
var encounter = new Encounter
{
Id = Guid.NewGuid(), PatientId = patient.Id, EncounterType = EncounterType.Inpatient,
Status = EncounterStatus.Active, Department = Department.Icu,
AttendingPhysician = "Dr. List", AdmittedAt = DateTimeOffset.UtcNow,
CreatedAt = DateTimeOffset.UtcNow
};
db.Patients.Add(patient);
db.Encounters.Add(encounter);
var alertId = Guid.NewGuid();
db.ClinicalAlerts.Add(new ClinicalAlert
{
Id = alertId, EncounterId = encounter.Id, PatientId = patient.Id,
AlertType = AlertType.SofaSepsis, Severity = AlertSeverity.Critical,
Details = "SOFA delta +2", Status = AlertStatus.Open,
TriggeredAt = DateTimeOffset.UtcNow
});
await db.SaveChangesAsync();
await handler.OnSepsisAlertCreatedAsync(
encounter.Id, alertId, AlertType.SofaSepsis, CancellationToken.None);
var resp = await _client.GetFromJsonAsync<JsonElement>(
"/api/v1/sepsis-bundles?status=IN_PROGRESS&page=1&pageSize=10");
var data = resp.GetProperty("data");
data.GetProperty("totalCount").GetInt32().Should().BeGreaterThanOrEqualTo(1);
var bundle = data.GetProperty("items").EnumerateArray()
.First(b => b.GetProperty("encounterId").GetGuid() == encounter.Id);
bundle.GetProperty("complianceStatus").GetString().Should().Be("IN_PROGRESS");
bundle.GetProperty("firstName").GetString().Should().Be("List");
bundle.GetProperty("lastName").GetString().Should().Be("Test");
bundle.GetProperty("mrn").GetString().Should().Be("MRN-LIST-001");
bundle.GetProperty("department").GetString().Should().Be("Icu");
bundle.GetProperty("elements").EnumerateArray().Should().HaveCount(4);
}
// -------------------------------------------------------------------------
// P1 — encounter timeline endpoint
// -------------------------------------------------------------------------
[Fact]
public async Task EncounterTimeline_ReturnsMergedEventTypes()
{
using var scope = _fixture.Services.CreateScope();
var db = scope.ServiceProvider.GetRequiredService<AppDbContext>();
var patient = new Patient
{
Id = Guid.NewGuid(), Mrn = "MRN-TL-001", FirstName = "TL", LastName = "Test",
DateOfBirth = new DateOnly(1980, 1, 1), Gender = "M",
CreatedAt = DateTimeOffset.UtcNow
};
var admittedAt = DateTimeOffset.UtcNow.AddHours(-6);
var encounter = new Encounter
{
Id = Guid.NewGuid(), PatientId = patient.Id, EncounterType = EncounterType.Inpatient,
Status = EncounterStatus.Active, Department = Department.Icu,
AttendingPhysician = "Dr. TL", AdmittedAt = admittedAt,
CreatedAt = DateTimeOffset.UtcNow
};
db.Patients.Add(patient);
db.Encounters.Add(encounter);
db.Observations.Add(new Observation
{
Id = Guid.NewGuid(), EncounterId = encounter.Id,
ObservationCode = "TEMP_C", Value = 38.8m, Unit = "C",
Source = ObservationSource.Manual, RecordedAt = admittedAt.AddHours(1),
CreatedAt = DateTimeOffset.UtcNow
});
db.ClinicalAlerts.Add(new ClinicalAlert
{
Id = Guid.NewGuid(), EncounterId = encounter.Id, PatientId = patient.Id,
AlertType = AlertType.QsofaScreen, Severity = AlertSeverity.Warning,
Details = "qSOFA screen", Status = AlertStatus.Open,
TriggeredAt = admittedAt.AddHours(2)
});
db.Orders.Add(new Order
{
Id = Guid.NewGuid(), EncounterId = encounter.Id,
OrderType = OrderType.Lab, Description = "Blood cultures",
OrderedBy = "Dr. TL", Status = OrderStatus.Pending,
OrderedAt = admittedAt.AddHours(3)
});
db.MedicationAdministrations.Add(new MedicationAdministration
{
Id = Guid.NewGuid(), EncounterId = encounter.Id,
DrugName = "Ceftriaxone", Dose = 1m, DoseUnit = "g", Route = "IV",
AdministeredAt = admittedAt.AddHours(4), AdministeredBy = "RN TL"
});
await db.SaveChangesAsync();
var resp = await _client.GetFromJsonAsync<JsonElement>(
$"/api/v1/encounters/{encounter.Id}/timeline");
var items = resp.GetProperty("data").GetProperty("events");
var types = items.EnumerateArray().Select(e => e.GetProperty("type").GetString()).ToList();
types.Should().Contain("status");
types.Should().Contain("observation");
types.Should().Contain("alert");
types.Should().Contain("order");
types.Should().Contain("medication");
}
// -------------------------------------------------------------------------
// P4 — qSOFA history endpoint
// -------------------------------------------------------------------------
[Fact]
public async Task QsofaHistory_ReturnsEvaluationRecords()
{
using var scope = _fixture.Services.CreateScope();
var db = scope.ServiceProvider.GetRequiredService<AppDbContext>();
var patient = new Patient
{
Id = Guid.NewGuid(), Mrn = "MRN-QH-001", FirstName = "QH", LastName = "Test",
DateOfBirth = new DateOnly(1975, 1, 1), Gender = "F",
CreatedAt = DateTimeOffset.UtcNow
};
var encounter = new Encounter
{
Id = Guid.NewGuid(), PatientId = patient.Id, EncounterType = EncounterType.Inpatient,
Status = EncounterStatus.Active, Department = Department.Icu,
AttendingPhysician = "Dr. QH", AdmittedAt = DateTimeOffset.UtcNow,
CreatedAt = DateTimeOffset.UtcNow
};
db.Patients.Add(patient);
db.Encounters.Add(encounter);
var now = DateTimeOffset.UtcNow;
db.QsofaEvaluations.Add(new QsofaEvaluation
{
Id = Guid.NewGuid(),
EncounterId = encounter.Id,
PatientId = patient.Id,
ActiveCriteria = 1,
RespRate = 24m,
EvaluatedAt = now.AddMinutes(-30),
CreatedAt = now,
});
db.QsofaEvaluations.Add(new QsofaEvaluation
{
Id = Guid.NewGuid(),
EncounterId = encounter.Id,
PatientId = patient.Id,
ActiveCriteria = 2,
RespRate = 24m,
SystolicBp = 95m,
ScreenAlertFired = true,
EvaluatedAt = now.AddMinutes(-10),
CreatedAt = now,
});
await db.SaveChangesAsync();
var resp = await _client.GetFromJsonAsync<JsonElement>(
$"/api/v1/encounters/{encounter.Id}/qsofa/history?limit=10");
var data = resp.GetProperty("data");
var items = data.GetProperty("items");
items.GetArrayLength().Should().Be(2);
var latest = items[0];
latest.GetProperty("activeCriteria").GetInt32().Should().Be(2);
latest.GetProperty("screenAlertFired").GetBoolean().Should().BeTrue();
}
// -------------------------------------------------------------------------
// P4 — Reconciliation alerts endpoint
// -------------------------------------------------------------------------
[Fact]
public async Task ReconciliationAlerts_ListWithFilter()
{
using var scope = _fixture.Services.CreateScope();
var db = scope.ServiceProvider.GetRequiredService<AppDbContext>();
var patient = new Patient
{
Id = Guid.NewGuid(), Mrn = "MRN-RECON-001", FirstName = "Recon", LastName = "Test",
DateOfBirth = new DateOnly(1980, 1, 1), Gender = "F",
CreatedAt = DateTimeOffset.UtcNow
};
var encounter = new Encounter
{
Id = Guid.NewGuid(), PatientId = patient.Id, EncounterType = EncounterType.Inpatient,
Status = EncounterStatus.Active, Department = Department.Icu,
AttendingPhysician = "Dr. Recon", AdmittedAt = DateTimeOffset.UtcNow,
CreatedAt = DateTimeOffset.UtcNow
};
db.Patients.Add(patient);
db.Encounters.Add(encounter);
db.ReconciliationAlerts.Add(new ReconciliationAlert
{
Id = Guid.NewGuid(),
CheckType = ReconciliationCheckType.UnacknowledgedCriticalAlert,
EncounterId = encounter.Id,
PatientId = patient.Id,
Details = "Test reconciliation alert",
CreatedAt = DateTimeOffset.UtcNow
});
await db.SaveChangesAsync();
var resp = await _client.GetFromJsonAsync<JsonElement>(
"/api/v1/reconciliation-alerts?resolved=false&page=1&pageSize=10");
var data = resp.GetProperty("data");
data.GetProperty("totalCount").GetInt32().Should().BeGreaterThanOrEqualTo(1);
data.GetProperty("items").EnumerateArray().Should().Contain(a =>
a.GetProperty("details").GetString()!.Contains("Test reconciliation alert"));
}
[Fact]
public async Task ReconciliationAlerts_FilterByCheckType()
{
using var scope = _fixture.Services.CreateScope();
var db = scope.ServiceProvider.GetRequiredService<AppDbContext>();
var patient = new Patient
{
Id = Guid.NewGuid(), Mrn = "MRN-RECON-002", FirstName = "Recon2", LastName = "Test",
DateOfBirth = new DateOnly(1980, 1, 1), Gender = "M",
CreatedAt = DateTimeOffset.UtcNow
};
var encounter = new Encounter
{
Id = Guid.NewGuid(), PatientId = patient.Id, EncounterType = EncounterType.Inpatient,
Status = EncounterStatus.Active, Department = Department.Icu,
AttendingPhysician = "Dr. Recon2", AdmittedAt = DateTimeOffset.UtcNow,
CreatedAt = DateTimeOffset.UtcNow
};
db.Patients.Add(patient);
db.Encounters.Add(encounter);
db.ReconciliationAlerts.Add(new ReconciliationAlert
{
Id = Guid.NewGuid(),
CheckType = ReconciliationCheckType.PendingOrderNoResult,
EncounterId = encounter.Id,
Details = "Pending order check",
CreatedAt = DateTimeOffset.UtcNow
});
await db.SaveChangesAsync();
var resp = await _client.GetFromJsonAsync<JsonElement>(
"/api/v1/reconciliation-alerts?checkType=PENDING_ORDER_NO_RESULT");
var items = resp.GetProperty("data").GetProperty("items");
items.GetArrayLength().Should().BeGreaterThanOrEqualTo(1);
}
// -------------------------------------------------------------------------
// P2 — New validators return 400 for invalid input
// -------------------------------------------------------------------------
[Fact]
public async Task TransitionStatusValidator_LongDiagnosis_Returns400()
{
var patientId = await CreatePatientAsync();
var encounterId = await CreateEncounterAsync(patientId);
var resp = await _client.PatchAsJsonAsync(
$"/api/v1/encounters/{encounterId}/status",
new { status = "Discharged", dischargeDiagnosis = new string('x', 501) });
resp.StatusCode.Should().Be(HttpStatusCode.BadRequest);
}
[Fact]
public async Task UpdatePatientValidator_LongFirstName_Returns400()
{
var patientId = await CreatePatientAsync();
var resp = await _client.PatchAsJsonAsync(
$"/api/v1/patients/{patientId}",
new { firstName = new string('x', 101) });
resp.StatusCode.Should().Be(HttpStatusCode.BadRequest);
}
// -------------------------------------------------------------------------
// P2 — Outbox retry columns exist
// -------------------------------------------------------------------------
[Fact]
public async Task OutboxEvent_HasRetryColumns()
{
using var scope = _fixture.Services.CreateScope();
var db = scope.ServiceProvider.GetRequiredService<AppDbContext>();
var ev = new OutboxEvent
{
Id = Guid.NewGuid(),
Topic = "test.retry",
Payload = "{}",
PartitionKey = "test",
CreatedAt = DateTimeOffset.UtcNow,
RetryCount = 3,
LastError = "Connection refused",
FailedAt = DateTimeOffset.UtcNow
};
db.OutboxEvents.Add(ev);
await db.SaveChangesAsync();
var loaded = await db.OutboxEvents.AsNoTracking().FirstAsync(e => e.Id == ev.Id);
loaded.RetryCount.Should().Be(3);
loaded.LastError.Should().Be("Connection refused");
loaded.FailedAt.Should().NotBeNull();
}
// -------------------------------------------------------------------------
// P0 — ClinicalAlert.ObservationCode column persists
// -------------------------------------------------------------------------
[Fact]
public async Task ClinicalAlert_ObservationCode_Persists()
{
using var scope = _fixture.Services.CreateScope();
var db = scope.ServiceProvider.GetRequiredService<AppDbContext>();
var patient = new Patient
{
Id = Guid.NewGuid(), Mrn = "MRN-OC-001", FirstName = "OC", LastName = "Persist",
DateOfBirth = new DateOnly(1980, 1, 1), Gender = "F",
CreatedAt = DateTimeOffset.UtcNow
};
var encounter = new Encounter
{
Id = Guid.NewGuid(), PatientId = patient.Id, EncounterType = EncounterType.Inpatient,
Status = EncounterStatus.Active, Department = Department.Icu,
AttendingPhysician = "Dr. OC", AdmittedAt = DateTimeOffset.UtcNow,
CreatedAt = DateTimeOffset.UtcNow
};
db.Patients.Add(patient);
db.Encounters.Add(encounter);
var alert = new ClinicalAlert
{
Id = Guid.NewGuid(), EncounterId = encounter.Id, PatientId = patient.Id,
AlertType = AlertType.RapidDeterioration, Severity = AlertSeverity.Warning,
Details = "Test", ObservationCode = "SPO2", Status = AlertStatus.Open,
TriggeredAt = DateTimeOffset.UtcNow
};
db.ClinicalAlerts.Add(alert);
await db.SaveChangesAsync();
var loaded = await db.ClinicalAlerts.AsNoTracking().FirstAsync(a => a.Id == alert.Id);
loaded.ObservationCode.Should().Be("SPO2");
}
// -------------------------------------------------------------------------
// Helpers
// -------------------------------------------------------------------------
private async Task<Guid> CreatePatientAsync()
{
var resp = await _client.PostAsJsonAsync("/api/v1/patients",
new RegisterPatientRequest("Gap", "Test", new DateOnly(1990, 1, 1), "F"));
resp.EnsureSuccessStatusCode();
var body = await resp.Content.ReadFromJsonAsync<JsonElement>();
return body.GetProperty("data").GetProperty("id").GetGuid();
}
private async Task<Guid> CreateEncounterAsync(Guid patientId)
{
var resp = await _client.PostAsJsonAsync(
$"/api/v1/patients/{patientId}/encounters",
new OpenEncounterRequest(EncounterType.Inpatient, Department.Icu, "Dr. Gap"));
resp.EnsureSuccessStatusCode();
var body = await resp.Content.ReadFromJsonAsync<JsonElement>();
return body.GetProperty("data").GetProperty("id").GetGuid();
}
}