55 lines
1.7 KiB
C#
55 lines
1.7 KiB
C#
using Microsoft.EntityFrameworkCore;
|
|
using StackExchange.Redis;
|
|
|
|
public class QsofaService : IQsofaService
|
|
{
|
|
private readonly AppDbContext _db;
|
|
private readonly IConnectionMultiplexer _redis;
|
|
|
|
public QsofaService(AppDbContext db, IConnectionMultiplexer redis)
|
|
{
|
|
_db = db;
|
|
_redis = redis;
|
|
}
|
|
|
|
public async Task<QsofaCurrentResponse> GetCurrentAsync(Guid encounterId)
|
|
{
|
|
await EnsureEncounterExistsAsync(encounterId);
|
|
|
|
var values = await ReadCriterionValuesAsync(encounterId);
|
|
return BuildResponse(values);
|
|
}
|
|
|
|
public async Task<int> GetActiveCriteriaCountAsync(Guid encounterId)
|
|
{
|
|
var values = await ReadCriterionValuesAsync(encounterId);
|
|
return QsofaCalculator.CountActiveCriteria(values);
|
|
}
|
|
|
|
private async Task EnsureEncounterExistsAsync(Guid encounterId)
|
|
{
|
|
var exists = await _db.Encounters.AnyAsync(e => e.Id == encounterId);
|
|
if (!exists)
|
|
throw new NotFoundException("Encounter not found.", "ENCOUNTER_NOT_FOUND");
|
|
}
|
|
|
|
private async Task<RedisValue[]> ReadCriterionValuesAsync(Guid encounterId)
|
|
{
|
|
var cache = _redis.GetDatabase();
|
|
return await cache.StringGetAsync(QsofaCalculator.AllCriterionKeys(encounterId));
|
|
}
|
|
|
|
private static QsofaCurrentResponse BuildResponse(RedisValue[] values)
|
|
{
|
|
return new QsofaCurrentResponse(
|
|
QsofaCalculator.CountActiveCriteria(values),
|
|
new QsofaCriteriaState(
|
|
ParseOptionalDecimal(values[0]),
|
|
ParseOptionalDecimal(values[1]),
|
|
ParseOptionalDecimal(values[2])));
|
|
}
|
|
|
|
private static decimal? ParseOptionalDecimal(RedisValue value) =>
|
|
value.HasValue ? decimal.Parse(value.ToString()) : null;
|
|
}
|