Files
git.stella-ops.org/src/Notify/StellaOps.Notify.WebService/Storage/Compat/QuietHoursCompat.cs
master 9eec100204 refactor(notify): merge Notifier WebService into Notify WebService
- Delete dead Notify Worker (NoOp handler)
- Move 51 source files (endpoints, contracts, services, compat stores)
- Transform namespaces from Notifier.WebService to Notify.WebService
- Update DI registrations, WebSocket support, v2 endpoint mapping
- Comment out notifier-web in compose, update gateway routes
- Update architecture docs, port registry, rollout matrix
- Notifier Worker stays as separate delivery engine container

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 13:17:13 +03:00

92 lines
2.8 KiB
C#

using StellaOps.Notify.Models;
using System.Collections.Concurrent;
using System.Linq;
namespace StellaOps.Notify.WebService.Storage.Compat;
public interface INotifyQuietHoursRepository
{
Task<IReadOnlyList<NotifyQuietHoursSchedule>> ListAsync(
string tenantId,
string? channelId,
bool? enabledOnly,
CancellationToken cancellationToken = default);
Task<NotifyQuietHoursSchedule?> GetAsync(
string tenantId,
string scheduleId,
CancellationToken cancellationToken = default);
Task<NotifyQuietHoursSchedule> UpsertAsync(
NotifyQuietHoursSchedule schedule,
CancellationToken cancellationToken = default);
Task<bool> DeleteAsync(
string tenantId,
string scheduleId,
CancellationToken cancellationToken = default);
}
public sealed class InMemoryQuietHoursRepository : INotifyQuietHoursRepository
{
private readonly ConcurrentDictionary<string, ConcurrentDictionary<string, NotifyQuietHoursSchedule>> _store = new();
public Task<IReadOnlyList<NotifyQuietHoursSchedule>> ListAsync(
string tenantId,
string? channelId,
bool? enabledOnly,
CancellationToken cancellationToken = default)
{
var items = ForTenant(tenantId).Values.AsEnumerable();
if (!string.IsNullOrWhiteSpace(channelId))
{
items = items.Where(s =>
string.Equals(s.ChannelId, channelId, StringComparison.OrdinalIgnoreCase));
}
if (enabledOnly is true)
{
items = items.Where(s => s.Enabled);
}
var result = items
.OrderBy(s => s.Name, StringComparer.OrdinalIgnoreCase)
.ToList();
return Task.FromResult<IReadOnlyList<NotifyQuietHoursSchedule>>(result);
}
public Task<NotifyQuietHoursSchedule?> GetAsync(
string tenantId,
string scheduleId,
CancellationToken cancellationToken = default)
{
var items = ForTenant(tenantId);
items.TryGetValue(scheduleId, out var schedule);
return Task.FromResult(schedule);
}
public Task<NotifyQuietHoursSchedule> UpsertAsync(
NotifyQuietHoursSchedule schedule,
CancellationToken cancellationToken = default)
{
var items = ForTenant(schedule.TenantId);
items[schedule.ScheduleId] = schedule;
return Task.FromResult(schedule);
}
public Task<bool> DeleteAsync(
string tenantId,
string scheduleId,
CancellationToken cancellationToken = default)
{
var items = ForTenant(tenantId);
return Task.FromResult(items.TryRemove(scheduleId, out _));
}
private ConcurrentDictionary<string, NotifyQuietHoursSchedule> ForTenant(string tenantId) =>
_store.GetOrAdd(tenantId, _ => new ConcurrentDictionary<string, NotifyQuietHoursSchedule>());
}