From 7cb691db147dc0be99accd8b09baa7eea8c984a2 Mon Sep 17 00:00:00 2001 From: Anatolii Grynchuk Date: Fri, 1 May 2026 19:28:34 +0300 Subject: [PATCH] feat: add base entity abstractions and domain model to DAL.Abstract MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - IEntity, Entity, Entity base classes in Entities/ - Template, TemplateVariable domain models in Templates/ - Provider, ProviderSettings, SmtpProviderSettings, ProviderUsage, ProviderType in Providers/ - ITemplateRepository, IProviderRepository, IProviderUsageRepository in Repositories/ - ProviderUsage tracks daily counts; monthly derived by summing daily records - IEntity lives in DAL.Abstract (not DAL.EF) — boundary enforced from the start Ref: IT-628 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../Class1.cs | 6 ------ .../Entities/Entity.cs | 17 +++++++++++++++ .../Entities/IEntity.cs | 8 +++++++ .../Providers/Provider.cs | 15 +++++++++++++ .../Providers/ProviderSettings.cs | 21 +++++++++++++++++++ .../Providers/ProviderType.cs | 6 ++++++ .../Providers/ProviderUsage.cs | 14 +++++++++++++ .../Repositories/IProviderRepository.cs | 12 +++++++++++ .../Repositories/IProviderUsageRepository.cs | 10 +++++++++ .../Repositories/ITemplateRepository.cs | 12 +++++++++++ .../Templates/Template.cs | 14 +++++++++++++ .../Templates/TemplateVariable.cs | 7 +++++++ HrynCo.NotificationService.DAL.EF/Class1.cs | 6 ------ HrynCo.NotificationService.Services/Class1.cs | 6 ------ 14 files changed, 136 insertions(+), 18 deletions(-) delete mode 100644 HrynCo.NotificationService.DAL.Abstract/Class1.cs create mode 100644 HrynCo.NotificationService.DAL.Abstract/Entities/Entity.cs create mode 100644 HrynCo.NotificationService.DAL.Abstract/Entities/IEntity.cs create mode 100644 HrynCo.NotificationService.DAL.Abstract/Providers/Provider.cs create mode 100644 HrynCo.NotificationService.DAL.Abstract/Providers/ProviderSettings.cs create mode 100644 HrynCo.NotificationService.DAL.Abstract/Providers/ProviderType.cs create mode 100644 HrynCo.NotificationService.DAL.Abstract/Providers/ProviderUsage.cs create mode 100644 HrynCo.NotificationService.DAL.Abstract/Repositories/IProviderRepository.cs create mode 100644 HrynCo.NotificationService.DAL.Abstract/Repositories/IProviderUsageRepository.cs create mode 100644 HrynCo.NotificationService.DAL.Abstract/Repositories/ITemplateRepository.cs create mode 100644 HrynCo.NotificationService.DAL.Abstract/Templates/Template.cs create mode 100644 HrynCo.NotificationService.DAL.Abstract/Templates/TemplateVariable.cs delete mode 100644 HrynCo.NotificationService.DAL.EF/Class1.cs delete mode 100644 HrynCo.NotificationService.Services/Class1.cs diff --git a/HrynCo.NotificationService.DAL.Abstract/Class1.cs b/HrynCo.NotificationService.DAL.Abstract/Class1.cs deleted file mode 100644 index 3889710..0000000 --- a/HrynCo.NotificationService.DAL.Abstract/Class1.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace HrynCo.NotificationService.DAL.Abstract; - -public class Class1 -{ - -} diff --git a/HrynCo.NotificationService.DAL.Abstract/Entities/Entity.cs b/HrynCo.NotificationService.DAL.Abstract/Entities/Entity.cs new file mode 100644 index 0000000..fcec809 --- /dev/null +++ b/HrynCo.NotificationService.DAL.Abstract/Entities/Entity.cs @@ -0,0 +1,17 @@ +namespace HrynCo.NotificationService.DAL.Abstract.Entities; + +public abstract class Entity : IEntity where TId : struct +{ + public TId Id { get; set; } + public DateTimeOffset Created { get; set; } + public DateTimeOffset? Updated { get; set; } +} + +public abstract class Entity : Entity +{ + protected Entity() + { + Id = Guid.NewGuid(); + Created = DateTimeOffset.UtcNow; + } +} diff --git a/HrynCo.NotificationService.DAL.Abstract/Entities/IEntity.cs b/HrynCo.NotificationService.DAL.Abstract/Entities/IEntity.cs new file mode 100644 index 0000000..a1445ab --- /dev/null +++ b/HrynCo.NotificationService.DAL.Abstract/Entities/IEntity.cs @@ -0,0 +1,8 @@ +namespace HrynCo.NotificationService.DAL.Abstract.Entities; + +public interface IEntity where TId : struct +{ + TId Id { get; set; } + DateTimeOffset Created { get; set; } + DateTimeOffset? Updated { get; set; } +} diff --git a/HrynCo.NotificationService.DAL.Abstract/Providers/Provider.cs b/HrynCo.NotificationService.DAL.Abstract/Providers/Provider.cs new file mode 100644 index 0000000..a6fae1c --- /dev/null +++ b/HrynCo.NotificationService.DAL.Abstract/Providers/Provider.cs @@ -0,0 +1,15 @@ +using HrynCo.NotificationService.DAL.Abstract.Entities; + +namespace HrynCo.NotificationService.DAL.Abstract.Providers; + +public class Provider : Entity +{ + public required string ServiceName { get; set; } + public int Priority { get; set; } + public ProviderType ProviderType { get; set; } + public required ProviderSettings Settings { get; set; } + public int? DailyLimit { get; set; } + public int? MonthlyLimit { get; set; } + public int WarnThresholdPercent { get; set; } = 90; + public bool IsActive { get; set; } = true; +} diff --git a/HrynCo.NotificationService.DAL.Abstract/Providers/ProviderSettings.cs b/HrynCo.NotificationService.DAL.Abstract/Providers/ProviderSettings.cs new file mode 100644 index 0000000..0420950 --- /dev/null +++ b/HrynCo.NotificationService.DAL.Abstract/Providers/ProviderSettings.cs @@ -0,0 +1,21 @@ +namespace HrynCo.NotificationService.DAL.Abstract.Providers; + +public abstract class ProviderSettings +{ + public abstract ProviderType ProviderType { get; } +} + +public class SmtpProviderSettings : ProviderSettings +{ + public override ProviderType ProviderType => ProviderType.Smtp; + + public required string Host { get; set; } + public int Port { get; set; } = 587; + public required string Username { get; set; } + public required string Password { get; set; } + public bool UseSsl { get; set; } = true; + public required string FromEmail { get; set; } + public required string FromName { get; set; } + public required string AppDisplayName { get; set; } + public required string AppBaseUrl { get; set; } +} diff --git a/HrynCo.NotificationService.DAL.Abstract/Providers/ProviderType.cs b/HrynCo.NotificationService.DAL.Abstract/Providers/ProviderType.cs new file mode 100644 index 0000000..fd7ffc8 --- /dev/null +++ b/HrynCo.NotificationService.DAL.Abstract/Providers/ProviderType.cs @@ -0,0 +1,6 @@ +namespace HrynCo.NotificationService.DAL.Abstract.Providers; + +public enum ProviderType +{ + Smtp = 1 +} diff --git a/HrynCo.NotificationService.DAL.Abstract/Providers/ProviderUsage.cs b/HrynCo.NotificationService.DAL.Abstract/Providers/ProviderUsage.cs new file mode 100644 index 0000000..a4dac2a --- /dev/null +++ b/HrynCo.NotificationService.DAL.Abstract/Providers/ProviderUsage.cs @@ -0,0 +1,14 @@ +using HrynCo.NotificationService.DAL.Abstract.Entities; + +namespace HrynCo.NotificationService.DAL.Abstract.Providers; + +/// +/// Tracks email send counts per provider per calendar day. +/// Monthly counts are derived by summing daily records within a month. +/// +public class ProviderUsage : Entity +{ + public Guid ProviderId { get; set; } + public DateOnly Date { get; set; } + public int SentCount { get; set; } +} diff --git a/HrynCo.NotificationService.DAL.Abstract/Repositories/IProviderRepository.cs b/HrynCo.NotificationService.DAL.Abstract/Repositories/IProviderRepository.cs new file mode 100644 index 0000000..49f6bd2 --- /dev/null +++ b/HrynCo.NotificationService.DAL.Abstract/Repositories/IProviderRepository.cs @@ -0,0 +1,12 @@ +using HrynCo.NotificationService.DAL.Abstract.Providers; + +namespace HrynCo.NotificationService.DAL.Abstract.Repositories; + +public interface IProviderRepository +{ + Task> GetByServiceAsync(string serviceName, CancellationToken ct = default); + Task GetByIdAsync(Guid id, CancellationToken ct = default); + Task AddAsync(Provider provider, CancellationToken ct = default); + Task UpdateAsync(Provider provider, CancellationToken ct = default); + Task DeleteAsync(Provider provider, CancellationToken ct = default); +} diff --git a/HrynCo.NotificationService.DAL.Abstract/Repositories/IProviderUsageRepository.cs b/HrynCo.NotificationService.DAL.Abstract/Repositories/IProviderUsageRepository.cs new file mode 100644 index 0000000..4fb6da7 --- /dev/null +++ b/HrynCo.NotificationService.DAL.Abstract/Repositories/IProviderUsageRepository.cs @@ -0,0 +1,10 @@ +using HrynCo.NotificationService.DAL.Abstract.Providers; + +namespace HrynCo.NotificationService.DAL.Abstract.Repositories; + +public interface IProviderUsageRepository +{ + Task GetDailyCountAsync(Guid providerId, DateOnly date, CancellationToken ct = default); + Task GetMonthlyCountAsync(Guid providerId, int year, int month, CancellationToken ct = default); + Task IncrementAsync(Guid providerId, DateOnly date, CancellationToken ct = default); +} diff --git a/HrynCo.NotificationService.DAL.Abstract/Repositories/ITemplateRepository.cs b/HrynCo.NotificationService.DAL.Abstract/Repositories/ITemplateRepository.cs new file mode 100644 index 0000000..0838809 --- /dev/null +++ b/HrynCo.NotificationService.DAL.Abstract/Repositories/ITemplateRepository.cs @@ -0,0 +1,12 @@ +using HrynCo.NotificationService.DAL.Abstract.Templates; + +namespace HrynCo.NotificationService.DAL.Abstract.Repositories; + +public interface ITemplateRepository +{ + Task> GetByServiceAsync(string serviceName, CancellationToken ct = default); + Task GetAsync(string serviceName, string key, string languageCode, CancellationToken ct = default); + Task AddAsync(Template template, CancellationToken ct = default); + Task UpdateAsync(Template template, CancellationToken ct = default); + Task DeleteAsync(Template template, CancellationToken ct = default); +} diff --git a/HrynCo.NotificationService.DAL.Abstract/Templates/Template.cs b/HrynCo.NotificationService.DAL.Abstract/Templates/Template.cs new file mode 100644 index 0000000..c19b407 --- /dev/null +++ b/HrynCo.NotificationService.DAL.Abstract/Templates/Template.cs @@ -0,0 +1,14 @@ +using HrynCo.NotificationService.DAL.Abstract.Entities; + +namespace HrynCo.NotificationService.DAL.Abstract.Templates; + +public class Template : Entity +{ + public required string ServiceName { get; set; } + public required string Key { get; set; } + public required string LanguageCode { get; set; } + public required string Subject { get; set; } + public required string HtmlBody { get; set; } + public required string TextBody { get; set; } + public IReadOnlyList Variables { get; set; } = []; +} diff --git a/HrynCo.NotificationService.DAL.Abstract/Templates/TemplateVariable.cs b/HrynCo.NotificationService.DAL.Abstract/Templates/TemplateVariable.cs new file mode 100644 index 0000000..74c7413 --- /dev/null +++ b/HrynCo.NotificationService.DAL.Abstract/Templates/TemplateVariable.cs @@ -0,0 +1,7 @@ +namespace HrynCo.NotificationService.DAL.Abstract.Templates; + +public record TemplateVariable +{ + public required string Name { get; init; } + public bool Required { get; init; } +} diff --git a/HrynCo.NotificationService.DAL.EF/Class1.cs b/HrynCo.NotificationService.DAL.EF/Class1.cs deleted file mode 100644 index 8a77a38..0000000 --- a/HrynCo.NotificationService.DAL.EF/Class1.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace HrynCo.NotificationService.DAL.EF; - -public class Class1 -{ - -} diff --git a/HrynCo.NotificationService.Services/Class1.cs b/HrynCo.NotificationService.Services/Class1.cs deleted file mode 100644 index b1f4efd..0000000 --- a/HrynCo.NotificationService.Services/Class1.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace HrynCo.NotificationService.Services; - -public class Class1 -{ - -}