diff --git a/Directory.Build.props b/Directory.Build.props new file mode 100644 index 0000000..e42216a --- /dev/null +++ b/Directory.Build.props @@ -0,0 +1,5 @@ + + + true + + diff --git a/Directory.Packages.props b/Directory.Packages.props new file mode 100644 index 0000000..4137eeb --- /dev/null +++ b/Directory.Packages.props @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/HrynCo.NotificationService.Api.IntegrationTests/HrynCo.NotificationService.Api.IntegrationTests.csproj b/HrynCo.NotificationService.Api.IntegrationTests/HrynCo.NotificationService.Api.IntegrationTests.csproj index 51b03d1..35be975 100644 --- a/HrynCo.NotificationService.Api.IntegrationTests/HrynCo.NotificationService.Api.IntegrationTests.csproj +++ b/HrynCo.NotificationService.Api.IntegrationTests/HrynCo.NotificationService.Api.IntegrationTests.csproj @@ -1,4 +1,4 @@ - + net10.0 @@ -8,10 +8,10 @@ - - - - + + + + diff --git a/HrynCo.NotificationService.Api/HrynCo.NotificationService.Api.csproj b/HrynCo.NotificationService.Api/HrynCo.NotificationService.Api.csproj index af153da..ef39b79 100644 --- a/HrynCo.NotificationService.Api/HrynCo.NotificationService.Api.csproj +++ b/HrynCo.NotificationService.Api/HrynCo.NotificationService.Api.csproj @@ -7,7 +7,7 @@ - + diff --git a/HrynCo.NotificationService.DAL.EF/Configurations/ProviderEntityConfiguration.cs b/HrynCo.NotificationService.DAL.EF/Configurations/ProviderEntityConfiguration.cs new file mode 100644 index 0000000..4d584c9 --- /dev/null +++ b/HrynCo.NotificationService.DAL.EF/Configurations/ProviderEntityConfiguration.cs @@ -0,0 +1,39 @@ +using HrynCo.NotificationService.DAL.EF.Entities; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; + +namespace HrynCo.NotificationService.DAL.EF.Configurations; + +internal class ProviderEntityConfiguration : IEntityTypeConfiguration +{ + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable("providers"); + + builder.HasKey(x => x.Id); + builder.Property(x => x.Id).HasColumnName("id"); + + builder.Property(x => x.ServiceName) + .HasColumnName("service_name") + .IsRequired() + .HasMaxLength(100); + + builder.HasIndex(x => new { x.ServiceName, x.Priority }); + + builder.Property(x => x.Priority).HasColumnName("priority"); + + builder.Property(x => x.ProviderType).HasColumnName("provider_type"); + + builder.Property(x => x.SettingsJson) + .HasColumnName("settings") + .HasColumnType("jsonb") + .IsRequired(); + + builder.Property(x => x.DailyLimit).HasColumnName("daily_limit"); + builder.Property(x => x.MonthlyLimit).HasColumnName("monthly_limit"); + builder.Property(x => x.WarnThresholdPercent).HasColumnName("warn_threshold_percent"); + builder.Property(x => x.IsActive).HasColumnName("is_active"); + builder.Property(x => x.Created).HasColumnName("created"); + builder.Property(x => x.Updated).HasColumnName("updated"); + } +} diff --git a/HrynCo.NotificationService.DAL.EF/Configurations/ProviderUsageEntityConfiguration.cs b/HrynCo.NotificationService.DAL.EF/Configurations/ProviderUsageEntityConfiguration.cs new file mode 100644 index 0000000..b2ac7ff --- /dev/null +++ b/HrynCo.NotificationService.DAL.EF/Configurations/ProviderUsageEntityConfiguration.cs @@ -0,0 +1,25 @@ +using HrynCo.NotificationService.DAL.EF.Entities; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; + +namespace HrynCo.NotificationService.DAL.EF.Configurations; + +internal class ProviderUsageEntityConfiguration : IEntityTypeConfiguration +{ + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable("provider_usage"); + + builder.HasKey(x => x.Id); + builder.Property(x => x.Id).HasColumnName("id"); + + builder.Property(x => x.ProviderId).HasColumnName("provider_id"); + + builder.HasIndex(x => new { x.ProviderId, x.Date }).IsUnique(); + + builder.Property(x => x.Date).HasColumnName("date"); + builder.Property(x => x.SentCount).HasColumnName("sent_count"); + builder.Property(x => x.Created).HasColumnName("created"); + builder.Property(x => x.Updated).HasColumnName("updated"); + } +} diff --git a/HrynCo.NotificationService.DAL.EF/Configurations/TemplateEntityConfiguration.cs b/HrynCo.NotificationService.DAL.EF/Configurations/TemplateEntityConfiguration.cs new file mode 100644 index 0000000..ed49681 --- /dev/null +++ b/HrynCo.NotificationService.DAL.EF/Configurations/TemplateEntityConfiguration.cs @@ -0,0 +1,56 @@ +using HrynCo.NotificationService.DAL.EF.Entities; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; + +namespace HrynCo.NotificationService.DAL.EF.Configurations; + +internal class TemplateEntityConfiguration : IEntityTypeConfiguration +{ + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable("templates"); + + builder.HasKey(x => x.Id); + builder.Property(x => x.Id).HasColumnName("id"); + + builder.Property(x => x.ServiceName) + .HasColumnName("service_name") + .IsRequired() + .HasMaxLength(100); + + builder.Property(x => x.Key) + .HasColumnName("key") + .IsRequired() + .HasMaxLength(100); + + builder.Property(x => x.LanguageCode) + .HasColumnName("language_code") + .IsRequired() + .HasMaxLength(10); + + builder.HasIndex(x => new { x.ServiceName, x.Key, x.LanguageCode }) + .IsUnique(); + + builder.Property(x => x.Subject) + .HasColumnName("subject") + .IsRequired(); + + builder.Property(x => x.HtmlBody) + .HasColumnName("html_body") + .IsRequired(); + + builder.Property(x => x.TextBody) + .HasColumnName("text_body") + .IsRequired(); + + builder.Property(x => x.Created).HasColumnName("created"); + builder.Property(x => x.Updated).HasColumnName("updated"); + + builder.OwnsMany(x => x.Variables, v => + { + v.ToJson("variables"); + v.Property(x => x.Name).HasJsonPropertyName("name"); + v.Property(x => x.Required).HasJsonPropertyName("required"); + }); + } +} diff --git a/HrynCo.NotificationService.DAL.EF/Entities/ProviderEntity.cs b/HrynCo.NotificationService.DAL.EF/Entities/ProviderEntity.cs new file mode 100644 index 0000000..1101ef1 --- /dev/null +++ b/HrynCo.NotificationService.DAL.EF/Entities/ProviderEntity.cs @@ -0,0 +1,24 @@ +using HrynCo.NotificationService.DAL.Abstract.Providers; + +namespace HrynCo.NotificationService.DAL.EF.Entities; + +internal class ProviderEntity +{ + public Guid Id { get; set; } + public required string ServiceName { get; set; } + public int Priority { get; set; } + public ProviderType ProviderType { get; set; } + + /// + /// Provider-specific credentials and settings stored as JSONB. + /// Deserialized based on in the repository. + /// + public required string SettingsJson { get; set; } + + public int? DailyLimit { get; set; } + public int? MonthlyLimit { get; set; } + public int WarnThresholdPercent { get; set; } + public bool IsActive { get; set; } + public DateTimeOffset Created { get; set; } + public DateTimeOffset? Updated { get; set; } +} diff --git a/HrynCo.NotificationService.DAL.EF/Entities/ProviderUsageEntity.cs b/HrynCo.NotificationService.DAL.EF/Entities/ProviderUsageEntity.cs new file mode 100644 index 0000000..dbce792 --- /dev/null +++ b/HrynCo.NotificationService.DAL.EF/Entities/ProviderUsageEntity.cs @@ -0,0 +1,11 @@ +namespace HrynCo.NotificationService.DAL.EF.Entities; + +internal class ProviderUsageEntity +{ + public Guid Id { get; set; } + public Guid ProviderId { get; set; } + public DateOnly Date { get; set; } + public int SentCount { get; set; } + public DateTimeOffset Created { get; set; } + public DateTimeOffset? Updated { get; set; } +} diff --git a/HrynCo.NotificationService.DAL.EF/Entities/TemplateEntity.cs b/HrynCo.NotificationService.DAL.EF/Entities/TemplateEntity.cs new file mode 100644 index 0000000..ffa132e --- /dev/null +++ b/HrynCo.NotificationService.DAL.EF/Entities/TemplateEntity.cs @@ -0,0 +1,21 @@ +namespace HrynCo.NotificationService.DAL.EF.Entities; + +internal class TemplateEntity +{ + public Guid Id { get; set; } + 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 List Variables { get; set; } = []; + public DateTimeOffset Created { get; set; } + public DateTimeOffset? Updated { get; set; } +} + +internal class TemplateVariableData +{ + public required string Name { get; set; } + public bool Required { get; set; } +} diff --git a/HrynCo.NotificationService.DAL.EF/HrynCo.NotificationService.DAL.EF.csproj b/HrynCo.NotificationService.DAL.EF/HrynCo.NotificationService.DAL.EF.csproj index 8011d57..f073f56 100644 --- a/HrynCo.NotificationService.DAL.EF/HrynCo.NotificationService.DAL.EF.csproj +++ b/HrynCo.NotificationService.DAL.EF/HrynCo.NotificationService.DAL.EF.csproj @@ -4,6 +4,16 @@ + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + net10.0 enable diff --git a/HrynCo.NotificationService.DAL.EF/NotificationDbContext.cs b/HrynCo.NotificationService.DAL.EF/NotificationDbContext.cs new file mode 100644 index 0000000..2ff4c34 --- /dev/null +++ b/HrynCo.NotificationService.DAL.EF/NotificationDbContext.cs @@ -0,0 +1,21 @@ +using HrynCo.NotificationService.DAL.EF.Entities; +using Microsoft.EntityFrameworkCore; + +namespace HrynCo.NotificationService.DAL.EF; + +public class NotificationDbContext : DbContext +{ + public NotificationDbContext(DbContextOptions options) + : base(options) + { + } + + internal DbSet Templates => Set(); + internal DbSet Providers => Set(); + internal DbSet ProviderUsage => Set(); + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + modelBuilder.ApplyConfigurationsFromAssembly(typeof(NotificationDbContext).Assembly); + } +} diff --git a/HrynCo.NotificationService.Services.Tests/HrynCo.NotificationService.Services.Tests.csproj b/HrynCo.NotificationService.Services.Tests/HrynCo.NotificationService.Services.Tests.csproj index 90aa85b..69e51f0 100644 --- a/HrynCo.NotificationService.Services.Tests/HrynCo.NotificationService.Services.Tests.csproj +++ b/HrynCo.NotificationService.Services.Tests/HrynCo.NotificationService.Services.Tests.csproj @@ -1,4 +1,4 @@ - + net10.0 @@ -8,10 +8,10 @@ - - - - + + + + diff --git a/HrynCo.NotificationService.Worker/HrynCo.NotificationService.Worker.csproj b/HrynCo.NotificationService.Worker/HrynCo.NotificationService.Worker.csproj index e044c6a..8f82f22 100644 --- a/HrynCo.NotificationService.Worker/HrynCo.NotificationService.Worker.csproj +++ b/HrynCo.NotificationService.Worker/HrynCo.NotificationService.Worker.csproj @@ -8,7 +8,7 @@ - +