Files
vigilcare-clinical/VigilCareClinicalAPI/Services/DischargeSummaryService.cs
T

107 lines
3.2 KiB
C#

using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Options;
using Minio;
using Minio.DataModel.Args;
using Minio.Exceptions;
public sealed class DischargeSummaryService : IDischargeSummaryService
{
private readonly AppDbContext _db;
private readonly MinioOptions _minioOpts;
public DischargeSummaryService(AppDbContext db, IOptions<MinioOptions> minioOpts)
{
_db = db;
_minioOpts = minioOpts.Value;
}
public async Task<DischargeSummaryInfo> GetInfoAsync(Guid encounterId, CancellationToken ct = default)
{
var encounter = await _db.Encounters
.AsNoTracking()
.FirstOrDefaultAsync(e => e.Id == encounterId, ct);
if (encounter is null)
throw new NotFoundException("Encounter not found.");
if (encounter.Status != EncounterStatus.Discharged)
{
return new DischargeSummaryInfo(
"NotDischarged",
encounter.DischargedAt,
null,
null);
}
var exists = await ObjectExistsAsync(encounterId, ct);
if (!exists)
{
return new DischargeSummaryInfo(
"Pending",
encounter.DischargedAt,
null,
null);
}
return new DischargeSummaryInfo(
"Ready",
encounter.DischargedAt,
"text/plain",
"discharge-summary.pdf");
}
public async Task<DischargeSummaryContent> GetContentAsync(Guid encounterId, CancellationToken ct = default)
{
var info = await GetInfoAsync(encounterId, ct);
if (info.Status == "NotDischarged")
{
throw new ConflictException(
"Discharge summary is only available for discharged encounters.",
"ENCOUNTER_NOT_DISCHARGED");
}
if (info.Status == "Pending")
{
throw new NotFoundException(
"Discharge summary is still being generated.",
"DISCHARGE_SUMMARY_PENDING");
}
var client = MinioClientFactory.Build(_minioOpts);
var bucket = _minioOpts.BucketName;
var objectKey = ObjectKey(encounterId);
var ms = new MemoryStream();
await client.GetObjectAsync(new GetObjectArgs()
.WithBucket(bucket)
.WithObject(objectKey)
.WithCallbackStream(stream => stream.CopyTo(ms)), ct);
ms.Position = 0;
return new DischargeSummaryContent(ms, info.ContentType!, info.FileName!);
}
private async Task<bool> ObjectExistsAsync(Guid encounterId, CancellationToken ct)
{
var client = MinioClientFactory.Build(_minioOpts);
var bucket = _minioOpts.BucketName;
var objectKey = ObjectKey(encounterId);
try
{
await client.StatObjectAsync(new StatObjectArgs()
.WithBucket(bucket)
.WithObject(objectKey), ct);
return true;
}
catch (ObjectNotFoundException)
{
return false;
}
}
private static string ObjectKey(Guid encounterId) =>
$"discharge-summaries/{encounterId}/summary.pdf";
}