namespace SeaHaven.DataServices.Models;
///
/// Server-derived feed scope. null is org-wide;
/// null means every dispatcher's work orders.
///
public sealed record NotificationFeedScope(int? AccountId, string? DispatcherId);
public sealed class UnassignedWorkOrdersSummary
{
public int Count { get; init; }
public DateTime? LatestCreatedAt { get; init; }
}
public sealed class NotificationWorkOrderCandidate
{
public int Id { get; init; }
public string? Number { get; init; }
public DateTime ScheduledDate { get; init; }
}
/// A bounded slice of candidates plus the unbounded total they were taken from.
public sealed class NotificationCandidatePage
{
public int Total { get; init; }
public IReadOnlyList Items { get; init; } = Array.Empty();
}
///
/// Server-derived scope for items addressed to one person: is the signed-in
/// user from claims and null is org-wide.
///
public sealed record NotificationPersonalScope(int? AccountId, string UserId);
/// An open work order assigned to the user, with when and by whom it was last assigned.
public sealed class NotificationAssignmentCandidate
{
public int WorkOrderId { get; init; }
public string? Number { get; init; }
public DateTime AssignedAt { get; init; }
public string? AssignedBy { get; init; }
}
public sealed class NotificationCommentCandidate
{
public int CommentId { get; init; }
public int WorkOrderId { get; init; }
public string? WorkOrderNumber { get; init; }
public string? AuthorFirstName { get; init; }
public string? AuthorLastName { get; init; }
/// Free-text author for comments with no user (email sync, vendor portal).
public string? Commenter { get; init; }
public string? Text { get; init; }
public DateTime CreatedAt { get; init; }
}
public sealed class NotificationUpliftDecisionCandidate
{
public int UpliftId { get; init; }
public int WorkOrderId { get; init; }
public string? WorkOrderNumber { get; init; }
public string Status { get; init; } = "";
public decimal Amount { get; init; }
public string? DecisionNote { get; init; }
public DateTime DecidedAt { get; init; }
}
///
/// Per SEV level, the latest work-order creation time that has reached a response-window threshold.
/// The business service computes them; the query only compares creation times.
///
public sealed record NotificationSlaCutoffs(DateTime Sev1, DateTime Sev2, DateTime Sev3, DateTime Sev4, DateTime Sev5);
///
/// The work-order audit entry that records an SLA breach acknowledgement: who (UserId), when (CreatedAt)
/// and the SEV level whose deadline was missed (NewValue). It is also what keeps the breach out of the feed.
///
public static class SlaBreachAcknowledgementAudit
{
public const string FieldName = "SlaBreachAcknowledged";
}
/// An open Reactive/Emergency work order with a SEV 1–5 level and a creation time.
public sealed class NotificationSlaCandidate
{
public int Id { get; init; }
public string? Number { get; init; }
public string Severity { get; init; } = "";
public DateTime CreatedAt { get; init; }
/// A breach of the work order's current severity has already been acknowledged.
public bool BreachAcknowledged { get; init; }
}
public sealed class NotificationSlaCandidates
{
/// Every work order past half its window but not past the whole window.
public IReadOnlyList AtRisk { get; init; } = Array.Empty();
/// Unacknowledged breaches: the newest slice, plus the unbounded total.
public IReadOnlyList Breached { get; init; } = Array.Empty();
public int BreachedTotal { get; init; }
}