1631786ce2
Add push contracts, provider delivery and channel diagnostics. Link email channels to services and document migration and validation. Ref: IT-1074
61 lines
3.0 KiB
C#
61 lines
3.0 KiB
C#
using HrynCo.NotificationService.DAL.Abstract.PushChannels;
|
|
using HrynCo.NotificationService.DAL.EF.Entities;
|
|
using Microsoft.EntityFrameworkCore;
|
|
|
|
namespace HrynCo.NotificationService.DAL.EF.Repositories;
|
|
|
|
internal sealed class PushChannelRepository(NotificationDbContext db, TemplateMutationRunner mutations) : IPushChannelRepository
|
|
{
|
|
public async Task<IReadOnlyList<PushChannel>> GetAllAsync(CancellationToken ct = default) =>
|
|
await ReadModels().OrderBy(c => c.ServiceName).ToListAsync(ct);
|
|
|
|
public Task<PushChannel?> GetByIdAsync(Guid id, CancellationToken ct = default) =>
|
|
ReadModels().SingleOrDefaultAsync(c => c.Id == id, ct);
|
|
|
|
public Task<PushChannel?> GetActiveForServiceAsync(Guid serviceId, CancellationToken ct = default) =>
|
|
ReadModels().SingleOrDefaultAsync(c => c.ServiceId == serviceId && c.IsActive, ct);
|
|
|
|
public Task<string?> GetCredentialsAsync(Guid id, CancellationToken ct = default) =>
|
|
db.PushChannels.AsNoTracking().Where(c => c.Id == id).Select(c => c.CredentialsJson).SingleOrDefaultAsync(ct);
|
|
|
|
public Task SaveAsync(PushChannel channel, string credentialsJson, bool isNew, CancellationToken ct = default) =>
|
|
mutations.ExecuteAsync(async () =>
|
|
{
|
|
await ValidateServiceAsync(channel, ct);
|
|
var entity = await LoadForSaveAsync(channel.Id, isNew, ct);
|
|
entity.ServiceId = channel.ServiceId;
|
|
entity.FirebaseProjectId = channel.FirebaseProjectId;
|
|
entity.CredentialsJson = credentialsJson;
|
|
entity.IsActive = channel.IsActive;
|
|
entity.Updated = isNew ? null : DateTimeOffset.UtcNow;
|
|
channel.Id = entity.Id;
|
|
}, ct);
|
|
|
|
private async Task ValidateServiceAsync(PushChannel channel, CancellationToken ct)
|
|
{
|
|
if (!await db.Services.AnyAsync(s => s.Id == channel.ServiceId, ct))
|
|
throw new PushChannelWriteException("Select an existing service.", false);
|
|
if (await db.PushChannels.AnyAsync(c => c.ServiceId == channel.ServiceId && c.Id != channel.Id, ct))
|
|
throw new PushChannelWriteException("This service already has a push channel. Edit that channel instead.");
|
|
}
|
|
|
|
private async Task<PushChannelEntity> LoadForSaveAsync(Guid id, bool isNew, CancellationToken ct)
|
|
{
|
|
if (!isNew)
|
|
return await db.PushChannels.SingleOrDefaultAsync(c => c.Id == id, ct)
|
|
?? throw new PushChannelWriteException("The push channel no longer exists. Reload the list.");
|
|
var entity = new PushChannelEntity
|
|
{
|
|
Id = id, FirebaseProjectId = string.Empty, CredentialsJson = "{}", Created = DateTimeOffset.UtcNow
|
|
};
|
|
db.PushChannels.Add(entity);
|
|
return entity;
|
|
}
|
|
|
|
private IQueryable<PushChannel> ReadModels() => db.PushChannels.AsNoTracking().Select(c => new PushChannel
|
|
{
|
|
Id = c.Id, ServiceId = c.ServiceId, ServiceName = c.Service.Name,
|
|
FirebaseProjectId = c.FirebaseProjectId, IsActive = c.IsActive, Created = c.Created, Updated = c.Updated
|
|
});
|
|
}
|