107 lines
3.2 KiB
C#
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";
|
|
}
|