using System.Text.Json; using Microsoft.AspNetCore.Mvc; [ApiController] [Route("api/v1/encounters/{encounterId:guid}/sofa")] [Produces("application/json")] public class SofaController : ControllerBase { private readonly ISofaService _sofa; public SofaController(ISofaService sofa) => _sofa = sofa; [HttpGet] [ProducesResponseType(typeof(ApiResponse), StatusCodes.Status200OK)] public async Task Current(Guid encounterId) { var score = await _sofa.GetCurrentAsync(encounterId); if (score is null) return Ok(ApiResponse.Ok(null)); return Ok(ApiResponse.Ok(MapResponse(score))); } [HttpGet("history")] [ProducesResponseType(typeof(ApiResponse), StatusCodes.Status200OK)] public async Task History( Guid encounterId, [FromQuery] int limit = 20, [FromQuery] string? cursor = null) { var page = await _sofa.GetHistoryAsync(encounterId, limit, cursor); return Ok(ApiResponse.Ok(new { items = page.Items.Select(MapResponse), nextCursor = page.NextCursor, hasMore = page.HasMore })); } private static SofaScoreResponse MapResponse(SofaScore score) { SofaStalenessInfo? staleness = null; if (!string.IsNullOrEmpty(score.StalenessFlags)) { var flags = JsonSerializer.Deserialize( score.StalenessFlags, new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); if (flags is not null) { staleness = new SofaStalenessInfo( flags.StaleComponents, flags.MissingComponents, flags.UsedSpO2Fallback); } } return new SofaScoreResponse( score.TotalScore, score.RespiratoryScore, score.CoagulationScore, score.LiverScore, score.CardiovascularScore, score.CnsScore, score.RenalScore, score.IsBaseline, score.DeltaFromBaseline, staleness, score.CalculatedAt); } }