using Deal.Modules.Kanban.Application.Models;
namespace Deal.Api.Events;
///
/// Публикация SSE-тостов статистики тика правил хранения в канал тенанта.
///
public sealed class StorageToastPublisher
{
private const string ToastEventType = "toast";
private const string AutoArchiveToastText = "Автоархив: {0} карточек";
private const string ArchiveClearedToastText = "Архив очищен: {0} (90 дн.)";
private const string TrashClearedToastText = "Корзина очищена: {0} (7 дн.)";
private const string RejectedPurgedToastText = "Отсев очищен: {0} записей (3 дн.)";
private const string ClockIcon = "clock";
private const string TrashIcon = "trash";
private readonly SseBroker _broker;
///
/// Создаёт публикатора тостов тика.
///
/// SSE-брокер каналов тенантов (singleton).
public StorageToastPublisher(SseBroker broker)
{
ArgumentNullException.ThrowIfNull(broker);
_broker = broker;
}
///
/// Публикует тосты статистики тика по ненулевым счётчикам.
///
/// Тенант-получатель тостов (сессия запроса / канал тенанта цикла).
/// Статистика только что выполненного тика.
public void PublishTickToasts(Guid tenantId, StorageTickStatsDto stats)
{
if (stats.Archived > 0)
{
_broker.Publish(tenantId, ToastEventType, new { text = string.Format(AutoArchiveToastText, stats.Archived), icon = ClockIcon });
}
if (stats.PurgedArchive > 0)
{
_broker.Publish(tenantId, ToastEventType, new { text = string.Format(ArchiveClearedToastText, stats.PurgedArchive), icon = TrashIcon });
}
if (stats.PurgedTrash > 0)
{
_broker.Publish(tenantId, ToastEventType, new { text = string.Format(TrashClearedToastText, stats.PurgedTrash), icon = TrashIcon });
}
if (stats.PurgedRejected > 0)
{
_broker.Publish(tenantId, ToastEventType, new { text = string.Format(RejectedPurgedToastText, stats.PurgedRejected), icon = TrashIcon });
}
}
}