feature: Ward Gateway Service (Local-First Clinical Path)

This commit is contained in:
voltsrage
2026-06-23 16:45:38 +08:00
parent d8e142fffe
commit 1bf8359097
100 changed files with 5474 additions and 4 deletions
@@ -0,0 +1,81 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
[ApiController]
[Authorize]
public class AlertsController : ControllerBase
{
private readonly ILocalAlertService _alerts;
public AlertsController(ILocalAlertService alerts) => _alerts = alerts;
[HttpGet("api/v1/encounters/{encounterId:guid}/alerts")]
public async Task<IActionResult> ListByEncounter(
Guid encounterId,
[FromQuery] string? status,
[FromQuery] int page = 1,
[FromQuery] int pageSize = 20)
{
if (!string.IsNullOrEmpty(status) && !TryParseStatus(status, out _))
return BadRequest(ApiResponse<object>.Fail(400, "Invalid status filter.", "INVALID_STATUS"));
var result = await _alerts.ListAsync(encounterId, status, page, pageSize);
return Ok(ApiResponse<object>.Ok(new
{
items = result.Items,
page = result.Page,
pageSize = result.PageSize,
totalCount = result.TotalCount,
totalPages = result.TotalPages
}));
}
[HttpGet("api/v1/alerts")]
public async Task<IActionResult> ListGlobal(
[FromQuery] string? status,
[FromQuery] int page = 1,
[FromQuery] int pageSize = 20)
{
if (!string.IsNullOrEmpty(status) && !TryParseStatus(status, out _))
return BadRequest(ApiResponse<object>.Fail(400, "Invalid status filter.", "INVALID_STATUS"));
var result = await _alerts.ListAsync(null, status, page, pageSize);
return Ok(ApiResponse<object>.Ok(new
{
items = result.Items,
page = result.Page,
pageSize = result.PageSize,
totalCount = result.TotalCount,
totalPages = result.TotalPages
}));
}
[HttpPost("api/v1/alerts/{id:guid}/acknowledge")]
public async Task<IActionResult> Acknowledge(Guid id, [FromBody] AcknowledgeAlertRequest req)
{
var clinicianId = User.Identity?.Name ?? "unknown";
var alert = await _alerts.AcknowledgeAsync(id, req, clinicianId);
return Ok(ApiResponse<LocalClinicalAlert>.Ok(alert));
}
[HttpPost("api/v1/alerts/{id:guid}/resolve")]
public async Task<IActionResult> Resolve(Guid id)
{
var alert = await _alerts.ResolveAsync(id);
return Ok(ApiResponse<LocalClinicalAlert>.Ok(alert));
}
private static bool TryParseStatus(string status, out AlertStatus _)
{
try
{
_ = AlertStatusExtensions.FromDbString(status);
return true;
}
catch (ArgumentOutOfRangeException)
{
_ = default;
return false;
}
}
}