mirror of
https://github.com/Sea-Haven-Industries/shoc-backend.git
synced 2026-09-30 07:13:12 +00:00
Adds GET /api/notifications, a per-user read model derived from live work-order state: Unassigned (grouped, High), No Vendor and Aveta Missing (per work order, Medium) and Vendor Conflict, account-scoped from claims and ordered by section severity with a fixed reason tie-break.
57 lines
2.3 KiB
C#
57 lines
2.3 KiB
C#
using SeaHaven.Services.DTOs;
|
|
|
|
namespace SeaHaven.Services.Helpers
|
|
{
|
|
public static class NotificationFeedOrdering
|
|
{
|
|
/// <summary>
|
|
/// Drops empty sections, orders items by severity then recency, and orders sections by
|
|
/// their highest severity with the fixed reason order breaking ties.
|
|
/// </summary>
|
|
public static IReadOnlyList<NotificationSectionDto> Order(
|
|
IEnumerable<(string Reason, int Count, IReadOnlyList<NotificationItemDto> Items)> sections)
|
|
{
|
|
return sections
|
|
.Where(section => section.Items.Count > 0)
|
|
.Select(section =>
|
|
{
|
|
var items = section.Items
|
|
.OrderByDescending(item => NotificationSeverities.Rank(item.Severity))
|
|
.ThenByDescending(item => item.TriggeredAt)
|
|
.ThenBy(item => item.Id, StringComparer.Ordinal)
|
|
.ToList();
|
|
return new NotificationSectionDto
|
|
{
|
|
Reason = section.Reason,
|
|
Label = NotificationReasons.Labels[section.Reason],
|
|
Severity = items[0].Severity,
|
|
Count = section.Count,
|
|
Items = items
|
|
};
|
|
})
|
|
.OrderByDescending(section => NotificationSeverities.Rank(section.Severity))
|
|
.ThenBy(section => ReasonIndex(section.Reason))
|
|
.ToList();
|
|
}
|
|
|
|
private static int ReasonIndex(string reason)
|
|
{
|
|
for (var index = 0; index < NotificationReasons.Order.Count; index++)
|
|
{
|
|
if (NotificationReasons.Order[index] == reason)
|
|
return index;
|
|
}
|
|
return NotificationReasons.Order.Count;
|
|
}
|
|
}
|
|
|
|
public static class NotificationBusinessTime
|
|
{
|
|
/// <summary>Business-calendar date of <paramref name="utcNow"/> in the dashboard's time zone.</summary>
|
|
public static DateOnly Today(DateTime utcNow)
|
|
{
|
|
var timezone = TimeZoneInfo.FindSystemTimeZoneById(DashboardBusinessTime.TimeZoneId);
|
|
return DateOnly.FromDateTime(TimeZoneInfo.ConvertTimeFromUtc(utcNow, timezone));
|
|
}
|
|
}
|
|
}
|