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>
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
|
||||
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>());
|
||||
}
|
||||
Reference in New Issue
Block a user