148 lines
7.1 KiB
C#
148 lines
7.1 KiB
C#
using System.Net.Http.Json;
|
|
using System.Text.Json;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
|
|
/// <summary>
|
|
/// Drives lab-result batches with potassium observations through the HTTP pipeline.
|
|
/// Uses DataSeeder usernames (intake1, entry1, verifier1, approver1).
|
|
/// </summary>
|
|
public static class CorrectionPipelineHelper
|
|
{
|
|
/// <summary>
|
|
/// Creates a LAB_RESULTS batch with K and Na draft observations, drives it through
|
|
/// verify → approve, and returns the promoted batch ID and live patient ID.
|
|
/// </summary>
|
|
public static async Task<(Guid BatchId, Guid PatientId)> PromoteLabBatchAsync(
|
|
ApiFixture fixture,
|
|
decimal potassiumValue,
|
|
decimal sodiumValue = 140m)
|
|
{
|
|
var batchId = await CreateLabBatchThroughVerificationAsync(fixture, potassiumValue, sodiumValue);
|
|
|
|
var client = await AuthHelper.LoginAsync(fixture, "approver1");
|
|
client.DefaultRequestHeaders.Add("Idempotency-Key", Guid.NewGuid().ToString());
|
|
|
|
var approveResponse = await client.PostAsJsonAsync(
|
|
$"/api/v1/digitization-batches/{batchId}/approve",
|
|
new { enableRetroactiveAlerts = false });
|
|
approveResponse.EnsureSuccessStatusCode();
|
|
|
|
using var scope = fixture.Services.CreateScope();
|
|
var db = scope.ServiceProvider.GetRequiredService<AppDbContext>();
|
|
var batch = await db.DigitizationBatches.AsNoTracking().FirstAsync(b => b.Id == batchId);
|
|
|
|
return (batchId, batch.PatientId!.Value);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Uploads a correction batch linked to a promoted batch, drives entry → verify → approve.
|
|
/// </summary>
|
|
public static async Task<Guid> PromoteCorrectionBatchAsync(
|
|
ApiFixture fixture,
|
|
Guid supersedesBatchId,
|
|
Guid patientId,
|
|
decimal potassiumValue,
|
|
decimal sodiumValue = 140m)
|
|
{
|
|
var client = await AuthHelper.LoginAsync(fixture, "intake1");
|
|
|
|
var fileContent = new ByteArrayContent(System.Text.Encoding.UTF8.GetBytes("%PDF-correction"));
|
|
fileContent.Headers.ContentType =
|
|
new System.Net.Http.Headers.MediaTypeHeaderValue("application/pdf");
|
|
|
|
var formData = new MultipartFormDataContent
|
|
{
|
|
{ fileContent, "file", $"correction-{Guid.NewGuid()}.pdf" },
|
|
{ new StringContent("LAB_RESULTS"), "batchType" },
|
|
{ new StringContent("BACKFILL"), "track" },
|
|
{ new StringContent(patientId.ToString()), "patientId" },
|
|
{ new StringContent(supersedesBatchId.ToString()), "supersedesBatchId" }
|
|
};
|
|
|
|
var uploadResponse = await client.PostAsync("/api/v1/digitization-batches", formData);
|
|
uploadResponse.EnsureSuccessStatusCode();
|
|
|
|
var uploadBody = await uploadResponse.Content.ReadFromJsonAsync<JsonElement>();
|
|
var correctionBatchId = uploadBody.GetProperty("data").GetProperty("id").GetGuid();
|
|
|
|
// Data entry — correction re-enters all observations
|
|
client = await AuthHelper.LoginAsync(fixture, "entry2");
|
|
await client.PostAsJsonAsync(
|
|
$"/api/v1/digitization-batches/{correctionBatchId}/draft/observations",
|
|
new { observationCode = "K", value = potassiumValue, unit = "mmol/L",
|
|
recordedAt = DateTimeOffset.UtcNow });
|
|
await client.PostAsJsonAsync(
|
|
$"/api/v1/digitization-batches/{correctionBatchId}/draft/observations",
|
|
new { observationCode = "Na", value = sodiumValue, unit = "mmol/L",
|
|
recordedAt = DateTimeOffset.UtcNow });
|
|
var submitResponse = await client.PostAsync(
|
|
$"/api/v1/digitization-batches/{correctionBatchId}/submit-for-verification", null);
|
|
submitResponse.EnsureSuccessStatusCode();
|
|
|
|
// Verify and approve
|
|
client = await AuthHelper.LoginAsync(fixture, "verifier2");
|
|
var verifyResponse = await client.PostAsJsonAsync(
|
|
$"/api/v1/digitization-batches/{correctionBatchId}/verify",
|
|
new { fieldChecks = new[] { new { fieldName = "observation.K", status = "ok", note = (string?)null } }, passed = true });
|
|
verifyResponse.EnsureSuccessStatusCode();
|
|
|
|
client = await AuthHelper.LoginAsync(fixture, "approver2");
|
|
client.DefaultRequestHeaders.Add("Idempotency-Key", Guid.NewGuid().ToString());
|
|
var approveResponse = await client.PostAsJsonAsync(
|
|
$"/api/v1/digitization-batches/{correctionBatchId}/approve",
|
|
new { enableRetroactiveAlerts = false });
|
|
approveResponse.EnsureSuccessStatusCode();
|
|
|
|
return correctionBatchId;
|
|
}
|
|
|
|
private static async Task<Guid> CreateLabBatchThroughVerificationAsync(
|
|
ApiFixture fixture, decimal potassiumValue, decimal sodiumValue)
|
|
{
|
|
var client = await AuthHelper.LoginAsync(fixture, "intake1");
|
|
|
|
var fileContent = new ByteArrayContent(System.Text.Encoding.UTF8.GetBytes("%PDF-lab"));
|
|
fileContent.Headers.ContentType =
|
|
new System.Net.Http.Headers.MediaTypeHeaderValue("application/pdf");
|
|
|
|
var formData = new MultipartFormDataContent
|
|
{
|
|
{ fileContent, "file", $"lab-{Guid.NewGuid()}.pdf" },
|
|
{ new StringContent("LAB_RESULTS"), "batchType" },
|
|
{ new StringContent("BACKFILL"), "track" }
|
|
};
|
|
|
|
var uploadResponse = await client.PostAsync("/api/v1/digitization-batches", formData);
|
|
uploadResponse.EnsureSuccessStatusCode();
|
|
|
|
var uploadBody = await uploadResponse.Content.ReadFromJsonAsync<JsonElement>();
|
|
var batchId = uploadBody.GetProperty("data").GetProperty("id").GetGuid();
|
|
|
|
client = await AuthHelper.LoginAsync(fixture, "entry1");
|
|
await client.PutAsJsonAsync(
|
|
$"/api/v1/digitization-batches/{batchId}/draft/patient",
|
|
new { fullName = "Correction Test Patient", dateOfBirth = "1980-01-15", sex = "Female" });
|
|
await client.PutAsJsonAsync(
|
|
$"/api/v1/digitization-batches/{batchId}/draft/encounter",
|
|
new { admissionDate = "2024-06-01T08:00:00Z", department = Department.InternalMedicine.ToDbString(),
|
|
roomBed = "4A-12", admissionReason = "Electrolyte panel", status = "active" });
|
|
await client.PostAsJsonAsync(
|
|
$"/api/v1/digitization-batches/{batchId}/draft/observations",
|
|
new { observationCode = "K", value = potassiumValue, unit = "mmol/L",
|
|
recordedAt = DateTimeOffset.UtcNow });
|
|
await client.PostAsJsonAsync(
|
|
$"/api/v1/digitization-batches/{batchId}/draft/observations",
|
|
new { observationCode = "Na", value = sodiumValue, unit = "mmol/L",
|
|
recordedAt = DateTimeOffset.UtcNow });
|
|
await client.PostAsync(
|
|
$"/api/v1/digitization-batches/{batchId}/submit-for-verification", null);
|
|
|
|
client = await AuthHelper.LoginAsync(fixture, "verifier1");
|
|
await client.PostAsJsonAsync(
|
|
$"/api/v1/digitization-batches/{batchId}/verify",
|
|
new { fieldChecks = new[] { new { fieldName = "observation.K", status = "ok", note = (string?)null } }, passed = true });
|
|
|
|
return batchId;
|
|
}
|
|
} |