mirror of
https://github.com/Sea-Haven-Industries/shoc-backend.git
synced 2026-09-30 16:33:12 +00:00
Reactive/Emergency work orders with a SEV 1-5 level are timed from their
creation against the SEV Respond deadline (2/4/8/24/72 hours, one backend
table). From 50% they are at risk: a dismissable High row in the "SLA at
Risk" section and an entry in the feed's slaAtRisk set with the server
clock (start, deadline, percent) for the banner and toast. From 100% they
are a Critical acknowledge row that only acknowledging removes.
POST /api/notifications/sla/{id}/acknowledge records who and when as a
work-order audit entry ("SLA breach acknowledged by <name>"), scoped to the
caller's feed audience: 404 outside it, 409 before the deadline, 204 when
recorded or already recorded. A later severity change is a new breach.
77 lines
2.8 KiB
C#
77 lines
2.8 KiB
C#
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using SeaHaven.Services.Exceptions;
|
|
using SeaHaven.Services.Interfaces;
|
|
|
|
namespace Api.SeaHavenIndustries.Controllers
|
|
{
|
|
[Authorize]
|
|
[ApiController]
|
|
[Route("api/notifications")]
|
|
public class NotificationsController : ControllerBase
|
|
{
|
|
private readonly INotificationFeedService _feedService;
|
|
private readonly ISlaBreachAcknowledgementService _slaAcknowledgement;
|
|
|
|
public NotificationsController(
|
|
INotificationFeedService feedService,
|
|
ISlaBreachAcknowledgementService slaAcknowledgement)
|
|
{
|
|
_feedService = feedService;
|
|
_slaAcknowledgement = slaAcknowledgement;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Acknowledges the missed response deadline of one work order in the caller's Notification Center.
|
|
/// 204 when recorded or already recorded; 404 when the caller's feed does not cover the work order;
|
|
/// 409 when its deadline has not been missed.
|
|
/// </summary>
|
|
[HttpPost("sla/{workOrderId:int}/acknowledge")]
|
|
public async Task<IActionResult> AcknowledgeSlaBreach(int workOrderId, CancellationToken cancellationToken)
|
|
{
|
|
try
|
|
{
|
|
var outcome = await _slaAcknowledgement.AcknowledgeAsync(User, workOrderId, cancellationToken);
|
|
return outcome switch
|
|
{
|
|
SlaBreachAcknowledgementOutcome.NotFound => NotFound(new
|
|
{
|
|
code = "NotFound",
|
|
message = "Work order not found."
|
|
}),
|
|
SlaBreachAcknowledgementOutcome.NotBreached => Conflict(new
|
|
{
|
|
code = "NotBreached",
|
|
message = "This work order has not missed its response deadline."
|
|
}),
|
|
_ => NoContent()
|
|
};
|
|
}
|
|
catch (WorkOrderBoardValidationException ex) when (ex.Code == "Forbidden")
|
|
{
|
|
return StatusCode(StatusCodes.Status403Forbidden, new
|
|
{
|
|
code = ex.Code,
|
|
message = ex.Message
|
|
});
|
|
}
|
|
}
|
|
|
|
[HttpGet]
|
|
public async Task<IActionResult> GetFeed(CancellationToken cancellationToken)
|
|
{
|
|
try
|
|
{
|
|
return Ok(await _feedService.GetFeedAsync(User, cancellationToken));
|
|
}
|
|
catch (WorkOrderBoardValidationException ex) when (ex.Code == "Forbidden")
|
|
{
|
|
return StatusCode(StatusCodes.Status403Forbidden, new
|
|
{
|
|
code = ex.Code,
|
|
message = ex.Message
|
|
});
|
|
}
|
|
}
|
|
}
|
|
}
|