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

80 lines
3.1 KiB
C#

using Microsoft.EntityFrameworkCore;
public class GatewayRegistryService : IGatewayRegistryService
{
private readonly AppDbContext _db;
public GatewayRegistryService(AppDbContext db) => _db = db;
public async Task<WardGateway> RegisterAsync(Guid siteId, RegisterGatewayRequest req)
{
var siteExists = await _db.ClinicalSites.AnyAsync(s => s.Id == siteId);
if (!siteExists)
throw new NotFoundException("Clinical site not found.", "SITE_NOT_FOUND");
var duplicate = await _db.WardGateways.AnyAsync(g =>
g.SiteId == siteId && g.GatewayCode == req.GatewayCode);
if (duplicate)
throw new ConflictException(
$"Gateway code '{req.GatewayCode}' already exists for this site.",
"GATEWAY_CODE_CONFLICT");
var gateway = new WardGateway(siteId, req.GatewayCode, req.Department);
_db.WardGateways.Add(gateway);
await _db.SaveChangesAsync();
return gateway;
}
public async Task<WardGateway> GetByIdAsync(Guid id)
{
var gateway = await _db.WardGateways
.AsNoTracking()
.Include(g => g.Site)
.FirstOrDefaultAsync(g => g.Id == id);
if (gateway is null)
throw new NotFoundException("Ward gateway not found.", "GATEWAY_NOT_FOUND");
return gateway;
}
public async Task<List<WardGateway>> ListBySiteAsync(Guid siteId, string? department)
{
var siteExists = await _db.ClinicalSites.AnyAsync(s => s.Id == siteId);
if (!siteExists)
throw new NotFoundException("Clinical site not found.", "SITE_NOT_FOUND");
var query = _db.WardGateways.AsNoTracking().Where(g => g.SiteId == siteId);
if (!string.IsNullOrWhiteSpace(department))
query = query.Where(g => g.Department == department);
return await query.OrderBy(g => g.GatewayCode).ToListAsync();
}
public async Task<WardGateway> RecordHeartbeatAsync(
Guid gatewayId, GatewayHeartbeatRequest req, string? authenticatedGatewayId)
{
if (authenticatedGatewayId is not null
&& Guid.TryParse(authenticatedGatewayId, out var authId)
&& authId != gatewayId)
throw new ValidationException(
"Gateway id in URL does not match X-Gateway-Id header.",
"GATEWAY_ID_MISMATCH");
var gateway = await _db.WardGateways.FindAsync(gatewayId);
if (gateway is null)
throw new NotFoundException("Ward gateway not found.", "GATEWAY_NOT_FOUND");
var status = GatewayStatusExtensions.FromDbString(req.Status.ToUpperInvariant());
gateway.RecordHeartbeat(status, req.BufferDepth, req.ReportedAtUtc);
await _db.SaveChangesAsync();
return gateway;
}
public async Task MarkOfflineAsync(Guid gatewayId)
{
var gateway = await _db.WardGateways.FindAsync(gatewayId);
if (gateway is null)
throw new NotFoundException("Ward gateway not found.", "GATEWAY_NOT_FOUND");
gateway.MarkOffline();
await _db.SaveChangesAsync();
}
}