diff --git a/LiteCharms.Abstractions/LiteCharms.Abstractions.csproj b/LiteCharms.Abstractions/LiteCharms.Abstractions.csproj
deleted file mode 100644
index 4074ad4..0000000
--- a/LiteCharms.Abstractions/LiteCharms.Abstractions.csproj
+++ /dev/null
@@ -1,40 +0,0 @@
-
-
-
- net10.0
- enable
- enable
- True
- ..\LiteCharms.snk
-
-
-
-
- LiteCharms.Abstractions
- 1.0.20
- Khwezi Mngoma
- Lite Charms (PTY) Ltd
- Shared abstractions for Lite Charms applications.
- https://gitea.khongisa.co.za/litecharms/components
- https://gitea.khongisa.co.za/litecharms/components.git
- git
- LICENSE
- utility;dotnet
- icon.png
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/LiteCharms.Entities/Configuration/OrderConfiguration.cs b/LiteCharms.Entities/Configuration/OrderConfiguration.cs
deleted file mode 100644
index 138e136..0000000
--- a/LiteCharms.Entities/Configuration/OrderConfiguration.cs
+++ /dev/null
@@ -1,32 +0,0 @@
-namespace LiteCharms.Entities.Configuration;
-
-public class OrderConfiguration : IEntityTypeConfiguration
-{
- public void Configure(EntityTypeBuilder builder)
- {
- builder.ToTable(nameof(Order));
-
- builder.HasKey(f => f.Id);
- builder.Property(f => f.CreatedAt).ValueGeneratedOnAdd();
- builder.Property(f => f.UpdatedAt).IsRequired(false).ValueGeneratedOnUpdate();
- builder.Property(f => f.CustomerId).IsRequired();
- builder.Property(f => f.QuoteId).IsRequired(false);
- builder.Property(f => f.RefundId).IsRequired(false);
- builder.Property(f => f.ShoppingCartId).IsRequired();
- builder.Property(f => f.Status).HasConversion().IsRequired();
- builder.Property(f => f.Requirements).HasColumnType("jsonb").IsRequired(false);
- builder.Property(f => f.Notes).HasColumnType("jsonb").IsRequired(false);
- builder.Property(f => f.Terms).HasColumnType("jsonb").IsRequired(false);
- builder.Property(f => f.DepositRequired);
-
- builder.HasOne(f => f.Quote)
- .WithOne(f => f.Order)
- .HasForeignKey(f => f.QuoteId)
- .OnDelete(DeleteBehavior.Restrict);
-
- builder.HasOne(f => f.Customer)
- .WithMany(f => f.Orders)
- .HasForeignKey(f => f.CustomerId)
- .OnDelete(DeleteBehavior.Restrict);
- }
-}
diff --git a/LiteCharms.Entities/Configuration/PackageConfirguration.cs b/LiteCharms.Entities/Configuration/PackageConfirguration.cs
deleted file mode 100644
index 71aa4fc..0000000
--- a/LiteCharms.Entities/Configuration/PackageConfirguration.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-namespace LiteCharms.Entities.Configuration;
-
-public class PackageConfirguration : IEntityTypeConfiguration
-{
- public void Configure(EntityTypeBuilder builder)
- {
- builder.ToTable(nameof(Package));
-
- builder.HasKey(f => f.Id);
- builder.Property(f => f.CreatedAt).IsRequired().ValueGeneratedOnAdd();
- builder.Property(f => f.UpdatedAt).IsRequired(false).ValueGeneratedOnUpdate();
- builder.Property(f => f.Name).IsRequired();
- builder.Property(f => f.Description).IsRequired();
- builder.Property(f => f.Active);
- }
-}
diff --git a/LiteCharms.Entities/Configuration/ProductConfiguration.cs b/LiteCharms.Entities/Configuration/ProductConfiguration.cs
deleted file mode 100644
index 3b5ca6d..0000000
--- a/LiteCharms.Entities/Configuration/ProductConfiguration.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-namespace LiteCharms.Entities.Configuration;
-
-public class ProductConfiguration : IEntityTypeConfiguration
-{
- public void Configure(EntityTypeBuilder builder)
- {
- builder.ToTable(nameof(Product));
-
- builder.HasKey(f => f.Id);
- builder.Property(f => f.Name).IsRequired();
- builder.Property(f => f.Description).IsRequired();
- builder.Property(f => f.Active).HasDefaultValue(true);
- }
-}
diff --git a/LiteCharms.Entities/Configuration/QuoteConfiguration.cs b/LiteCharms.Entities/Configuration/QuoteConfiguration.cs
deleted file mode 100644
index d48a768..0000000
--- a/LiteCharms.Entities/Configuration/QuoteConfiguration.cs
+++ /dev/null
@@ -1,23 +0,0 @@
-namespace LiteCharms.Entities.Configuration;
-
-public class QuoteConfiguration : IEntityTypeConfiguration
-{
- public void Configure(EntityTypeBuilder builder)
- {
- builder.ToTable(nameof(Quote));
-
- builder.HasKey(f => f.Id);
- builder.Property(f => f.CreatedAt).IsRequired().ValueGeneratedOnAdd();
- builder.Property(f => f.UpdatedAt).IsRequired(false).ValueGeneratedOnUpdate();
- builder.Property(f => f.ExpiredAt).IsRequired(false);
- builder.Property(f => f.CustomerId).IsRequired();
- builder.Property(f => f.Status).IsRequired().HasConversion();
- builder.Property(f => f.ShoppingCartId).IsRequired();
- builder.Property(f => f.Reason).IsRequired(false);
-
- builder.HasOne(f => f.Customer)
- .WithMany()
- .HasForeignKey(f => f.CustomerId)
- .OnDelete(DeleteBehavior.Cascade);
- }
-}
diff --git a/LiteCharms.Entities/Configuration/ShoppingCartConfiguration.cs b/LiteCharms.Entities/Configuration/ShoppingCartConfiguration.cs
deleted file mode 100644
index 109fd99..0000000
--- a/LiteCharms.Entities/Configuration/ShoppingCartConfiguration.cs
+++ /dev/null
@@ -1,31 +0,0 @@
-namespace LiteCharms.Entities.Configuration;
-
-public class ShoppingCartConfiguration : IEntityTypeConfiguration
-{
- public void Configure(EntityTypeBuilder builder)
- {
- builder.ToTable(nameof(ShoppingCart));
-
- builder.HasKey(f => f.Id);
- builder.Property(f => f.CreatedAt).IsRequired().ValueGeneratedOnAdd();
- builder.Property(f => f.UpdatedAt).IsRequired(false).ValueGeneratedOnUpdate();
- builder.Property(f => f.CustomerId).IsRequired(false);
- builder.Property(f => f.OrderId).IsRequired(false);
- builder.Property(f => f.QuoteId).IsRequired(false);
-
- builder.HasOne(f => f.Customer)
- .WithMany(c => c.ShoppingCarts)
- .HasForeignKey(f => f.CustomerId)
- .OnDelete(DeleteBehavior.NoAction);
-
- builder.HasOne(f => f.Order)
- .WithOne(o => o.ShoppingCart)
- .HasForeignKey(o => o.ShoppingCartId)
- .OnDelete(DeleteBehavior.NoAction);
-
- builder.HasOne(f => f.Quote)
- .WithOne(o => o.ShoppingCart)
- .HasForeignKey(o => o.ShoppingCartId)
- .OnDelete(DeleteBehavior.NoAction);
- }
-}
diff --git a/LiteCharms.Entities/Configuration/ShoppingCartItemConfiguration.cs b/LiteCharms.Entities/Configuration/ShoppingCartItemConfiguration.cs
deleted file mode 100644
index 948f988..0000000
--- a/LiteCharms.Entities/Configuration/ShoppingCartItemConfiguration.cs
+++ /dev/null
@@ -1,25 +0,0 @@
-namespace LiteCharms.Entities.Configuration;
-
-public class ShoppingCartItemConfiguration : IEntityTypeConfiguration
-{
- public void Configure(EntityTypeBuilder builder)
- {
- builder.ToTable(nameof(ShoppingCartItem));
-
- builder.HasKey(f => f.Id);
- builder.Property(f => f.CreatedAt).IsRequired().ValueGeneratedOnAdd();
- builder.Property(f => f.UpdatedAt).IsRequired(false).ValueGeneratedOnUpdate();
- builder.Property(f => f.Quantity).IsRequired().HasDefaultValue(1);
- builder.Property(f => f.ProductPriceId).IsRequired();
-
- builder.HasOne(f => f.ProductPrice)
- .WithMany()
- .HasForeignKey(f => f.ProductPriceId)
- .OnDelete(DeleteBehavior.NoAction);
-
- builder.HasOne(f => f.ShoppingCart)
- .WithMany(f => f.ShoppingCartItems)
- .HasForeignKey(f => f.ShoppingCartId)
- .OnDelete(DeleteBehavior.NoAction);
- }
-}
diff --git a/LiteCharms.Entities/LiteCharms.Entities.csproj b/LiteCharms.Entities/LiteCharms.Entities.csproj
deleted file mode 100644
index b32a09d..0000000
--- a/LiteCharms.Entities/LiteCharms.Entities.csproj
+++ /dev/null
@@ -1,45 +0,0 @@
-
-
-
- net10.0
- enable
- enable
- True
- ..\LiteCharms.snk
-
-
-
-
- LiteCharms.Entities
- 1.0.20
- Khwezi Mngoma
- Lite Charms (PTY) Ltd
- Shared entities for Lite Charms applications.
- https://gitea.khongisa.co.za/litecharms/components
- https://gitea.khongisa.co.za/litecharms/components.git
- git
- LICENSE
- utility;dotnet
- icon.png
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/LiteCharms.Entities/Order.cs b/LiteCharms.Entities/Order.cs
deleted file mode 100644
index 5f7d5dc..0000000
--- a/LiteCharms.Entities/Order.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-using LiteCharms.Entities.Configuration;
-
-namespace LiteCharms.Entities;
-
-[EntityTypeConfiguration]
-public class Order : Models.Order
-{
- public virtual OrderRefund? Refund { get; set; }
-
- public virtual Customer? Customer { get; set; }
-
- public virtual Quote? Quote { get; set; }
-
- public virtual ShoppingCart? ShoppingCart { get; set; }
-}
diff --git a/LiteCharms.Entities/PackageItem.cs b/LiteCharms.Entities/PackageItem.cs
deleted file mode 100644
index 986fc75..0000000
--- a/LiteCharms.Entities/PackageItem.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-using LiteCharms.Entities.Configuration;
-
-namespace LiteCharms.Entities;
-
-[EntityTypeConfiguration]
-public class PackageItem : Models.PackageItem
-{
- public virtual Package? Package { get; set; }
-}
diff --git a/LiteCharms.Extensions/Email.cs b/LiteCharms.Extensions/Email.cs
deleted file mode 100644
index e081f4e..0000000
--- a/LiteCharms.Extensions/Email.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-using LiteCharms.Models.Configuraton.Email;
-
-namespace LiteCharms.Extensions;
-
-public static class Email
-{
- public static IServiceCollection AddEmailServices(this IServiceCollection services, IConfiguration configuration)
- {
- services.Configure(configuration.GetSection("Email"));
-
- return services;
- }
-}
diff --git a/LiteCharms.Extensions/LiteCharms.Extensions.csproj b/LiteCharms.Extensions/LiteCharms.Extensions.csproj
deleted file mode 100644
index 3f531b7..0000000
--- a/LiteCharms.Extensions/LiteCharms.Extensions.csproj
+++ /dev/null
@@ -1,113 +0,0 @@
-
-
-
- net10.0
- enable
- enable
- True
- ..\LiteCharms.snk
- true
-
-
-
-
- $(NoWarn);MA0004
-
- $(NoWarn);AD0001
- true
- $(NoWarn);IL2080;IL2065;IL2075;IL2087;IL2057;IL2060;IL2070;IL2067;IL2072;IL2026;IL2104
- $(NoWarn);IL2110;IL2111
-
-
-
-
- LiteCharms.Extensions
- 1.0.20
- Khwezi Mngoma
- Lite Charms (PTY) Ltd
- Extension components for Lite Charms applications.
- https://gitea.khongisa.co.za/litecharms/components
- https://gitea.khongisa.co.za/litecharms/components.git
- git
- LICENSE
- utility;dotnet
- icon.png
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- all
- runtime; build; native; contentfiles; analyzers; buildtransitive
-
-
-
- all
- runtime; build; native; contentfiles; analyzers; buildtransitive
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/LiteCharms.Features.Tests/CommonFixture.cs b/LiteCharms.Features.Tests/CommonFixture.cs
new file mode 100644
index 0000000..b237b8f
--- /dev/null
+++ b/LiteCharms.Features.Tests/CommonFixture.cs
@@ -0,0 +1,34 @@
+using LiteCharms.Extensions;
+
+namespace LiteCharms.Features.Tests;
+
+public class CommonFixture : IDisposable
+{
+ public IConfiguration Configuration { get; set; }
+
+ public IServiceProvider Services { get; set; }
+
+ public IMediator Mediator { get; set; }
+
+ public CommonFixture()
+ {
+ Configuration = new ConfigurationBuilder()
+ .SetBasePath(Directory.GetCurrentDirectory())
+ .AddJsonFile("appsettings.json")
+ .AddUserSecrets()
+ .AddEnvironmentVariables()
+ .Build();
+
+ Services = new ServiceCollection()
+ .AddMediator()
+ .AddLogging()
+ .AddEmailServiceBus()
+ .AddShopDatabase(Configuration)
+ .AddEmailServices(Configuration)
+ .BuildServiceProvider();
+
+ Mediator = Services.GetRequiredService();
+ }
+
+ public void Dispose() { }
+}
diff --git a/LiteCharms.Features.Tests/LiteCharms.Features.Tests.csproj b/LiteCharms.Features.Tests/LiteCharms.Features.Tests.csproj
new file mode 100644
index 0000000..7070851
--- /dev/null
+++ b/LiteCharms.Features.Tests/LiteCharms.Features.Tests.csproj
@@ -0,0 +1,50 @@
+
+
+
+ net10.0
+ enable
+ enable
+ false
+ 62fa604a-1340-4edb-9ddd-3305fcf46fca
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ PreserveNewest
+
+
+
+
\ No newline at end of file
diff --git a/LiteCharms.Features.Tests/NotificationsFeatureTests.cs b/LiteCharms.Features.Tests/NotificationsFeatureTests.cs
new file mode 100644
index 0000000..53b8154
--- /dev/null
+++ b/LiteCharms.Features.Tests/NotificationsFeatureTests.cs
@@ -0,0 +1,19 @@
+using LiteCharms.Features.Notifications.Commands;
+
+namespace LiteCharms.Features.Tests;
+
+public class NotificationsFeatureTests(CommonFixture fixture) : IClassFixture
+{
+ [Fact]
+ public async Task CreateNotificationCommand_ShouldSucceed()
+ {
+ var command = CreateNotification.Create(Models.NotificationDirection.Outgoing, "UnitTest", "khwezi@mngoma.co.za",
+ "CreateNotificationCommand_ShouldSucceed Test", "Test Message", Models.NotificationPlatforms.Email, Models.Priorities.Medium,
+ "Khngisa Shop - Test", "shop@litecharms.co.za", Guid.NewGuid().ToString(), Models.CorrelationIdTypes.None,
+ true, false);
+
+ var result = await fixture.Mediator.Send(command);
+
+ Assert.True(result.IsSuccess);
+ }
+}
diff --git a/LiteCharms.Features.Tests/appsettings.json b/LiteCharms.Features.Tests/appsettings.json
new file mode 100644
index 0000000..aec5c2e
--- /dev/null
+++ b/LiteCharms.Features.Tests/appsettings.json
@@ -0,0 +1,22 @@
+{
+ "Email": {
+ "Credentials": {
+ "Username": "shop@litecharms.co.za"
+ },
+ "Port": 465,
+ "Host": "mail.litecharms.co.za",
+ "UseSsl": true
+ },
+ "Monitoring": {
+ "ApiKey": "",
+ "Address": "http://aspire-dashboard-service.aspire.svc.cluster.local:18889",
+ "ServiceName": "LiteCharms.LeadGenerator"
+ },
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information",
+ "Microsoft.AspNetCore": "Warning"
+ }
+ },
+ "AllowedHosts": "*"
+}
diff --git a/LiteCharms.Abstractions/EventBase.cs b/LiteCharms.Features/Abstractions/EventBase.cs
similarity index 65%
rename from LiteCharms.Abstractions/EventBase.cs
rename to LiteCharms.Features/Abstractions/EventBase.cs
index 6c11736..32def99 100644
--- a/LiteCharms.Abstractions/EventBase.cs
+++ b/LiteCharms.Features/Abstractions/EventBase.cs
@@ -1,6 +1,7 @@
-using static LiteCharms.Abstractions.Timezones;
+using LiteCharms.Features.Extensions;
+using static LiteCharms.Features.Extensions.Timezones;
-namespace LiteCharms.Abstractions;
+namespace LiteCharms.Features.Abstractions;
public abstract class EventBase
{
diff --git a/LiteCharms.Abstractions/IEvent.cs b/LiteCharms.Features/Abstractions/IEvent.cs
similarity index 79%
rename from LiteCharms.Abstractions/IEvent.cs
rename to LiteCharms.Features/Abstractions/IEvent.cs
index 08bc091..366ad86 100644
--- a/LiteCharms.Abstractions/IEvent.cs
+++ b/LiteCharms.Features/Abstractions/IEvent.cs
@@ -1,4 +1,4 @@
-namespace LiteCharms.Abstractions;
+namespace LiteCharms.Features.Abstractions;
public interface IEvent : INotification
{
diff --git a/LiteCharms.Features/Email/Commands/Handlers/SendEmailCommandHandler.cs b/LiteCharms.Features/Email/Commands/Handlers/SendEmailCommandHandler.cs
deleted file mode 100644
index 30f86dc..0000000
--- a/LiteCharms.Features/Email/Commands/Handlers/SendEmailCommandHandler.cs
+++ /dev/null
@@ -1,61 +0,0 @@
-using LiteCharms.Features.Email.Commands;
-using LiteCharms.Models.Configuraton.Email;
-
-namespace LiteCharms.Features.Email.Commands.Handlers;
-
-public class SendEmailCommandHandler(IOptions smtpOptions) : IRequestHandler
-{
- public async ValueTask Handle(SendEmailCommand request, CancellationToken cancellationToken)
- {
- try
- {
- var settings = smtpOptions.Value;
-
- if(settings == null)
- return Result.Fail(new Error("SMTP settings are not configured."));
-
- if(settings.Credentials == null)
- return Result.Fail(new Error("SMTP credentials are not configured."));
-
- if(string.IsNullOrWhiteSpace(settings?.Credentials.Username) || string.IsNullOrWhiteSpace(settings.Credentials.Password))
- return Result.Fail(new Error("SMTP credentials are incomplete."));
-
- if(string.IsNullOrWhiteSpace(settings.Host) || settings.Port == 0)
- return Result.Fail(new Error("SMTP host and port must be configured."));
-
- var message = new MimeMessage();
- message.From.Add(new MailboxAddress(request.SenderName, request.From!));
- message.To.Add(new MailboxAddress(request.RecipientName, request.To!));
- message.Subject = request.Subject!;
-
- var bodyBuilder = new BodyBuilder();
-
- if(request.Attachment?.Length > 0 && !string.IsNullOrEmpty(request.AttachmentFileName))
- bodyBuilder.Attachments.Add(request.AttachmentFileName!, request.Attachment!, cancellationToken);
-
- if (!request.IsHtml) bodyBuilder.TextBody = request.Message;
- if (request.IsHtml) bodyBuilder.HtmlBody = request.Message;
-
- message.Body = bodyBuilder.ToMessageBody();
-
- using var client = new SmtpClient();
-
- await client.ConnectAsync(settings.Host!, settings.Port, settings.UseSsl, cancellationToken);
- await client.AuthenticateAsync(settings.Credentials!.Username!, settings.Credentials.Password!, cancellationToken);
-
- var response = await client.SendAsync(message, cancellationToken);
-
- bool emailSent = response.Contains("OK", StringComparison.InvariantCultureIgnoreCase);
-
- await client.DisconnectAsync(true, cancellationToken);
-
- return emailSent
- ? Result.Ok()
- : Result.Fail(new Error("Failed to send email. SMTP response: " + response));
- }
- catch (Exception ex)
- {
- return Result.Fail(new Error(ex.Message).CausedBy(ex));
- }
- }
-}
diff --git a/LiteCharms.Features/Email/Commands/SendEmailCommand.cs b/LiteCharms.Features/Email/Commands/SendEmailCommand.cs
deleted file mode 100644
index 972e496..0000000
--- a/LiteCharms.Features/Email/Commands/SendEmailCommand.cs
+++ /dev/null
@@ -1,79 +0,0 @@
-namespace LiteCharms.Features.Email.Commands;
-
-public class SendEmailCommand : IRequest
-{
- public string? From { get; set; }
-
- public string? SenderName { get; set; }
-
- public string? To { get; set; }
-
- public string? RecipientName { get; set; }
-
- public string? Subject { get; set; }
-
- public string? Message { get; set; }
-
- public bool IsHtml { get; set; }
-
- public Stream? Attachment { get; set; }
-
- public string? AttachmentFileName { get; set; }
-
- private SendEmailCommand(string from, string senderName, string to, string recipientName, string subject, string message, bool isHtml = false, Stream? attachment = null, string? attachmentFileName = null)
- {
- From = from;
- To = to;
- Subject = subject;
- Message = message;
- IsHtml = isHtml;
- Attachment = attachment;
- AttachmentFileName = attachmentFileName;
- SenderName = senderName;
- RecipientName = recipientName;
- }
-
- public static SendEmailCommand Create(string from, string senderName, string to, string recipientName, string subject, string message, bool isHtml = false, Stream? attachment = null, string? attachmentFileName = null)
- {
- if (string.IsNullOrWhiteSpace(from))
- throw new ArgumentException("From address is required.");
-
- if (string.IsNullOrWhiteSpace(senderName))
- throw new ArgumentException("Sender name is required.");
-
- if (!string.IsNullOrWhiteSpace(senderName) && senderName?.Length > 255)
- throw new ArgumentException("Sender name cannot exceed 255 characters.");
-
- if (string.IsNullOrWhiteSpace(to))
- throw new ArgumentException("To address is required.");
-
- if (string.IsNullOrWhiteSpace(recipientName))
- throw new ArgumentException("Recipient name is required.");
-
- if (!string.IsNullOrWhiteSpace(recipientName) && recipientName?.Length > 255)
- throw new ArgumentException("Recipient name cannot exceed 255 characters.");
-
- if (string.IsNullOrWhiteSpace(subject))
- throw new ArgumentException("Subject is required.");
-
- if (!string.IsNullOrWhiteSpace(subject) && subject?.Length > 2048)
- throw new ArgumentException("Subject cannot exceed 2048 characters.");
-
- if (string.IsNullOrWhiteSpace(message))
- throw new ArgumentException("Message is required.");
-
- if (message.Length > 10485760)
- throw new ArgumentException("Message cannot exceed 10 MB.");
-
- if (attachment != null && string.IsNullOrWhiteSpace(attachmentFileName))
- throw new ArgumentException("Attachment file name must be provided when an attachment is included.");
-
- if (attachment is not null && attachment.Length > 10485760)
- throw new ArgumentException("Attachment cannot exceed 10 MB.");
-
- if (!string.IsNullOrWhiteSpace(attachmentFileName) && attachmentFileName.Length > 255)
- throw new ArgumentException("Attachment file name cannot exceed 255 characters.");
-
- return new(from, senderName!, to, recipientName!, subject!, message, isHtml, attachment, attachmentFileName);
- }
-}
diff --git a/LiteCharms.Models/Configuraton/Email/Account.cs b/LiteCharms.Features/Email/Configuration/Account.cs
similarity index 67%
rename from LiteCharms.Models/Configuraton/Email/Account.cs
rename to LiteCharms.Features/Email/Configuration/Account.cs
index 96424ce..e0c65e7 100644
--- a/LiteCharms.Models/Configuraton/Email/Account.cs
+++ b/LiteCharms.Features/Email/Configuration/Account.cs
@@ -1,4 +1,4 @@
-namespace LiteCharms.Models.Configuraton.Email;
+namespace LiteCharms.Features.Email.Configuration;
public class Account
{
diff --git a/LiteCharms.Models/Configuraton/Email/SmtpSettings.cs b/LiteCharms.Features/Email/Configuration/SmtpSettings.cs
similarity index 77%
rename from LiteCharms.Models/Configuraton/Email/SmtpSettings.cs
rename to LiteCharms.Features/Email/Configuration/SmtpSettings.cs
index c44fbbe..78798f2 100644
--- a/LiteCharms.Models/Configuraton/Email/SmtpSettings.cs
+++ b/LiteCharms.Features/Email/Configuration/SmtpSettings.cs
@@ -1,4 +1,4 @@
-namespace LiteCharms.Models.Configuraton.Email;
+namespace LiteCharms.Features.Email.Configuration;
public class SmtpSettings
{
diff --git a/LiteCharms.Features/Email/EmailService.cs b/LiteCharms.Features/Email/EmailService.cs
new file mode 100644
index 0000000..8cb3a82
--- /dev/null
+++ b/LiteCharms.Features/Email/EmailService.cs
@@ -0,0 +1,192 @@
+using LiteCharms.Features.Email.Configuration;
+using LiteCharms.Features.Email.Extensions;
+using LiteCharms.Features.Email.Models;
+using LiteCharms.Features.Shop;
+
+namespace LiteCharms.Features.Email;
+
+public class EmailService(IOptions options) : IEmailService
+{
+ private readonly SmtpSettings settings = options.Value;
+ private readonly SmtpClient client = new();
+ private readonly int sendMaxCount = 10;
+ private int sendCount = 0;
+
+ public EmailStatuses Status { get; private set; } = EmailStatuses.Disconnected;
+
+ public async Task> SendEmailAsync(Message message, CancellationToken cancellationToken = default)
+ {
+ using var activity = EmailTelemetry.Source.StartActivity("Email Send");
+ activity?.SetTag("email.recipient", message.Recipient?.Address);
+
+ try
+ {
+ if (Status != EmailStatuses.Connected)
+ {
+ activity?.SetStatus(ActivityStatusCode.Error, "Disconnected");
+
+ return Result.Fail("Smtp service is disconnected.");
+ }
+
+ var email = new MimeMessage();
+ email.From.Add(new MailboxAddress(message.Sender!.Name, message.Sender.Address!));
+ email.To.Add(new MailboxAddress(message.Recipient!.Name, message.Recipient!.Address!));
+ email.Subject = message.Subject!;
+
+ var bodyBuilder = new BodyBuilder();
+
+ foreach (var attachment in message.Body?.Attachments!)
+ bodyBuilder.Attachments.Add(attachment.Name!, attachment.FileStream!, cancellationToken);
+
+ if (!message.Body.Properties.IsHtml) bodyBuilder.TextBody = message.Body.Message;
+ if (message.Body.Properties.IsHtml) bodyBuilder.HtmlBody = message.Body.Message;
+
+ email.Body = bodyBuilder.ToMessageBody();
+
+ var response = await client.SendAsync(email, cancellationToken);
+
+ bool emailSent = response.Contains("OK", StringComparison.InvariantCultureIgnoreCase);
+
+ message.Dispose();
+
+ Interlocked.Increment(ref sendCount);
+
+ if (sendCount % sendMaxCount == 0)
+ {
+ using var delayActivity = EmailTelemetry.Source.StartActivity("Rate Limit Pause");
+
+ sendCount = 0;
+
+ await Task.Delay(1000, cancellationToken);
+ }
+
+ if (emailSent)
+ {
+ EmailTelemetry.EmailsSent.Add(1, new TagList { { "host", settings.Host } });
+
+ return Result.Ok(Response.Create(EmailStatuses.Success));
+ }
+
+ await DisconnectAsync(cancellationToken);
+
+ if (response.Contains("421"))
+ {
+ Status = EmailStatuses.TooManyConnections;
+
+ return Result.Fail(response);
+ }
+
+ if (response.Contains("451"))
+ {
+ Status = EmailStatuses.ConnectionAborted;
+
+ return Result.Fail(response);
+ }
+
+ EmailTelemetry.EmailsFailed.Add(1, new TagList { { "error_message", response } });
+
+ Status = EmailStatuses.Disconnected;
+
+ return Result.Fail("General error, disconnected");
+ }
+ catch (Exception ex)
+ {
+ activity?.SetStatus(ActivityStatusCode.Error, ex.Message);
+ activity?.AddException(ex);
+
+ EmailTelemetry.EmailsFailed.Add(1, new TagList { { "exception", ex.GetType().Name } });
+
+ return Result.Fail(new Error(ex.Message).CausedBy(ex));
+ }
+ }
+
+ public async Task> ConnectAsync(CancellationToken cancellationToken = default)
+ {
+ using var activity = EmailTelemetry.Source.StartActivity("Email Connect");
+ activity?.SetTag("email.smtp.connect", settings.Host);
+
+ try
+ {
+ if (Status is EmailStatuses.Connected) return Result.Ok(Response.Create(Status));
+
+ await client.ConnectAsync(settings.Host!, settings.Port, settings.UseSsl, cancellationToken);
+ await client.AuthenticateAsync(settings.Credentials!.Username!, settings.Credentials.Password!, cancellationToken);
+
+ Status = EmailStatuses.Connected;
+
+ activity?.SetStatus(ActivityStatusCode.Ok, "Connected");
+
+ return Result.Ok(Response.Create(Status));
+ }
+ catch (MailKit.ProtocolException ex)
+ {
+ activity?.SetStatus(ActivityStatusCode.Error, ex.Message);
+ activity?.AddException(ex);
+
+ EmailTelemetry.EmailsFailed.Add(1, new TagList { { "exception", ex.GetType().Name } });
+
+ Status = EmailStatuses.ProtocolError;
+
+ return Result.Fail(new Error(ex.Message).CausedBy(ex));
+ }
+ catch (Exception ex) when (ex is MailKit.Security.SslHandshakeException || ex is MailKit.Security.AuthenticationException)
+ {
+ activity?.SetStatus(ActivityStatusCode.Error, ex.Message);
+ activity?.AddException(ex);
+
+ EmailTelemetry.EmailsFailed.Add(1, new TagList { { "exception", ex.GetType().Name } });
+
+ Status = EmailStatuses.AuthenticationError;
+
+ return Result.Fail(new Error(ex.Message).CausedBy(ex));
+ }
+ catch (Exception ex)
+ {
+ activity?.SetStatus(ActivityStatusCode.Error, ex.Message);
+ activity?.AddException(ex);
+
+ EmailTelemetry.EmailsFailed.Add(1, new TagList { { "exception", ex.GetType().Name } });
+
+ Status = EmailStatuses.GeneralError;
+
+ return Result.Fail(new Error(ex.Message).CausedBy(ex));
+ }
+ }
+
+ public async Task DisconnectAsync(CancellationToken cancellationToken = default)
+ {
+ using var activity = EmailTelemetry.Source.StartActivity("Email Disconnect");
+ activity?.SetTag("email.smtp.disconnect", settings.Host);
+
+ try
+ {
+ if (Status is EmailStatuses.Disconnected) return Result.Ok();
+
+ await client.DisconnectAsync(true, cancellationToken);
+
+ activity?.SetStatus(ActivityStatusCode.Ok, "Disconnected");
+
+ Status = EmailStatuses.Disconnected;
+
+ return Result.Ok();
+ }
+ catch (Exception ex)
+ {
+ activity?.SetStatus(ActivityStatusCode.Error, ex.Message);
+ activity?.AddException(ex);
+
+ EmailTelemetry.EmailsFailed.Add(1, new TagList { { "exception", ex.GetType().Name } });
+
+ Status = EmailStatuses.GeneralError;
+
+ return Result.Fail(new Error(ex.Message).CausedBy(ex));
+ }
+ }
+
+ public void Dispose()
+ {
+ client.Dispose();
+
+ GC.SuppressFinalize(this);
+ }
+}
diff --git a/LiteCharms.Features/Email/Events/Handlers/SendShopEmailEnquiryEventHandler.cs b/LiteCharms.Features/Email/Events/Handlers/SendShopEmailEnquiryEventHandler.cs
index 9c19500..f3e703f 100644
--- a/LiteCharms.Features/Email/Events/Handlers/SendShopEmailEnquiryEventHandler.cs
+++ b/LiteCharms.Features/Email/Events/Handlers/SendShopEmailEnquiryEventHandler.cs
@@ -1,18 +1,22 @@
using LiteCharms.Features.Notifications.Commands;
-using static LiteCharms.Abstractions.Constants;
+using LiteCharms.Features.Shop;
+using static LiteCharms.Features.Email.Extensions.Constants;
namespace LiteCharms.Features.Email.Events.Handlers;
+// TODO: Inject the INotificationService
public class SendShopEmailEnquiryEventHandler(ISender mediator) :
INotificationHandler
{
public async ValueTask Handle(SendShopEmailEnquiryEvent notification, CancellationToken cancellationToken)
{
- var command = CreateNotificationCommand.Create(Models.NotificationDirection.Outgoing, notification.SenderName!,
- notification.SenderAddress!, notification.Subject!, notification.Message!, Models.NotificationPlatforms.Email,
+ // TODO: Refactor this to use the NotificationService
+ var command = CreateNotification.Create(NotificationDirection.Outgoing, notification.SenderName!,
+ notification.SenderAddress!, notification.Subject!, notification.Message!, NotificationPlatforms.Email,
notification.Priority, ShopEmailFromName, ShopEmailFromAddress, Guid.CreateVersion7().ToString(),
- Models.CorrelationIdTypes.None, isInternal: true, isHtml: false);
+ CorrelationIdTypes.None, isInternal: true, isHtml: false);
+ // TODO: Remove, deprecated
await mediator.Send(command, cancellationToken);
}
}
diff --git a/LiteCharms.Features/Email/Events/SendShopEmailEnquiryEvent.cs b/LiteCharms.Features/Email/Events/SendShopEmailEnquiryEvent.cs
index 07e3830..3377b44 100644
--- a/LiteCharms.Features/Email/Events/SendShopEmailEnquiryEvent.cs
+++ b/LiteCharms.Features/Email/Events/SendShopEmailEnquiryEvent.cs
@@ -1,5 +1,5 @@
-using LiteCharms.Abstractions;
-using LiteCharms.Models;
+using LiteCharms.Features.Abstractions;
+using LiteCharms.Features.Shop;
namespace LiteCharms.Features.Email.Events;
diff --git a/LiteCharms.Features/Email/Extensions/Constants.cs b/LiteCharms.Features/Email/Extensions/Constants.cs
new file mode 100644
index 0000000..1d02879
--- /dev/null
+++ b/LiteCharms.Features/Email/Extensions/Constants.cs
@@ -0,0 +1,8 @@
+namespace LiteCharms.Features.Email.Extensions;
+
+public static class Constants
+{
+ public const string ShopSchedulerName = "shop";
+ public const string ShopEmailFromName = "Khongisa Shop";
+ public const string ShopEmailFromAddress = "shop@litecharms.co.za";
+}
diff --git a/LiteCharms.Features/Email/Extensions/EmailTelemetry.cs b/LiteCharms.Features/Email/Extensions/EmailTelemetry.cs
new file mode 100644
index 0000000..48a9a4a
--- /dev/null
+++ b/LiteCharms.Features/Email/Extensions/EmailTelemetry.cs
@@ -0,0 +1,9 @@
+namespace LiteCharms.Features.Email.Extensions;
+
+public static class EmailTelemetry
+{
+ public static readonly ActivitySource Source = new("LiteCharms.EmailService");
+ public static readonly Meter Meter = new("LiteCharms.EmailService");
+ public static readonly Counter EmailsSent = Meter.CreateCounter("emails_sent_total", "count", "Total successful emails sent");
+ public static readonly Counter EmailsFailed = Meter.CreateCounter("emails_failed_total", "count", "Total failed email attempts");
+}
diff --git a/LiteCharms.Features/Email/Extensions/Setup.cs b/LiteCharms.Features/Email/Extensions/Setup.cs
new file mode 100644
index 0000000..f937dda
--- /dev/null
+++ b/LiteCharms.Features/Email/Extensions/Setup.cs
@@ -0,0 +1,19 @@
+using LiteCharms.Features.Email.Configuration;
+
+namespace LiteCharms.Features.Email.Extensions;
+
+public static class Setup
+{
+ public static IServiceCollection AddEmailServices(this IServiceCollection services, IConfiguration configuration)
+ {
+ services.Configure(configuration.GetSection("Email"));
+
+ services.AddSingleton();
+
+ services.AddOpenTelemetry()
+ .WithTracing(tracing => tracing.AddSource("LiteCharms.EmailService"))
+ .WithMetrics(metrics => metrics.AddMeter("LiteCharms.EmailService"));
+
+ return services;
+ }
+}
diff --git a/LiteCharms.Features/Email/IEmailService.cs b/LiteCharms.Features/Email/IEmailService.cs
new file mode 100644
index 0000000..bda6a6f
--- /dev/null
+++ b/LiteCharms.Features/Email/IEmailService.cs
@@ -0,0 +1,15 @@
+using LiteCharms.Features.Email.Models;
+using LiteCharms.Features.Shop;
+
+namespace LiteCharms.Features.Email;
+
+public interface IEmailService : IDisposable
+{
+ EmailStatuses Status { get; }
+
+ Task> SendEmailAsync(Message message, CancellationToken cancellationToken = default);
+
+ Task> ConnectAsync(CancellationToken cancellationToken = default);
+
+ Task DisconnectAsync(CancellationToken cancellationToken = default);
+}
diff --git a/LiteCharms.Features/Email/Models/Attachment.cs b/LiteCharms.Features/Email/Models/Attachment.cs
new file mode 100644
index 0000000..6558058
--- /dev/null
+++ b/LiteCharms.Features/Email/Models/Attachment.cs
@@ -0,0 +1,8 @@
+namespace LiteCharms.Features.Email.Models;
+
+public class Attachment
+{
+ public string? Name { get; set; }
+
+ public Stream? FileStream { get; set; }
+}
diff --git a/LiteCharms.Features/Email/Models/Body.cs b/LiteCharms.Features/Email/Models/Body.cs
new file mode 100644
index 0000000..99156d8
--- /dev/null
+++ b/LiteCharms.Features/Email/Models/Body.cs
@@ -0,0 +1,26 @@
+namespace LiteCharms.Features.Email.Models;
+
+public class Body : IDisposable
+{
+ public string? Message { get; set; }
+
+ public ReadOnlyCollection? Attachments { get; set; }
+
+ public BodyProperties Properties { get; set; } = new();
+
+ public void Dispose()
+ {
+ if (Attachments is null) return;
+
+ foreach (var attachment in Attachments!)
+ {
+ if (attachment is not null)
+ {
+ attachment.FileStream!.Close();
+ attachment.FileStream!.Dispose();
+ }
+ }
+
+ GC.SuppressFinalize(this);
+ }
+}
diff --git a/LiteCharms.Features/Email/Models/BodyProperties.cs b/LiteCharms.Features/Email/Models/BodyProperties.cs
new file mode 100644
index 0000000..7bdfa01
--- /dev/null
+++ b/LiteCharms.Features/Email/Models/BodyProperties.cs
@@ -0,0 +1,8 @@
+namespace LiteCharms.Features.Email.Models;
+
+public class BodyProperties
+{
+ public bool IsHtml { get; set; }
+
+ public bool HasAttachments { get; set; }
+}
diff --git a/LiteCharms.Models/EmailEnquiry.cs b/LiteCharms.Features/Email/Models/EmailEnquiry.cs
similarity index 86%
rename from LiteCharms.Models/EmailEnquiry.cs
rename to LiteCharms.Features/Email/Models/EmailEnquiry.cs
index a858328..97c2fe3 100644
--- a/LiteCharms.Models/EmailEnquiry.cs
+++ b/LiteCharms.Features/Email/Models/EmailEnquiry.cs
@@ -1,4 +1,6 @@
-namespace LiteCharms.Models;
+using System.ComponentModel.DataAnnotations;
+
+namespace LiteCharms.Features.Email.Models;
public sealed class EmailEnquiry
{
diff --git a/LiteCharms.Features/Email/Models/Message.cs b/LiteCharms.Features/Email/Models/Message.cs
new file mode 100644
index 0000000..7432545
--- /dev/null
+++ b/LiteCharms.Features/Email/Models/Message.cs
@@ -0,0 +1,19 @@
+namespace LiteCharms.Features.Email.Models;
+
+public class Message : IDisposable
+{
+ public Party? Sender { get; set; }
+
+ public Party? Recipient { get; set; }
+
+ public string? Subject { get; set; }
+
+ public Body? Body { get; set; }
+
+ public void Dispose()
+ {
+ Body?.Dispose();
+
+ GC.SuppressFinalize(this);
+ }
+}
diff --git a/LiteCharms.Features/Email/Models/Party.cs b/LiteCharms.Features/Email/Models/Party.cs
new file mode 100644
index 0000000..65c2e85
--- /dev/null
+++ b/LiteCharms.Features/Email/Models/Party.cs
@@ -0,0 +1,8 @@
+namespace LiteCharms.Features.Email.Models;
+
+public class Party
+{
+ public string? Name { get; set; }
+
+ public string? Address { get; set; }
+}
diff --git a/LiteCharms.Features/Email/Models/Response.cs b/LiteCharms.Features/Email/Models/Response.cs
new file mode 100644
index 0000000..4474d9e
--- /dev/null
+++ b/LiteCharms.Features/Email/Models/Response.cs
@@ -0,0 +1,22 @@
+using LiteCharms.Features.Shop;
+
+namespace LiteCharms.Features.Email.Models;
+
+public class Response
+{
+ public int Code { get; set; }
+
+ public string? Error { get; set; }
+
+ public EmailStatuses Status { get; set; }
+
+ private Response(EmailStatuses status, int code = 0, string? error = null)
+ {
+ Status = status;
+ Code = code;
+ Error = error;
+ }
+
+ public static Response Create(EmailStatuses status, int code = 0, string? error = null) =>
+ new(status, code, error);
+}
diff --git a/LiteCharms.Features/Extensions/Constants.cs b/LiteCharms.Features/Extensions/Constants.cs
new file mode 100644
index 0000000..b9d11e1
--- /dev/null
+++ b/LiteCharms.Features/Extensions/Constants.cs
@@ -0,0 +1,5 @@
+namespace LiteCharms.Features.Extensions;
+
+public static class Constants
+{
+}
diff --git a/LiteCharms.Extensions/EntityModeMappers.cs b/LiteCharms.Features/Extensions/EntityModeMappers.cs
similarity index 100%
rename from LiteCharms.Extensions/EntityModeMappers.cs
rename to LiteCharms.Features/Extensions/EntityModeMappers.cs
diff --git a/LiteCharms.Features/Extensions/Hash.cs b/LiteCharms.Features/Extensions/Hash.cs
new file mode 100644
index 0000000..ab76ecc
--- /dev/null
+++ b/LiteCharms.Features/Extensions/Hash.cs
@@ -0,0 +1,7 @@
+namespace LiteCharms.Features.Extensions;
+
+public static class Hash
+{
+ public static Func GenerateSha256HashString = (input) =>
+ Convert.ToHexString(SHA256.HashData(Encoding.UTF8.GetBytes(input!)));
+}
diff --git a/LiteCharms.Extensions/HealthChecks.cs b/LiteCharms.Features/Extensions/HealthChecks.cs
similarity index 100%
rename from LiteCharms.Extensions/HealthChecks.cs
rename to LiteCharms.Features/Extensions/HealthChecks.cs
diff --git a/LiteCharms.Extensions/Monitoring.cs b/LiteCharms.Features/Extensions/Monitoring.cs
similarity index 100%
rename from LiteCharms.Extensions/Monitoring.cs
rename to LiteCharms.Features/Extensions/Monitoring.cs
diff --git a/LiteCharms.Extensions/Postgres.cs b/LiteCharms.Features/Extensions/Postgres.cs
similarity index 100%
rename from LiteCharms.Extensions/Postgres.cs
rename to LiteCharms.Features/Extensions/Postgres.cs
diff --git a/LiteCharms.Extensions/Quartz.cs b/LiteCharms.Features/Extensions/Quartz.cs
similarity index 100%
rename from LiteCharms.Extensions/Quartz.cs
rename to LiteCharms.Features/Extensions/Quartz.cs
diff --git a/LiteCharms.Extensions/ServiceBus.cs b/LiteCharms.Features/Extensions/ServiceBus.cs
similarity index 100%
rename from LiteCharms.Extensions/ServiceBus.cs
rename to LiteCharms.Features/Extensions/ServiceBus.cs
diff --git a/LiteCharms.Abstractions/Timezones.cs b/LiteCharms.Features/Extensions/Timezones.cs
similarity index 96%
rename from LiteCharms.Abstractions/Timezones.cs
rename to LiteCharms.Features/Extensions/Timezones.cs
index 5457130..bbddd5d 100644
--- a/LiteCharms.Abstractions/Timezones.cs
+++ b/LiteCharms.Features/Extensions/Timezones.cs
@@ -1,4 +1,4 @@
-namespace LiteCharms.Abstractions;
+namespace LiteCharms.Features.Extensions;
public static class Timezones
{
diff --git a/LiteCharms.Infrastructure/HealthChecks/PostgresHealthCheck.cs b/LiteCharms.Features/HealthChecks/PostgresHealthCheck.cs
similarity index 94%
rename from LiteCharms.Infrastructure/HealthChecks/PostgresHealthCheck.cs
rename to LiteCharms.Features/HealthChecks/PostgresHealthCheck.cs
index 9cb5f03..377da08 100644
--- a/LiteCharms.Infrastructure/HealthChecks/PostgresHealthCheck.cs
+++ b/LiteCharms.Features/HealthChecks/PostgresHealthCheck.cs
@@ -1,4 +1,4 @@
-namespace LiteCharms.Infrastructure.HealthChecks;
+namespace LiteCharms.Features.HealthChecks;
public class PostgresHealthCheck(IConfiguration configuration) : IHealthCheck
{
diff --git a/LiteCharms.Infrastructure/HealthChecks/QuartzHealthCheck.cs b/LiteCharms.Features/HealthChecks/QuartzHealthCheck.cs
similarity index 93%
rename from LiteCharms.Infrastructure/HealthChecks/QuartzHealthCheck.cs
rename to LiteCharms.Features/HealthChecks/QuartzHealthCheck.cs
index d1a8bd0..59eb397 100644
--- a/LiteCharms.Infrastructure/HealthChecks/QuartzHealthCheck.cs
+++ b/LiteCharms.Features/HealthChecks/QuartzHealthCheck.cs
@@ -1,4 +1,4 @@
-namespace LiteCharms.Infrastructure.HealthChecks;
+namespace LiteCharms.Features.HealthChecks;
public class QuartzHealthCheck(ISchedulerFactory schedulerFactory) : IHealthCheck
{
diff --git a/LiteCharms.Features/LiteCharms.Features.csproj b/LiteCharms.Features/LiteCharms.Features.csproj
index f541547..3d6552b 100644
--- a/LiteCharms.Features/LiteCharms.Features.csproj
+++ b/LiteCharms.Features/LiteCharms.Features.csproj
@@ -28,6 +28,86 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+
+
+
+
+
+
@@ -50,16 +130,17 @@
+
-
-
+
+
+
+
+
+
+
-
-
-
-
-
diff --git a/LiteCharms.Features/Mediator/LoggingPipelineBehavior.cs b/LiteCharms.Features/Mediator/LoggingPipelineBehavior.cs
new file mode 100644
index 0000000..2bf0410
--- /dev/null
+++ b/LiteCharms.Features/Mediator/LoggingPipelineBehavior.cs
@@ -0,0 +1,29 @@
+namespace LiteCharms.Features.Mediator;
+
+public sealed class LoggingPipelineBehavior(ILogger> logger) :
+ IPipelineBehavior
+ where TRequest : IRequest
+ where TResponse : ResultBase, new()
+{
+ public async ValueTask Handle(TRequest message, MessageHandlerDelegate next, CancellationToken cancellationToken)
+ {
+ TResponse? response = await next(message, cancellationToken);
+
+ if (response is null)
+ logger.LogCritical("{Request} {TypeName} was returned as null", typeof(TRequest).Name, typeof(TRequest).Name);
+
+ if(response?.IsFailed == true || response?.Errors?.Any() == true)
+ {
+ foreach (var error in response.Errors)
+ {
+ if (!string.IsNullOrWhiteSpace(error.Message))
+ logger.LogWarning("{Request} {Error}", typeof(TRequest).Name, error.Message);
+
+ if (error?.Reasons?.Count > 0)
+ error.Reasons.ForEach(r => logger.LogError("{Request} {Reason}", typeof(TRequest).Name, r.ToString()));
+ }
+ }
+
+ return response;
+ }
+}
diff --git a/LiteCharms.Features/Mediator/MediatorTelemetry.cs b/LiteCharms.Features/Mediator/MediatorTelemetry.cs
new file mode 100644
index 0000000..00493c1
--- /dev/null
+++ b/LiteCharms.Features/Mediator/MediatorTelemetry.cs
@@ -0,0 +1,12 @@
+namespace LiteCharms.Features.Mediator;
+
+public static class MediatorTelemetry
+{
+ public const string ServiceName = "LiteCharms.Mediator";
+
+ public static readonly ActivitySource Source = new(ServiceName);
+ public static readonly Meter Meter = new(ServiceName);
+
+ public static readonly Counter RequestCounter = Meter.CreateCounter("mediator_requests_total");
+ public static readonly Histogram RequestDuration = Meter.CreateHistogram("mediator_request_duration_ms");
+}
diff --git a/LiteCharms.Features/Mediator/TelemetryPipelineBehavior.cs b/LiteCharms.Features/Mediator/TelemetryPipelineBehavior.cs
new file mode 100644
index 0000000..0a9efbd
--- /dev/null
+++ b/LiteCharms.Features/Mediator/TelemetryPipelineBehavior.cs
@@ -0,0 +1,66 @@
+namespace LiteCharms.Features.Mediator;
+
+public sealed class TelemetryPipelineBehavior :
+ IPipelineBehavior
+ where TRequest : IRequest
+ where TResponse : ResultBase, new()
+{
+ public async ValueTask Handle(TRequest message, MessageHandlerDelegate next, CancellationToken cancellationToken)
+ {
+ var requestName = typeof(TRequest).Name;
+
+ using var activity = MediatorTelemetry.Source.StartActivity(requestName);
+
+ activity?.SetTag("mediator.request_type", typeof(TRequest).FullName);
+
+ var stopWatch = Stopwatch.StartNew();
+ var status = "Success";
+
+ try
+ {
+ TResponse? response = await next(message, cancellationToken);
+
+ if (response is null)
+ {
+ status = "NullResponse";
+ activity?.SetStatus(ActivityStatusCode.Error, "Response was null");
+
+ return response;
+ }
+
+ if (response.IsFailed)
+ {
+ status = "Failed";
+ activity?.SetStatus(ActivityStatusCode.Error, "Request failed");
+
+ var firstError = response.Errors.FirstOrDefault()?.Message ?? "Unknown Error";
+ activity?.SetTag("error.message", firstError);
+
+ foreach (var error in response.Errors)
+ activity?.AddEvent(new ActivityEvent("Result Error", tags: new() { { "message", error.Message } }));
+ }
+ else
+ activity?.SetStatus(ActivityStatusCode.Ok);
+
+ return response;
+ }
+ catch (Exception ex)
+ {
+ status = "Exception";
+ activity?.SetStatus(ActivityStatusCode.Error, ex.Message);
+
+ activity?.AddException(ex);
+
+ throw;
+ }
+ finally
+ {
+ stopWatch.Stop();
+
+ var tags = new TagList { { "request", requestName }, { "status", status } };
+
+ MediatorTelemetry.RequestCounter.Add(1, tags);
+ MediatorTelemetry.RequestDuration.Record(stopWatch.Elapsed.TotalMilliseconds, tags);
+ }
+ }
+}
\ No newline at end of file
diff --git a/LiteCharms.Abstractions/IJobOrchestrator.cs b/LiteCharms.Features/Quartz/Abstractions/IJobOrchestrator.cs
similarity index 79%
rename from LiteCharms.Abstractions/IJobOrchestrator.cs
rename to LiteCharms.Features/Quartz/Abstractions/IJobOrchestrator.cs
index d98c155..8ce2c33 100644
--- a/LiteCharms.Abstractions/IJobOrchestrator.cs
+++ b/LiteCharms.Features/Quartz/Abstractions/IJobOrchestrator.cs
@@ -1,4 +1,6 @@
-namespace LiteCharms.Abstractions;
+using LiteCharms.Features.Abstractions;
+
+namespace LiteCharms.Features.Quartz.Abstractions;
public interface IJobOrchestrator
{
diff --git a/LiteCharms.Infrastructure/Quartz/JobOrchestrator.cs b/LiteCharms.Features/Quartz/JobOrchestrator.cs
similarity index 93%
rename from LiteCharms.Infrastructure/Quartz/JobOrchestrator.cs
rename to LiteCharms.Features/Quartz/JobOrchestrator.cs
index 6874541..4f578b5 100644
--- a/LiteCharms.Infrastructure/Quartz/JobOrchestrator.cs
+++ b/LiteCharms.Features/Quartz/JobOrchestrator.cs
@@ -1,7 +1,8 @@
-using LiteCharms.Abstractions;
-using static LiteCharms.Abstractions.Timezones;
+using LiteCharms.Features.Abstractions;
+using LiteCharms.Features.Quartz.Abstractions;
+using static LiteCharms.Features.Extensions.Timezones;
-namespace LiteCharms.Infrastructure.Quartz;
+namespace LiteCharms.Features.Quartz;
public class JobOrchestrator(ISchedulerFactory schedulerFactory) : IJobOrchestrator
{
diff --git a/LiteCharms.Infrastructure/Quartz/MediatorJob.cs b/LiteCharms.Features/Quartz/MediatorJob.cs
similarity index 87%
rename from LiteCharms.Infrastructure/Quartz/MediatorJob.cs
rename to LiteCharms.Features/Quartz/MediatorJob.cs
index 8cf9c75..b3ea928 100644
--- a/LiteCharms.Infrastructure/Quartz/MediatorJob.cs
+++ b/LiteCharms.Features/Quartz/MediatorJob.cs
@@ -1,6 +1,6 @@
-using LiteCharms.Abstractions;
+using LiteCharms.Features.Abstractions;
-namespace LiteCharms.Infrastructure.Quartz;
+namespace LiteCharms.Features.Quartz;
[DisallowConcurrentExecution]
public class MediatorJob(IMediator mediator) : IJob where TNotification : IEvent
diff --git a/LiteCharms.Infrastructure/Quartz/RetryJobListener.cs b/LiteCharms.Features/Quartz/RetryJobListener.cs
similarity index 93%
rename from LiteCharms.Infrastructure/Quartz/RetryJobListener.cs
rename to LiteCharms.Features/Quartz/RetryJobListener.cs
index afe84e7..968b8bb 100644
--- a/LiteCharms.Infrastructure/Quartz/RetryJobListener.cs
+++ b/LiteCharms.Features/Quartz/RetryJobListener.cs
@@ -1,4 +1,4 @@
-namespace LiteCharms.Infrastructure.Quartz;
+namespace LiteCharms.Features.Quartz;
public class RetryJobListener : IJobListener
{
diff --git a/LiteCharms.Abstractions/EventBusQueueBase.cs b/LiteCharms.Features/ServiceBus/Abstractions/EventBusQueueBase.cs
similarity index 73%
rename from LiteCharms.Abstractions/EventBusQueueBase.cs
rename to LiteCharms.Features/ServiceBus/Abstractions/EventBusQueueBase.cs
index 29f7265..31391af 100644
--- a/LiteCharms.Abstractions/EventBusQueueBase.cs
+++ b/LiteCharms.Features/ServiceBus/Abstractions/EventBusQueueBase.cs
@@ -1,4 +1,6 @@
-namespace LiteCharms.Abstractions;
+using LiteCharms.Features.Abstractions;
+
+namespace LiteCharms.Features.ServiceBus.Abstractions;
public abstract class EventBusQueueBase
{
diff --git a/LiteCharms.Abstractions/IEventBus.cs b/LiteCharms.Features/ServiceBus/Abstractions/IEventBus.cs
similarity index 64%
rename from LiteCharms.Abstractions/IEventBus.cs
rename to LiteCharms.Features/ServiceBus/Abstractions/IEventBus.cs
index f40d372..4f3ebb0 100644
--- a/LiteCharms.Abstractions/IEventBus.cs
+++ b/LiteCharms.Features/ServiceBus/Abstractions/IEventBus.cs
@@ -1,4 +1,6 @@
-namespace LiteCharms.Abstractions;
+using LiteCharms.Features.Abstractions;
+
+namespace LiteCharms.Features.ServiceBus.Abstractions;
public interface IEventBus
{
diff --git a/LiteCharms.Abstractions/IEventBusQueue.cs b/LiteCharms.Features/ServiceBus/Abstractions/IEventBusQueue.cs
similarity index 56%
rename from LiteCharms.Abstractions/IEventBusQueue.cs
rename to LiteCharms.Features/ServiceBus/Abstractions/IEventBusQueue.cs
index 98750b4..1877555 100644
--- a/LiteCharms.Abstractions/IEventBusQueue.cs
+++ b/LiteCharms.Features/ServiceBus/Abstractions/IEventBusQueue.cs
@@ -1,4 +1,6 @@
-namespace LiteCharms.Abstractions;
+using LiteCharms.Features.Abstractions;
+
+namespace LiteCharms.Features.ServiceBus.Abstractions;
public interface IEventBusQueue
{
diff --git a/LiteCharms.Abstractions/Constants.cs b/LiteCharms.Features/ServiceBus/Constants.cs
similarity index 55%
rename from LiteCharms.Abstractions/Constants.cs
rename to LiteCharms.Features/ServiceBus/Constants.cs
index ae08f94..ff8d4fe 100644
--- a/LiteCharms.Abstractions/Constants.cs
+++ b/LiteCharms.Features/ServiceBus/Constants.cs
@@ -1,13 +1,9 @@
-namespace LiteCharms.Abstractions;
+namespace LiteCharms.Features.ServiceBus;
public static class Constants
{
public const int QueueBounds = 100000;
- public const string ShopSchedulerName = "shop";
- public const string ShopEmailFromName = "Khongisa Shop";
- public const string ShopEmailFromAddress = "shop@litecharms.co.za";
-
public const string EmailServiceBus = nameof(EmailServiceBus);
public const string GeneralServiceBus = nameof(GeneralServiceBus);
public const string SalesServiceBus = nameof(SalesServiceBus);
diff --git a/LiteCharms.Infrastructure/ServiceBus/EmailServiceBus.cs b/LiteCharms.Features/ServiceBus/EmailServiceBus.cs
similarity index 70%
rename from LiteCharms.Infrastructure/ServiceBus/EmailServiceBus.cs
rename to LiteCharms.Features/ServiceBus/EmailServiceBus.cs
index 5205283..c79438e 100644
--- a/LiteCharms.Infrastructure/ServiceBus/EmailServiceBus.cs
+++ b/LiteCharms.Features/ServiceBus/EmailServiceBus.cs
@@ -1,7 +1,8 @@
-using LiteCharms.Abstractions;
-using LiteCharms.Infrastructure.ServiceBus.Queues;
+using LiteCharms.Features.Abstractions;
+using LiteCharms.Features.ServiceBus.Abstractions;
+using LiteCharms.Features.ServiceBus.Queues;
-namespace LiteCharms.Infrastructure.ServiceBus;
+namespace LiteCharms.Features.ServiceBus;
public class EmailServiceBus(EmailQueue messages) : IEventBus
{
diff --git a/LiteCharms.Features/ServiceBus/Exchanges/EmailExchange.cs b/LiteCharms.Features/ServiceBus/Exchanges/EmailExchange.cs
new file mode 100644
index 0000000..5ccae66
--- /dev/null
+++ b/LiteCharms.Features/ServiceBus/Exchanges/EmailExchange.cs
@@ -0,0 +1,33 @@
+using LiteCharms.Features.Abstractions;
+using LiteCharms.Features.ServiceBus.Queues;
+
+namespace LiteCharms.Features.ServiceBus.Exchanges;
+
+public class EmailExchange(EmailQueue messages, ILogger logger, IPublisher mediator) : BackgroundService
+{
+ protected override async Task ExecuteAsync(CancellationToken stoppingToken)
+ {
+ await foreach(IEvent? message in messages.Incoming.ReadAllAsync(stoppingToken))
+ {
+ try
+ {
+ switch (message.Name)
+ {
+ case "SendShopEmailEnquiryEvent":
+ await mediator.Publish(message, stoppingToken);
+ break;
+ case "ProcessEmailNotificationsEvent":
+ await mediator.Publish(message, stoppingToken);
+ break;
+ default:
+ logger.LogWarning("Unsupported email event {Event}", message.Name);
+ break;
+ }
+ }
+ catch (Exception ex)
+ {
+ logger.LogError(ex, ex.Message);
+ }
+ }
+ }
+}
diff --git a/LiteCharms.Infrastructure/ServiceBus/Exchanges/GeneralExchange.cs b/LiteCharms.Features/ServiceBus/Exchanges/GeneralExchange.cs
similarity index 69%
rename from LiteCharms.Infrastructure/ServiceBus/Exchanges/GeneralExchange.cs
rename to LiteCharms.Features/ServiceBus/Exchanges/GeneralExchange.cs
index f21d566..c94fb5d 100644
--- a/LiteCharms.Infrastructure/ServiceBus/Exchanges/GeneralExchange.cs
+++ b/LiteCharms.Features/ServiceBus/Exchanges/GeneralExchange.cs
@@ -1,6 +1,6 @@
-using LiteCharms.Infrastructure.ServiceBus.Queues;
+using LiteCharms.Features.ServiceBus.Queues;
-namespace LiteCharms.Infrastructure.ServiceBus.Exchanges;
+namespace LiteCharms.Features.ServiceBus.Exchanges;
public class GeneralExchange(GeneralQueue messages) : BackgroundService
{
diff --git a/LiteCharms.Infrastructure/ServiceBus/Exchanges/SalesExchange.cs b/LiteCharms.Features/ServiceBus/Exchanges/SalesExchange.cs
similarity index 69%
rename from LiteCharms.Infrastructure/ServiceBus/Exchanges/SalesExchange.cs
rename to LiteCharms.Features/ServiceBus/Exchanges/SalesExchange.cs
index 6288734..645ab49 100644
--- a/LiteCharms.Infrastructure/ServiceBus/Exchanges/SalesExchange.cs
+++ b/LiteCharms.Features/ServiceBus/Exchanges/SalesExchange.cs
@@ -1,6 +1,6 @@
-using LiteCharms.Infrastructure.ServiceBus.Queues;
+using LiteCharms.Features.ServiceBus.Queues;
-namespace LiteCharms.Infrastructure.ServiceBus.Exchanges;
+namespace LiteCharms.Features.ServiceBus.Exchanges;
public class SalesExchange(SalesQueue messages) : BackgroundService
{
diff --git a/LiteCharms.Infrastructure/ServiceBus/GeneralServiceBus.cs b/LiteCharms.Features/ServiceBus/GeneralServiceBus.cs
similarity index 73%
rename from LiteCharms.Infrastructure/ServiceBus/GeneralServiceBus.cs
rename to LiteCharms.Features/ServiceBus/GeneralServiceBus.cs
index 28d6088..94edb37 100644
--- a/LiteCharms.Infrastructure/ServiceBus/GeneralServiceBus.cs
+++ b/LiteCharms.Features/ServiceBus/GeneralServiceBus.cs
@@ -1,7 +1,8 @@
-using LiteCharms.Abstractions;
-using LiteCharms.Infrastructure.ServiceBus.Queues;
+using LiteCharms.Features.Abstractions;
+using LiteCharms.Features.ServiceBus.Abstractions;
+using LiteCharms.Features.ServiceBus.Queues;
-namespace LiteCharms.Infrastructure.ServiceBus;
+namespace LiteCharms.Features.ServiceBus;
public class GeneralServiceBus(GeneralQueue messages) : IEventBus
{
diff --git a/LiteCharms.Features/ServiceBus/Queues/EmailQueue.cs b/LiteCharms.Features/ServiceBus/Queues/EmailQueue.cs
new file mode 100644
index 0000000..508ad5f
--- /dev/null
+++ b/LiteCharms.Features/ServiceBus/Queues/EmailQueue.cs
@@ -0,0 +1,5 @@
+using LiteCharms.Features.ServiceBus.Abstractions;
+
+namespace LiteCharms.Features.ServiceBus.Queues;
+
+public class EmailQueue : EventBusQueueBase, IEventBusQueue;
diff --git a/LiteCharms.Features/ServiceBus/Queues/GeneralQueue.cs b/LiteCharms.Features/ServiceBus/Queues/GeneralQueue.cs
new file mode 100644
index 0000000..3d79a2f
--- /dev/null
+++ b/LiteCharms.Features/ServiceBus/Queues/GeneralQueue.cs
@@ -0,0 +1,5 @@
+using LiteCharms.Features.ServiceBus.Abstractions;
+
+namespace LiteCharms.Features.ServiceBus.Queues;
+
+public class GeneralQueue : EventBusQueueBase, IEventBusQueue;
diff --git a/LiteCharms.Features/ServiceBus/Queues/SalesQueue.cs b/LiteCharms.Features/ServiceBus/Queues/SalesQueue.cs
new file mode 100644
index 0000000..8dc5601
--- /dev/null
+++ b/LiteCharms.Features/ServiceBus/Queues/SalesQueue.cs
@@ -0,0 +1,5 @@
+using LiteCharms.Features.ServiceBus.Abstractions;
+
+namespace LiteCharms.Features.ServiceBus.Queues;
+
+public class SalesQueue : EventBusQueueBase, IEventBusQueue;
diff --git a/LiteCharms.Infrastructure/ServiceBus/SalesServiceBus.cs b/LiteCharms.Features/ServiceBus/SalesServiceBus.cs
similarity index 73%
rename from LiteCharms.Infrastructure/ServiceBus/SalesServiceBus.cs
rename to LiteCharms.Features/ServiceBus/SalesServiceBus.cs
index bb3412c..853657b 100644
--- a/LiteCharms.Infrastructure/ServiceBus/SalesServiceBus.cs
+++ b/LiteCharms.Features/ServiceBus/SalesServiceBus.cs
@@ -1,7 +1,8 @@
-using LiteCharms.Abstractions;
-using LiteCharms.Infrastructure.ServiceBus.Queues;
+using LiteCharms.Features.Abstractions;
+using LiteCharms.Features.ServiceBus.Abstractions;
+using LiteCharms.Features.ServiceBus.Queues;
-namespace LiteCharms.Infrastructure.ServiceBus;
+namespace LiteCharms.Features.ServiceBus;
public class SalesServiceBus(SalesQueue messages) : IEventBus
{
diff --git a/LiteCharms.Features/CartPackages/Commands/AddPackageItemsCommand.cs b/LiteCharms.Features/Shop/CartPackages/Commands/AddPackageItemsCommand.cs
similarity index 100%
rename from LiteCharms.Features/CartPackages/Commands/AddPackageItemsCommand.cs
rename to LiteCharms.Features/Shop/CartPackages/Commands/AddPackageItemsCommand.cs
diff --git a/LiteCharms.Features/CartPackages/Commands/CreatePackageCommand.cs b/LiteCharms.Features/Shop/CartPackages/Commands/CreatePackageCommand.cs
similarity index 100%
rename from LiteCharms.Features/CartPackages/Commands/CreatePackageCommand.cs
rename to LiteCharms.Features/Shop/CartPackages/Commands/CreatePackageCommand.cs
diff --git a/LiteCharms.Features/CartPackages/Commands/DeletePackageCommand.cs b/LiteCharms.Features/Shop/CartPackages/Commands/DeletePackageCommand.cs
similarity index 100%
rename from LiteCharms.Features/CartPackages/Commands/DeletePackageCommand.cs
rename to LiteCharms.Features/Shop/CartPackages/Commands/DeletePackageCommand.cs
diff --git a/LiteCharms.Features/CartPackages/Commands/DeletePackageItemsCommand.cs b/LiteCharms.Features/Shop/CartPackages/Commands/DeletePackageItemsCommand.cs
similarity index 100%
rename from LiteCharms.Features/CartPackages/Commands/DeletePackageItemsCommand.cs
rename to LiteCharms.Features/Shop/CartPackages/Commands/DeletePackageItemsCommand.cs
diff --git a/LiteCharms.Features/CartPackages/Commands/Handlers/AddPackageItemCommandHandler.cs b/LiteCharms.Features/Shop/CartPackages/Commands/Handlers/AddPackageItemCommandHandler.cs
similarity index 97%
rename from LiteCharms.Features/CartPackages/Commands/Handlers/AddPackageItemCommandHandler.cs
rename to LiteCharms.Features/Shop/CartPackages/Commands/Handlers/AddPackageItemCommandHandler.cs
index ffdd24a..71c54f7 100644
--- a/LiteCharms.Features/CartPackages/Commands/Handlers/AddPackageItemCommandHandler.cs
+++ b/LiteCharms.Features/Shop/CartPackages/Commands/Handlers/AddPackageItemCommandHandler.cs
@@ -1,4 +1,4 @@
-using LiteCharms.Infrastructure.Database;
+using LiteCharms.Features.Shop.Postgres;
namespace LiteCharms.Features.CartPackages.Commands.Handlers;
diff --git a/LiteCharms.Features/CartPackages/Commands/Handlers/CreatePackageCommandHandler.cs b/LiteCharms.Features/Shop/CartPackages/Commands/Handlers/CreatePackageCommandHandler.cs
similarity index 96%
rename from LiteCharms.Features/CartPackages/Commands/Handlers/CreatePackageCommandHandler.cs
rename to LiteCharms.Features/Shop/CartPackages/Commands/Handlers/CreatePackageCommandHandler.cs
index 4945a73..ff7847e 100644
--- a/LiteCharms.Features/CartPackages/Commands/Handlers/CreatePackageCommandHandler.cs
+++ b/LiteCharms.Features/Shop/CartPackages/Commands/Handlers/CreatePackageCommandHandler.cs
@@ -1,4 +1,4 @@
-using LiteCharms.Infrastructure.Database;
+using LiteCharms.Features.Shop.Postgres;
namespace LiteCharms.Features.CartPackages.Commands.Handlers;
diff --git a/LiteCharms.Features/CartPackages/Commands/Handlers/DeletePackageItemCommandHandler.cs b/LiteCharms.Features/Shop/CartPackages/Commands/Handlers/DeletePackageItemCommandHandler.cs
similarity index 96%
rename from LiteCharms.Features/CartPackages/Commands/Handlers/DeletePackageItemCommandHandler.cs
rename to LiteCharms.Features/Shop/CartPackages/Commands/Handlers/DeletePackageItemCommandHandler.cs
index 5ec6745..7d7284e 100644
--- a/LiteCharms.Features/CartPackages/Commands/Handlers/DeletePackageItemCommandHandler.cs
+++ b/LiteCharms.Features/Shop/CartPackages/Commands/Handlers/DeletePackageItemCommandHandler.cs
@@ -1,4 +1,4 @@
-using LiteCharms.Infrastructure.Database;
+using LiteCharms.Features.Shop.Postgres;
namespace LiteCharms.Features.CartPackages.Commands.Handlers;
diff --git a/LiteCharms.Features/CartPackages/Commands/Handlers/DeletePackageItemsCommandHandler.cs b/LiteCharms.Features/Shop/CartPackages/Commands/Handlers/DeletePackageItemsCommandHandler.cs
similarity index 96%
rename from LiteCharms.Features/CartPackages/Commands/Handlers/DeletePackageItemsCommandHandler.cs
rename to LiteCharms.Features/Shop/CartPackages/Commands/Handlers/DeletePackageItemsCommandHandler.cs
index 8f4e8e7..bad0e89 100644
--- a/LiteCharms.Features/CartPackages/Commands/Handlers/DeletePackageItemsCommandHandler.cs
+++ b/LiteCharms.Features/Shop/CartPackages/Commands/Handlers/DeletePackageItemsCommandHandler.cs
@@ -1,4 +1,4 @@
-using LiteCharms.Infrastructure.Database;
+using LiteCharms.Features.Shop.Postgres;
namespace LiteCharms.Features.CartPackages.Commands.Handlers;
diff --git a/LiteCharms.Features/CartPackages/Commands/Handlers/UpdatePackageCommandHandler.cs b/LiteCharms.Features/Shop/CartPackages/Commands/Handlers/UpdatePackageCommandHandler.cs
similarity index 96%
rename from LiteCharms.Features/CartPackages/Commands/Handlers/UpdatePackageCommandHandler.cs
rename to LiteCharms.Features/Shop/CartPackages/Commands/Handlers/UpdatePackageCommandHandler.cs
index 7889c52..15945ff 100644
--- a/LiteCharms.Features/CartPackages/Commands/Handlers/UpdatePackageCommandHandler.cs
+++ b/LiteCharms.Features/Shop/CartPackages/Commands/Handlers/UpdatePackageCommandHandler.cs
@@ -1,4 +1,4 @@
-using LiteCharms.Infrastructure.Database;
+using LiteCharms.Features.Shop.Postgres;
namespace LiteCharms.Features.CartPackages.Commands.Handlers;
diff --git a/LiteCharms.Features/CartPackages/Commands/Handlers/UpdatePackageStatusCommandHandler.cs b/LiteCharms.Features/Shop/CartPackages/Commands/Handlers/UpdatePackageStatusCommandHandler.cs
similarity index 95%
rename from LiteCharms.Features/CartPackages/Commands/Handlers/UpdatePackageStatusCommandHandler.cs
rename to LiteCharms.Features/Shop/CartPackages/Commands/Handlers/UpdatePackageStatusCommandHandler.cs
index 5ef4a91..16c6482 100644
--- a/LiteCharms.Features/CartPackages/Commands/Handlers/UpdatePackageStatusCommandHandler.cs
+++ b/LiteCharms.Features/Shop/CartPackages/Commands/Handlers/UpdatePackageStatusCommandHandler.cs
@@ -1,4 +1,4 @@
-using LiteCharms.Infrastructure.Database;
+using LiteCharms.Features.Shop.Postgres;
namespace LiteCharms.Features.CartPackages.Commands.Handlers;
diff --git a/LiteCharms.Features/CartPackages/Commands/UpdatePackageCommand.cs b/LiteCharms.Features/Shop/CartPackages/Commands/UpdatePackageCommand.cs
similarity index 100%
rename from LiteCharms.Features/CartPackages/Commands/UpdatePackageCommand.cs
rename to LiteCharms.Features/Shop/CartPackages/Commands/UpdatePackageCommand.cs
diff --git a/LiteCharms.Features/CartPackages/Commands/UpdatePackageStatusCommand.cs b/LiteCharms.Features/Shop/CartPackages/Commands/UpdatePackageStatusCommand.cs
similarity index 100%
rename from LiteCharms.Features/CartPackages/Commands/UpdatePackageStatusCommand.cs
rename to LiteCharms.Features/Shop/CartPackages/Commands/UpdatePackageStatusCommand.cs
diff --git a/LiteCharms.Entities/Package.cs b/LiteCharms.Features/Shop/CartPackages/Entities/Package.cs
similarity index 69%
rename from LiteCharms.Entities/Package.cs
rename to LiteCharms.Features/Shop/CartPackages/Entities/Package.cs
index ce8e799..3e4d210 100644
--- a/LiteCharms.Entities/Package.cs
+++ b/LiteCharms.Features/Shop/CartPackages/Entities/Package.cs
@@ -1,6 +1,4 @@
-using LiteCharms.Entities.Configuration;
-
-namespace LiteCharms.Entities;
+namespace LiteCharms.Features.Shop.CartPackages.Entities;
[EntityTypeConfiguration]
public class Package : Models.Package
diff --git a/LiteCharms.Features/Shop/CartPackages/Entities/PackageConfirguration.cs b/LiteCharms.Features/Shop/CartPackages/Entities/PackageConfirguration.cs
new file mode 100644
index 0000000..e6ff029
--- /dev/null
+++ b/LiteCharms.Features/Shop/CartPackages/Entities/PackageConfirguration.cs
@@ -0,0 +1,18 @@
+namespace LiteCharms.Features.Shop.CartPackages.Entities;
+
+public class PackageConfirguration : IEntityTypeConfiguration
+{
+ public void Configure(EntityTypeBuilder builder)
+ {
+ builder.ToTable(nameof(Package));
+
+ builder.HasKey(f => f.Id);
+ builder.Property(f => f.CreatedAt).IsRequired().ValueGeneratedOnAdd().HasDefaultValueSql("now()");
+ builder.Property(f => f.UpdatedAt).IsRequired(false);
+ builder.Property(f => f.Name).IsRequired();
+ builder.Property(f => f.Summary).IsRequired().HasMaxLength(512);
+ builder.Property(f => f.Description).IsRequired().HasMaxLength(2048);
+ builder.Property(f => f.ImageUrl).IsRequired(false).HasMaxLength(2048);
+ builder.Property(f => f.Active);
+ }
+}
diff --git a/LiteCharms.Features/Shop/CartPackages/Entities/PackageItem.cs b/LiteCharms.Features/Shop/CartPackages/Entities/PackageItem.cs
new file mode 100644
index 0000000..306975e
--- /dev/null
+++ b/LiteCharms.Features/Shop/CartPackages/Entities/PackageItem.cs
@@ -0,0 +1,11 @@
+using LiteCharms.Features.Shop.Products.Entities;
+
+namespace LiteCharms.Features.Shop.CartPackages.Entities;
+
+[EntityTypeConfiguration]
+public class PackageItem : Models.PackageItem
+{
+ public virtual Package? Package { get; set; }
+
+ public virtual ProductPrice? ProductPrice { get; set; }
+}
diff --git a/LiteCharms.Entities/Configuration/PackageItemConfiguration.cs b/LiteCharms.Features/Shop/CartPackages/Entities/PackageItemConfiguration.cs
similarity index 51%
rename from LiteCharms.Entities/Configuration/PackageItemConfiguration.cs
rename to LiteCharms.Features/Shop/CartPackages/Entities/PackageItemConfiguration.cs
index bf31659..c6f1009 100644
--- a/LiteCharms.Entities/Configuration/PackageItemConfiguration.cs
+++ b/LiteCharms.Features/Shop/CartPackages/Entities/PackageItemConfiguration.cs
@@ -1,4 +1,4 @@
-namespace LiteCharms.Entities.Configuration;
+namespace LiteCharms.Features.Shop.CartPackages.Entities;
public class PackageItemConfiguration : IEntityTypeConfiguration
{
@@ -7,14 +7,21 @@ public class PackageItemConfiguration : IEntityTypeConfiguration
builder.ToTable(nameof(PackageItem));
builder.HasKey(f => f.Id);
- builder.Property(f => f.CreatedAt).IsRequired().ValueGeneratedOnAdd();
+ builder.Property(f => f.CreatedAt).IsRequired().ValueGeneratedOnAdd().HasDefaultValueSql("now()");
builder.Property(f => f.PackageId).IsRequired();
builder.Property(f => f.ProductPriceId).IsRequired();
builder.Property(f => f.Active);
builder.HasOne(f => f.Package)
- .WithMany()
- .HasForeignKey(f => f.PackageId)
- .OnDelete(DeleteBehavior.NoAction);
+ .WithMany(f => f.PackageItems)
+ .HasForeignKey(pi => pi.PackageId)
+ .IsRequired()
+ .OnDelete(DeleteBehavior.Cascade);
+
+ builder.HasOne(f => f.ProductPrice)
+ .WithMany()
+ .HasForeignKey(pi => pi.ProductPriceId)
+ .IsRequired()
+ .OnDelete(DeleteBehavior.Restrict);
}
}
diff --git a/LiteCharms.Models/Package.cs b/LiteCharms.Features/Shop/CartPackages/Models/Package.cs
similarity index 66%
rename from LiteCharms.Models/Package.cs
rename to LiteCharms.Features/Shop/CartPackages/Models/Package.cs
index cfc0feb..fcc560b 100644
--- a/LiteCharms.Models/Package.cs
+++ b/LiteCharms.Features/Shop/CartPackages/Models/Package.cs
@@ -1,4 +1,4 @@
-namespace LiteCharms.Models;
+namespace LiteCharms.Features.Shop.CartPackages.Models;
public class Package
{
@@ -10,7 +10,11 @@ public class Package
public string? Name { get; set; }
+ public string? Summary { get; set; }
+
public string? Description { get; set; }
+ public string? ImageUrl { get; set; }
+
public bool Active { get; set; }
}
diff --git a/LiteCharms.Models/PackageItem.cs b/LiteCharms.Features/Shop/CartPackages/Models/PackageItem.cs
similarity index 80%
rename from LiteCharms.Models/PackageItem.cs
rename to LiteCharms.Features/Shop/CartPackages/Models/PackageItem.cs
index 2c27ad3..ff81c0a 100644
--- a/LiteCharms.Models/PackageItem.cs
+++ b/LiteCharms.Features/Shop/CartPackages/Models/PackageItem.cs
@@ -1,4 +1,4 @@
-namespace LiteCharms.Models;
+namespace LiteCharms.Features.Shop.CartPackages.Models;
public class PackageItem
{
diff --git a/LiteCharms.Features/CartPackages/Queries/GetPackageItemsQuery.cs b/LiteCharms.Features/Shop/CartPackages/Queries/GetPackageItemsQuery.cs
similarity index 89%
rename from LiteCharms.Features/CartPackages/Queries/GetPackageItemsQuery.cs
rename to LiteCharms.Features/Shop/CartPackages/Queries/GetPackageItemsQuery.cs
index e0830af..3315726 100644
--- a/LiteCharms.Features/CartPackages/Queries/GetPackageItemsQuery.cs
+++ b/LiteCharms.Features/Shop/CartPackages/Queries/GetPackageItemsQuery.cs
@@ -1,4 +1,4 @@
-using LiteCharms.Models;
+using LiteCharms.Features.Shop.CartPackages.Models;
namespace LiteCharms.Features.CartPackages.Queries;
diff --git a/LiteCharms.Features/CartPackages/Queries/GetPackageQuery.cs b/LiteCharms.Features/Shop/CartPackages/Queries/GetPackageQuery.cs
similarity index 89%
rename from LiteCharms.Features/CartPackages/Queries/GetPackageQuery.cs
rename to LiteCharms.Features/Shop/CartPackages/Queries/GetPackageQuery.cs
index 1384783..a05264e 100644
--- a/LiteCharms.Features/CartPackages/Queries/GetPackageQuery.cs
+++ b/LiteCharms.Features/Shop/CartPackages/Queries/GetPackageQuery.cs
@@ -1,4 +1,4 @@
-using LiteCharms.Models;
+using LiteCharms.Features.Shop.CartPackages.Models;
namespace LiteCharms.Features.CartPackages.Queries;
diff --git a/LiteCharms.Features/CartPackages/Queries/GetPackagesQuery.cs b/LiteCharms.Features/Shop/CartPackages/Queries/GetPackagesQuery.cs
similarity index 94%
rename from LiteCharms.Features/CartPackages/Queries/GetPackagesQuery.cs
rename to LiteCharms.Features/Shop/CartPackages/Queries/GetPackagesQuery.cs
index 351a141..036ff09 100644
--- a/LiteCharms.Features/CartPackages/Queries/GetPackagesQuery.cs
+++ b/LiteCharms.Features/Shop/CartPackages/Queries/GetPackagesQuery.cs
@@ -1,4 +1,4 @@
-using LiteCharms.Models;
+using LiteCharms.Features.Shop.CartPackages.Models;
namespace LiteCharms.Features.CartPackages.Queries;
diff --git a/LiteCharms.Features/CartPackages/Queries/Handlers/GetPackageItemsQueryHandler.cs b/LiteCharms.Features/Shop/CartPackages/Queries/Handlers/GetPackageItemsQueryHandler.cs
similarity index 93%
rename from LiteCharms.Features/CartPackages/Queries/Handlers/GetPackageItemsQueryHandler.cs
rename to LiteCharms.Features/Shop/CartPackages/Queries/Handlers/GetPackageItemsQueryHandler.cs
index 487b203..3b19cdc 100644
--- a/LiteCharms.Features/CartPackages/Queries/Handlers/GetPackageItemsQueryHandler.cs
+++ b/LiteCharms.Features/Shop/CartPackages/Queries/Handlers/GetPackageItemsQueryHandler.cs
@@ -1,6 +1,6 @@
using LiteCharms.Extensions;
-using LiteCharms.Infrastructure.Database;
-using LiteCharms.Models;
+using LiteCharms.Features.Shop.CartPackages.Models;
+using LiteCharms.Features.Shop.Postgres;
namespace LiteCharms.Features.CartPackages.Queries.Handlers;
diff --git a/LiteCharms.Features/CartPackages/Queries/Handlers/GetPackageQueryHandler.cs b/LiteCharms.Features/Shop/CartPackages/Queries/Handlers/GetPackageQueryHandler.cs
similarity index 90%
rename from LiteCharms.Features/CartPackages/Queries/Handlers/GetPackageQueryHandler.cs
rename to LiteCharms.Features/Shop/CartPackages/Queries/Handlers/GetPackageQueryHandler.cs
index 7a01fb5..d822584 100644
--- a/LiteCharms.Features/CartPackages/Queries/Handlers/GetPackageQueryHandler.cs
+++ b/LiteCharms.Features/Shop/CartPackages/Queries/Handlers/GetPackageQueryHandler.cs
@@ -1,6 +1,6 @@
using LiteCharms.Extensions;
-using LiteCharms.Infrastructure.Database;
-using LiteCharms.Models;
+using LiteCharms.Features.Shop.CartPackages.Models;
+using LiteCharms.Features.Shop.Postgres;
namespace LiteCharms.Features.CartPackages.Queries.Handlers;
diff --git a/LiteCharms.Features/CartPackages/Queries/Handlers/GetPackagesQueryHandler.cs b/LiteCharms.Features/Shop/CartPackages/Queries/Handlers/GetPackagesQueryHandler.cs
similarity index 93%
rename from LiteCharms.Features/CartPackages/Queries/Handlers/GetPackagesQueryHandler.cs
rename to LiteCharms.Features/Shop/CartPackages/Queries/Handlers/GetPackagesQueryHandler.cs
index b495bb0..1ef691f 100644
--- a/LiteCharms.Features/CartPackages/Queries/Handlers/GetPackagesQueryHandler.cs
+++ b/LiteCharms.Features/Shop/CartPackages/Queries/Handlers/GetPackagesQueryHandler.cs
@@ -1,6 +1,6 @@
using LiteCharms.Extensions;
-using LiteCharms.Infrastructure.Database;
-using LiteCharms.Models;
+using LiteCharms.Features.Shop.CartPackages.Models;
+using LiteCharms.Features.Shop.Postgres;
namespace LiteCharms.Features.CartPackages.Queries.Handlers;
diff --git a/LiteCharms.Features/Customers/Commands/CreateCustomerCommand.cs b/LiteCharms.Features/Shop/Customers/Commands/CreateCustomerCommand.cs
similarity index 100%
rename from LiteCharms.Features/Customers/Commands/CreateCustomerCommand.cs
rename to LiteCharms.Features/Shop/Customers/Commands/CreateCustomerCommand.cs
diff --git a/LiteCharms.Features/Customers/Commands/Handlers/CreateCustomerCommandHandler.cs b/LiteCharms.Features/Shop/Customers/Commands/Handlers/CreateCustomerCommandHandler.cs
similarity index 97%
rename from LiteCharms.Features/Customers/Commands/Handlers/CreateCustomerCommandHandler.cs
rename to LiteCharms.Features/Shop/Customers/Commands/Handlers/CreateCustomerCommandHandler.cs
index 82f836b..bf1a5d6 100644
--- a/LiteCharms.Features/Customers/Commands/Handlers/CreateCustomerCommandHandler.cs
+++ b/LiteCharms.Features/Shop/Customers/Commands/Handlers/CreateCustomerCommandHandler.cs
@@ -1,4 +1,4 @@
-using LiteCharms.Infrastructure.Database;
+using LiteCharms.Features.Shop.Postgres;
namespace LiteCharms.Features.Customers.Commands.Handlers;
diff --git a/LiteCharms.Features/Customers/Commands/Handlers/UpdateCustomerCommandHandler.cs b/LiteCharms.Features/Shop/Customers/Commands/Handlers/UpdateCustomerCommandHandler.cs
similarity index 97%
rename from LiteCharms.Features/Customers/Commands/Handlers/UpdateCustomerCommandHandler.cs
rename to LiteCharms.Features/Shop/Customers/Commands/Handlers/UpdateCustomerCommandHandler.cs
index 72b9109..031f591 100644
--- a/LiteCharms.Features/Customers/Commands/Handlers/UpdateCustomerCommandHandler.cs
+++ b/LiteCharms.Features/Shop/Customers/Commands/Handlers/UpdateCustomerCommandHandler.cs
@@ -1,4 +1,4 @@
-using LiteCharms.Infrastructure.Database;
+using LiteCharms.Features.Shop.Postgres;
namespace LiteCharms.Features.Customers.Commands.Handlers;
diff --git a/LiteCharms.Features/Customers/Commands/UpdateCustomerCommand.cs b/LiteCharms.Features/Shop/Customers/Commands/UpdateCustomerCommand.cs
similarity index 100%
rename from LiteCharms.Features/Customers/Commands/UpdateCustomerCommand.cs
rename to LiteCharms.Features/Shop/Customers/Commands/UpdateCustomerCommand.cs
diff --git a/LiteCharms.Entities/Customer.cs b/LiteCharms.Features/Shop/Customers/Entities/Customer.cs
similarity index 58%
rename from LiteCharms.Entities/Customer.cs
rename to LiteCharms.Features/Shop/Customers/Entities/Customer.cs
index bd3bf40..7b78bc8 100644
--- a/LiteCharms.Entities/Customer.cs
+++ b/LiteCharms.Features/Shop/Customers/Entities/Customer.cs
@@ -1,6 +1,9 @@
-using LiteCharms.Entities.Configuration;
+using LiteCharms.Features.Shop.Leads.Entities;
+using LiteCharms.Features.Shop.Orders.Entities;
+using LiteCharms.Features.Shop.Quotes.Entities;
+using LiteCharms.Features.Shop.ShoppingCarts.Entities;
-namespace LiteCharms.Entities;
+namespace LiteCharms.Features.Shop.Customers.Entities;
[EntityTypeConfiguration]
public class Customer : Models.Customer
diff --git a/LiteCharms.Entities/Configuration/CustomerConfiguration.cs b/LiteCharms.Features/Shop/Customers/Entities/CustomerConfiguration.cs
similarity index 77%
rename from LiteCharms.Entities/Configuration/CustomerConfiguration.cs
rename to LiteCharms.Features/Shop/Customers/Entities/CustomerConfiguration.cs
index 9792251..335c1b0 100644
--- a/LiteCharms.Entities/Configuration/CustomerConfiguration.cs
+++ b/LiteCharms.Features/Shop/Customers/Entities/CustomerConfiguration.cs
@@ -1,4 +1,4 @@
-namespace LiteCharms.Entities.Configuration;
+namespace LiteCharms.Features.Shop.Customers.Entities;
public class CustomerConfiguration : IEntityTypeConfiguration
{
@@ -7,8 +7,8 @@ public class CustomerConfiguration : IEntityTypeConfiguration
builder.ToTable(nameof(Customer));
builder.HasKey(f => f.Id);
- builder.Property(f => f.CreatedAt).ValueGeneratedOnAdd();
- builder.Property(f => f.UpdatedAt).IsRequired(false).ValueGeneratedOnUpdate();
+ builder.Property(f => f.CreatedAt).ValueGeneratedOnAdd().HasDefaultValueSql("now()");
+ builder.Property(f => f.UpdatedAt).IsRequired(false);
builder.Property(f => f.Company);
builder.Property(f => f.Name).IsRequired();
builder.Property(f => f.LastName).IsRequired();
@@ -26,10 +26,5 @@ public class CustomerConfiguration : IEntityTypeConfiguration
builder.Property(f => f.Country);
builder.Property(f => f.PostalCode);
builder.Property(f => f.Active).HasDefaultValue(true);
-
- builder.HasMany(f => f.Leads)
- .WithOne(f => f.Customer)
- .HasForeignKey(f => f.CustomerId)
- .OnDelete(DeleteBehavior.NoAction);
}
}
\ No newline at end of file
diff --git a/LiteCharms.Models/Customer.cs b/LiteCharms.Features/Shop/Customers/Models/Customer.cs
similarity index 93%
rename from LiteCharms.Models/Customer.cs
rename to LiteCharms.Features/Shop/Customers/Models/Customer.cs
index b322f8a..14387f6 100644
--- a/LiteCharms.Models/Customer.cs
+++ b/LiteCharms.Features/Shop/Customers/Models/Customer.cs
@@ -1,4 +1,4 @@
-namespace LiteCharms.Models;
+namespace LiteCharms.Features.Shop.Customers.Models;
public class Customer
{
diff --git a/LiteCharms.Features/Customers/Queries/GetCustomerQuery.cs b/LiteCharms.Features/Shop/Customers/Queries/GetCustomerQuery.cs
similarity index 89%
rename from LiteCharms.Features/Customers/Queries/GetCustomerQuery.cs
rename to LiteCharms.Features/Shop/Customers/Queries/GetCustomerQuery.cs
index 5ea7394..c6ee4b0 100644
--- a/LiteCharms.Features/Customers/Queries/GetCustomerQuery.cs
+++ b/LiteCharms.Features/Shop/Customers/Queries/GetCustomerQuery.cs
@@ -1,4 +1,4 @@
-using LiteCharms.Models;
+using LiteCharms.Features.Shop.Customers.Models;
namespace LiteCharms.Features.Customers.Queries;
diff --git a/LiteCharms.Features/Customers/Queries/GetCustomersQuery.cs b/LiteCharms.Features/Shop/Customers/Queries/GetCustomersQuery.cs
similarity index 93%
rename from LiteCharms.Features/Customers/Queries/GetCustomersQuery.cs
rename to LiteCharms.Features/Shop/Customers/Queries/GetCustomersQuery.cs
index 3f271b3..9c830b4 100644
--- a/LiteCharms.Features/Customers/Queries/GetCustomersQuery.cs
+++ b/LiteCharms.Features/Shop/Customers/Queries/GetCustomersQuery.cs
@@ -1,4 +1,4 @@
-using LiteCharms.Models;
+using LiteCharms.Features.Shop.Customers.Models;
namespace LiteCharms.Features.Customers.Queries;
diff --git a/LiteCharms.Features/Customers/Queries/Handlers/GetCustomerQueryHandler.cs b/LiteCharms.Features/Shop/Customers/Queries/Handlers/GetCustomerQueryHandler.cs
similarity index 90%
rename from LiteCharms.Features/Customers/Queries/Handlers/GetCustomerQueryHandler.cs
rename to LiteCharms.Features/Shop/Customers/Queries/Handlers/GetCustomerQueryHandler.cs
index 0f921db..cbe478d 100644
--- a/LiteCharms.Features/Customers/Queries/Handlers/GetCustomerQueryHandler.cs
+++ b/LiteCharms.Features/Shop/Customers/Queries/Handlers/GetCustomerQueryHandler.cs
@@ -1,6 +1,6 @@
using LiteCharms.Extensions;
-using LiteCharms.Infrastructure.Database;
-using LiteCharms.Models;
+using LiteCharms.Features.Shop.Customers.Models;
+using LiteCharms.Features.Shop.Postgres;
namespace LiteCharms.Features.Customers.Queries.Handlers;
diff --git a/LiteCharms.Features/Customers/Queries/Handlers/GetCustomersQueryHandler.cs b/LiteCharms.Features/Shop/Customers/Queries/Handlers/GetCustomersQueryHandler.cs
similarity index 93%
rename from LiteCharms.Features/Customers/Queries/Handlers/GetCustomersQueryHandler.cs
rename to LiteCharms.Features/Shop/Customers/Queries/Handlers/GetCustomersQueryHandler.cs
index 960ef3a..b9d1e99 100644
--- a/LiteCharms.Features/Customers/Queries/Handlers/GetCustomersQueryHandler.cs
+++ b/LiteCharms.Features/Shop/Customers/Queries/Handlers/GetCustomersQueryHandler.cs
@@ -1,6 +1,6 @@
using LiteCharms.Extensions;
-using LiteCharms.Infrastructure.Database;
-using LiteCharms.Models;
+using LiteCharms.Features.Shop.Customers.Models;
+using LiteCharms.Features.Shop.Postgres;
namespace LiteCharms.Features.Customers.Queries.Handlers;
diff --git a/LiteCharms.Models/Enums.cs b/LiteCharms.Features/Shop/Enums.cs
similarity index 76%
rename from LiteCharms.Models/Enums.cs
rename to LiteCharms.Features/Shop/Enums.cs
index b672e25..6f25546 100644
--- a/LiteCharms.Models/Enums.cs
+++ b/LiteCharms.Features/Shop/Enums.cs
@@ -1,4 +1,16 @@
-namespace LiteCharms.Models;
+namespace LiteCharms.Features.Shop;
+
+public enum EmailStatuses : int
+{
+ GeneralError = 0,
+ AuthenticationError = 1,
+ ProtocolError = 2,
+ Connected = 3,
+ Disconnected = 4,
+ TooManyConnections = 5,
+ ConnectionAborted = 6,
+ Success = 7
+}
public enum CorrelationIdTypes : int
{
@@ -17,7 +29,7 @@ public enum CorrelationIdTypes : int
public enum Priorities : int
{
- Low = 0,
+ Low = 0,
Medium = 1,
High = 2,
}
@@ -66,3 +78,4 @@ public enum NotificationDirection : int
Outgoing = 1,
Neutral = 2
}
+
diff --git a/LiteCharms.Features/Leads/Commands/CreateLeadCommand.cs b/LiteCharms.Features/Shop/Leads/Commands/CreateLeadCommand.cs
similarity index 100%
rename from LiteCharms.Features/Leads/Commands/CreateLeadCommand.cs
rename to LiteCharms.Features/Shop/Leads/Commands/CreateLeadCommand.cs
diff --git a/LiteCharms.Features/Leads/Commands/Handlers/CreateLeadCommandHandler.cs b/LiteCharms.Features/Shop/Leads/Commands/Handlers/CreateLeadCommandHandler.cs
similarity index 95%
rename from LiteCharms.Features/Leads/Commands/Handlers/CreateLeadCommandHandler.cs
rename to LiteCharms.Features/Shop/Leads/Commands/Handlers/CreateLeadCommandHandler.cs
index 256bc22..a51d31a 100644
--- a/LiteCharms.Features/Leads/Commands/Handlers/CreateLeadCommandHandler.cs
+++ b/LiteCharms.Features/Shop/Leads/Commands/Handlers/CreateLeadCommandHandler.cs
@@ -1,5 +1,5 @@
-using LiteCharms.Features.Utilities.Hash.Commands;
-using LiteCharms.Infrastructure.Database;
+using LiteCharms.Features.Shop.Postgres;
+using LiteCharms.Features.Utilities.Hash.Commands;
namespace LiteCharms.Features.Leads.Commands.Handlers;
diff --git a/LiteCharms.Features/Leads/Commands/Handlers/UpdateLeadCommandHandler.cs b/LiteCharms.Features/Shop/Leads/Commands/Handlers/UpdateLeadCommandHandler.cs
similarity index 95%
rename from LiteCharms.Features/Leads/Commands/Handlers/UpdateLeadCommandHandler.cs
rename to LiteCharms.Features/Shop/Leads/Commands/Handlers/UpdateLeadCommandHandler.cs
index afaa15c..67f14fc 100644
--- a/LiteCharms.Features/Leads/Commands/Handlers/UpdateLeadCommandHandler.cs
+++ b/LiteCharms.Features/Shop/Leads/Commands/Handlers/UpdateLeadCommandHandler.cs
@@ -1,4 +1,4 @@
-using LiteCharms.Infrastructure.Database;
+using LiteCharms.Features.Shop.Postgres;
namespace LiteCharms.Features.Leads.Commands.Handlers;
diff --git a/LiteCharms.Features/Leads/Commands/UpdateLeadCommand.cs b/LiteCharms.Features/Shop/Leads/Commands/UpdateLeadCommand.cs
similarity index 92%
rename from LiteCharms.Features/Leads/Commands/UpdateLeadCommand.cs
rename to LiteCharms.Features/Shop/Leads/Commands/UpdateLeadCommand.cs
index a201b70..ef31b01 100644
--- a/LiteCharms.Features/Leads/Commands/UpdateLeadCommand.cs
+++ b/LiteCharms.Features/Shop/Leads/Commands/UpdateLeadCommand.cs
@@ -1,4 +1,5 @@
-using LiteCharms.Models;
+using LiteCharms.Features.Shop;
+using LiteCharms.Models;
namespace LiteCharms.Features.Leads.Commands;
diff --git a/LiteCharms.Entities/Lead.cs b/LiteCharms.Features/Shop/Leads/Entities/Lead.cs
similarity index 57%
rename from LiteCharms.Entities/Lead.cs
rename to LiteCharms.Features/Shop/Leads/Entities/Lead.cs
index b1bdf62..deda2d6 100644
--- a/LiteCharms.Entities/Lead.cs
+++ b/LiteCharms.Features/Shop/Leads/Entities/Lead.cs
@@ -1,6 +1,6 @@
-using LiteCharms.Entities.Configuration;
+using LiteCharms.Features.Shop.Customers.Models;
-namespace LiteCharms.Entities;
+namespace LiteCharms.Features.Shop.Leads.Entities;
[EntityTypeConfiguration]
public class Lead : Models.Lead
diff --git a/LiteCharms.Entities/Configuration/LeadConfiguration.cs b/LiteCharms.Features/Shop/Leads/Entities/LeadConfiguration.cs
similarity index 86%
rename from LiteCharms.Entities/Configuration/LeadConfiguration.cs
rename to LiteCharms.Features/Shop/Leads/Entities/LeadConfiguration.cs
index 8c8d004..482677c 100644
--- a/LiteCharms.Entities/Configuration/LeadConfiguration.cs
+++ b/LiteCharms.Features/Shop/Leads/Entities/LeadConfiguration.cs
@@ -1,4 +1,4 @@
-namespace LiteCharms.Entities.Configuration;
+namespace LiteCharms.Features.Shop.Leads.Entities;
public class LeadConfiguration : IEntityTypeConfiguration
{
@@ -7,8 +7,8 @@ public class LeadConfiguration : IEntityTypeConfiguration
builder.ToTable(nameof(Lead));
builder.HasKey(f => f.Id);
- builder.Property(f => f.CreatedAt).ValueGeneratedOnAdd();
- builder.Property(f => f.UpdatedAt).IsRequired(false).ValueGeneratedOnUpdate();
+ builder.Property(f => f.CreatedAt).ValueGeneratedOnAdd().HasDefaultValueSql("now()");
+ builder.Property(f => f.UpdatedAt).IsRequired(false);
builder.Property(f => f.CustomerId).IsRequired(false);
builder.Property(f => f.Source);
builder.Property(f => f.ClickId);
diff --git a/LiteCharms.Models/Lead.cs b/LiteCharms.Features/Shop/Leads/Models/Lead.cs
similarity index 93%
rename from LiteCharms.Models/Lead.cs
rename to LiteCharms.Features/Shop/Leads/Models/Lead.cs
index 5222114..0cb9fa1 100644
--- a/LiteCharms.Models/Lead.cs
+++ b/LiteCharms.Features/Shop/Leads/Models/Lead.cs
@@ -1,4 +1,4 @@
-namespace LiteCharms.Models;
+namespace LiteCharms.Features.Shop.Leads.Models;
public class Lead
{
diff --git a/LiteCharms.Features/Leads/Queries/GetCustomerLeadsQuery.cs b/LiteCharms.Features/Shop/Leads/Queries/GetCustomerLeadsQuery.cs
similarity index 94%
rename from LiteCharms.Features/Leads/Queries/GetCustomerLeadsQuery.cs
rename to LiteCharms.Features/Shop/Leads/Queries/GetCustomerLeadsQuery.cs
index ddede3c..de53634 100644
--- a/LiteCharms.Features/Leads/Queries/GetCustomerLeadsQuery.cs
+++ b/LiteCharms.Features/Shop/Leads/Queries/GetCustomerLeadsQuery.cs
@@ -1,4 +1,4 @@
-using LiteCharms.Models;
+using LiteCharms.Features.Shop.Leads.Models;
namespace LiteCharms.Features.Leads.Queries;
diff --git a/LiteCharms.Features/Leads/Queries/GetLeadsQuery.cs b/LiteCharms.Features/Shop/Leads/Queries/GetLeadsQuery.cs
similarity index 93%
rename from LiteCharms.Features/Leads/Queries/GetLeadsQuery.cs
rename to LiteCharms.Features/Shop/Leads/Queries/GetLeadsQuery.cs
index 3278bf7..d280e65 100644
--- a/LiteCharms.Features/Leads/Queries/GetLeadsQuery.cs
+++ b/LiteCharms.Features/Shop/Leads/Queries/GetLeadsQuery.cs
@@ -1,4 +1,4 @@
-using LiteCharms.Models;
+using LiteCharms.Features.Shop.Leads.Models;
namespace LiteCharms.Features.Leads.Queries;
diff --git a/LiteCharms.Features/Leads/Queries/Handlers/GetCustomerLeadsQueryHandler.cs b/LiteCharms.Features/Shop/Leads/Queries/Handlers/GetCustomerLeadsQueryHandler.cs
similarity index 93%
rename from LiteCharms.Features/Leads/Queries/Handlers/GetCustomerLeadsQueryHandler.cs
rename to LiteCharms.Features/Shop/Leads/Queries/Handlers/GetCustomerLeadsQueryHandler.cs
index ed90212..dd9ba15 100644
--- a/LiteCharms.Features/Leads/Queries/Handlers/GetCustomerLeadsQueryHandler.cs
+++ b/LiteCharms.Features/Shop/Leads/Queries/Handlers/GetCustomerLeadsQueryHandler.cs
@@ -1,6 +1,6 @@
using LiteCharms.Extensions;
-using LiteCharms.Infrastructure.Database;
-using LiteCharms.Models;
+using LiteCharms.Features.Shop.Leads.Models;
+using LiteCharms.Features.Shop.Postgres;
namespace LiteCharms.Features.Leads.Queries.Handlers;
diff --git a/LiteCharms.Features/Leads/Queries/Handlers/GetLeadsQueryHandler.cs b/LiteCharms.Features/Shop/Leads/Queries/Handlers/GetLeadsQueryHandler.cs
similarity index 93%
rename from LiteCharms.Features/Leads/Queries/Handlers/GetLeadsQueryHandler.cs
rename to LiteCharms.Features/Shop/Leads/Queries/Handlers/GetLeadsQueryHandler.cs
index 0ebaafb..417ff5c 100644
--- a/LiteCharms.Features/Leads/Queries/Handlers/GetLeadsQueryHandler.cs
+++ b/LiteCharms.Features/Shop/Leads/Queries/Handlers/GetLeadsQueryHandler.cs
@@ -1,6 +1,6 @@
using LiteCharms.Extensions;
-using LiteCharms.Infrastructure.Database;
-using LiteCharms.Models;
+using LiteCharms.Features.Shop.Leads.Models;
+using LiteCharms.Features.Shop.Postgres;
namespace LiteCharms.Features.Leads.Queries.Handlers;
diff --git a/LiteCharms.Features/Notifications/Commands/CreateNotificationCommand.cs b/LiteCharms.Features/Shop/Notifications/Commands/CreateNotificationCommand.cs
similarity index 73%
rename from LiteCharms.Features/Notifications/Commands/CreateNotificationCommand.cs
rename to LiteCharms.Features/Shop/Notifications/Commands/CreateNotificationCommand.cs
index 2b3e933..59e69d6 100644
--- a/LiteCharms.Features/Notifications/Commands/CreateNotificationCommand.cs
+++ b/LiteCharms.Features/Shop/Notifications/Commands/CreateNotificationCommand.cs
@@ -1,8 +1,9 @@
-using LiteCharms.Models;
+using LiteCharms.Features.Shop;
+using LiteCharms.Models;
namespace LiteCharms.Features.Notifications.Commands;
-public class CreateNotificationCommand : IRequest>
+public class CreateNotification : IRequest>
{
public NotificationDirection Direction { get; set; }
@@ -30,7 +31,7 @@ public class CreateNotificationCommand : IRequest>
public bool IsHtml { get; set; }
- private CreateNotificationCommand(NotificationDirection direction, string sender, string senderAddress, string subject, string message, NotificationPlatforms platform, Priorities priority, string recipient, string recipientAddress, string correlationId, CorrelationIdTypes correlationIdType, bool isInternal, bool isHtml = false)
+ private CreateNotification(NotificationDirection direction, string sender, string senderAddress, string subject, string message, NotificationPlatforms platform, Priorities priority, string recipient, string recipientAddress, string correlationId, CorrelationIdTypes correlationIdType, bool isInternal, bool isHtml = false)
{
Direction = direction;
Sender = sender;
@@ -47,7 +48,7 @@ public class CreateNotificationCommand : IRequest>
IsHtml = isHtml;
}
- public static CreateNotificationCommand Create(NotificationDirection direction, string sender, string senderAddress, string subject, string message, NotificationPlatforms platform, Priorities priority, string recipient, string recipientAddress, string correlationId, CorrelationIdTypes correlationIdType, bool isInternal, bool isHtml = false)
+ public static CreateNotification Create(NotificationDirection direction, string sender, string senderAddress, string subject, string message, NotificationPlatforms platform, Priorities priority, string recipient, string recipientAddress, string correlationId, CorrelationIdTypes correlationIdType, bool isInternal, bool isHtml = false)
{
if (string.IsNullOrWhiteSpace(sender))
throw new ArgumentException("Sender name is required.", nameof(sender));
diff --git a/LiteCharms.Features/Notifications/Commands/Handlers/CreateNotificationCommandHandler.cs b/LiteCharms.Features/Shop/Notifications/Commands/Handlers/CreateNotificationCommandHandler.cs
similarity index 92%
rename from LiteCharms.Features/Notifications/Commands/Handlers/CreateNotificationCommandHandler.cs
rename to LiteCharms.Features/Shop/Notifications/Commands/Handlers/CreateNotificationCommandHandler.cs
index e7a3fb4..facd9a3 100644
--- a/LiteCharms.Features/Notifications/Commands/Handlers/CreateNotificationCommandHandler.cs
+++ b/LiteCharms.Features/Shop/Notifications/Commands/Handlers/CreateNotificationCommandHandler.cs
@@ -1,10 +1,10 @@
-using LiteCharms.Infrastructure.Database;
+using LiteCharms.Features.Shop.Postgres;
namespace LiteCharms.Features.Notifications.Commands.Handlers;
-public class CreateNotificationCommandHandler(IDbContextFactory contextFactory) : IRequestHandler>
+public class CreateNotificationCommandHandler(IDbContextFactory contextFactory) : IRequestHandler>
{
- public async ValueTask> Handle(CreateNotificationCommand request, CancellationToken cancellationToken)
+ public async ValueTask> Handle(CreateNotification request, CancellationToken cancellationToken)
{
try
{
diff --git a/LiteCharms.Features/Notifications/Commands/Handlers/UpdateNotificationCommandHandler.cs b/LiteCharms.Features/Shop/Notifications/Commands/Handlers/UpdateNotificationCommandHandler.cs
similarity index 96%
rename from LiteCharms.Features/Notifications/Commands/Handlers/UpdateNotificationCommandHandler.cs
rename to LiteCharms.Features/Shop/Notifications/Commands/Handlers/UpdateNotificationCommandHandler.cs
index 5ce4e81..6d32acc 100644
--- a/LiteCharms.Features/Notifications/Commands/Handlers/UpdateNotificationCommandHandler.cs
+++ b/LiteCharms.Features/Shop/Notifications/Commands/Handlers/UpdateNotificationCommandHandler.cs
@@ -1,4 +1,4 @@
-using LiteCharms.Infrastructure.Database;
+using LiteCharms.Features.Shop.Postgres;
namespace LiteCharms.Features.Notifications.Commands.Handlers;
diff --git a/LiteCharms.Features/Notifications/Commands/UpdateNotificationCommand.cs b/LiteCharms.Features/Shop/Notifications/Commands/UpdateNotificationCommand.cs
similarity index 100%
rename from LiteCharms.Features/Notifications/Commands/UpdateNotificationCommand.cs
rename to LiteCharms.Features/Shop/Notifications/Commands/UpdateNotificationCommand.cs
diff --git a/LiteCharms.Entities/Notification.cs b/LiteCharms.Features/Shop/Notifications/Entities/Notification.cs
similarity index 60%
rename from LiteCharms.Entities/Notification.cs
rename to LiteCharms.Features/Shop/Notifications/Entities/Notification.cs
index 2f3bf11..36a7dbc 100644
--- a/LiteCharms.Entities/Notification.cs
+++ b/LiteCharms.Features/Shop/Notifications/Entities/Notification.cs
@@ -1,6 +1,4 @@
-using LiteCharms.Entities.Configuration;
-
-namespace LiteCharms.Entities;
+namespace LiteCharms.Features.Shop.Notifications.Entities;
[EntityTypeConfiguration]
public class Notification : Models.Notification;
diff --git a/LiteCharms.Entities/Configuration/NotificationConfiguration.cs b/LiteCharms.Features/Shop/Notifications/Entities/NotificationConfiguration.cs
similarity index 88%
rename from LiteCharms.Entities/Configuration/NotificationConfiguration.cs
rename to LiteCharms.Features/Shop/Notifications/Entities/NotificationConfiguration.cs
index 45319a4..37b7659 100644
--- a/LiteCharms.Entities/Configuration/NotificationConfiguration.cs
+++ b/LiteCharms.Features/Shop/Notifications/Entities/NotificationConfiguration.cs
@@ -1,6 +1,4 @@
-using LiteCharms.Models;
-
-namespace LiteCharms.Entities.Configuration;
+namespace LiteCharms.Features.Shop.Notifications.Entities;
public class NotificationConfiguration : IEntityTypeConfiguration
{
@@ -9,8 +7,8 @@ public class NotificationConfiguration : IEntityTypeConfiguration
builder.ToTable(nameof(Notification));
builder.HasKey(f => f.Id);
- builder.Property(f => f.CreatedAt).IsRequired().ValueGeneratedOnAdd();
- builder.Property(f => f.UpdatedAt).IsRequired(false).ValueGeneratedOnUpdate();
+ builder.Property(f => f.CreatedAt).IsRequired().ValueGeneratedOnAdd().HasDefaultValueSql("now()");
+ builder.Property(f => f.UpdatedAt).IsRequired(false);
builder.Property(f => f.Direction).IsRequired().HasConversion();
builder.Property(f => f.Platform).IsRequired().HasConversion();
builder.Property(f => f.Priority).IsRequired().HasConversion();
diff --git a/LiteCharms.Features/Notifications/Events/Handlers/ProcessEmailNotificationsEventHandler.cs b/LiteCharms.Features/Shop/Notifications/Events/Handlers/ProcessEmailNotificationsEventHandler.cs
similarity index 89%
rename from LiteCharms.Features/Notifications/Events/Handlers/ProcessEmailNotificationsEventHandler.cs
rename to LiteCharms.Features/Shop/Notifications/Events/Handlers/ProcessEmailNotificationsEventHandler.cs
index 61b24d5..332ec86 100644
--- a/LiteCharms.Features/Notifications/Events/Handlers/ProcessEmailNotificationsEventHandler.cs
+++ b/LiteCharms.Features/Shop/Notifications/Events/Handlers/ProcessEmailNotificationsEventHandler.cs
@@ -1,6 +1,7 @@
using LiteCharms.Features.Email.Commands;
-using LiteCharms.Infrastructure.Database;
-using static LiteCharms.Abstractions.Constants;
+using LiteCharms.Features.Shop.Notifications.Entities;
+using LiteCharms.Features.Shop.Postgres;
+using static LiteCharms.Features.ServiceBus.Constants;
namespace LiteCharms.Features.Notifications.Events.Handlers;
@@ -49,7 +50,7 @@ public class ProcessEmailNotificationsEventHandler(IDbContextFactory SendEmailAsync(Entities.Notification notification, CancellationToken cancellationToken = default)
+ private async Task SendEmailAsync(Notification notification, CancellationToken cancellationToken = default)
{
try
{
diff --git a/LiteCharms.Features/Notifications/Events/ProcessEmailNotificationsEvent.cs b/LiteCharms.Features/Shop/Notifications/Events/ProcessEmailNotificationsEvent.cs
similarity index 91%
rename from LiteCharms.Features/Notifications/Events/ProcessEmailNotificationsEvent.cs
rename to LiteCharms.Features/Shop/Notifications/Events/ProcessEmailNotificationsEvent.cs
index 9ac754f..bbc4da4 100644
--- a/LiteCharms.Features/Notifications/Events/ProcessEmailNotificationsEvent.cs
+++ b/LiteCharms.Features/Shop/Notifications/Events/ProcessEmailNotificationsEvent.cs
@@ -1,4 +1,4 @@
-using LiteCharms.Abstractions;
+using LiteCharms.Features.Abstractions;
namespace LiteCharms.Features.Notifications.Events;
diff --git a/LiteCharms.Features/Shop/Notifications/INotificationService.cs b/LiteCharms.Features/Shop/Notifications/INotificationService.cs
new file mode 100644
index 0000000..d036de3
--- /dev/null
+++ b/LiteCharms.Features/Shop/Notifications/INotificationService.cs
@@ -0,0 +1,9 @@
+using LiteCharms.Features.Shop.Notifications.Models;
+
+namespace LiteCharms.Features.Shop.Notifications;
+
+public interface INotificationService
+{
+ Task> CreateNotificationAsync(CreateNotification request, CancellationToken cancellationToken = default);
+ Task UpdateNotificationAsync(UpdateNotification request, CancellationToken cancellationToken = default);
+}
diff --git a/LiteCharms.Models/Notification.cs b/LiteCharms.Features/Shop/Notifications/Models/Notification.cs
similarity index 93%
rename from LiteCharms.Models/Notification.cs
rename to LiteCharms.Features/Shop/Notifications/Models/Notification.cs
index 6108cbb..cba815c 100644
--- a/LiteCharms.Models/Notification.cs
+++ b/LiteCharms.Features/Shop/Notifications/Models/Notification.cs
@@ -1,4 +1,4 @@
-namespace LiteCharms.Models;
+namespace LiteCharms.Features.Shop.Notifications.Models;
public class Notification
{
diff --git a/LiteCharms.Features/Shop/Notifications/Models/Records.cs b/LiteCharms.Features/Shop/Notifications/Models/Records.cs
new file mode 100644
index 0000000..2f0f949
--- /dev/null
+++ b/LiteCharms.Features/Shop/Notifications/Models/Records.cs
@@ -0,0 +1,41 @@
+namespace LiteCharms.Features.Shop.Notifications.Models;
+
+public record CreateNotification
+{
+ public NotificationDirection Direction { get; set; }
+
+ public string? Sender { get; set; }
+
+ public string? SenderAddress { get; set; }
+
+ public string? Subject { get; set; }
+
+ public string? Message { get; set; }
+
+ public NotificationPlatforms Platform { get; set; }
+
+ public Priorities Priority { get; set; }
+
+ public string? Recipient { get; set; }
+
+ public string? RecipientAddress { get; set; }
+
+ public string? CorrelationId { get; set; }
+
+ public CorrelationIdTypes CorrelationIdType { get; set; }
+
+ public bool IsInternal { get; set; }
+
+ public bool IsHtml { get; set; }
+}
+
+public class UpdateNotification
+{
+ public Guid NotificationId { get; set; }
+
+ public bool Processed { get; set; }
+
+ public bool HasError { get; set; }
+
+ public string[]? Errors { get; set; }
+}
diff --git a/LiteCharms.Features/Shop/Notifications/NotificationService.cs b/LiteCharms.Features/Shop/Notifications/NotificationService.cs
new file mode 100644
index 0000000..02ee707
--- /dev/null
+++ b/LiteCharms.Features/Shop/Notifications/NotificationService.cs
@@ -0,0 +1,5 @@
+namespace LiteCharms.Features.Shop.Notifications;
+
+public class NotificationService : INotificationService
+{
+}
diff --git a/LiteCharms.Features/Notifications/Queries/GetNotificationQuery.cs b/LiteCharms.Features/Shop/Notifications/Queries/GetNotificationQuery.cs
similarity index 90%
rename from LiteCharms.Features/Notifications/Queries/GetNotificationQuery.cs
rename to LiteCharms.Features/Shop/Notifications/Queries/GetNotificationQuery.cs
index f41aea5..6c599fb 100644
--- a/LiteCharms.Features/Notifications/Queries/GetNotificationQuery.cs
+++ b/LiteCharms.Features/Shop/Notifications/Queries/GetNotificationQuery.cs
@@ -1,4 +1,4 @@
-using LiteCharms.Models;
+using LiteCharms.Features.Shop.Notifications.Models;
namespace LiteCharms.Features.Notifications.Queries;
diff --git a/LiteCharms.Features/Notifications/Queries/GetNotificationsQuery.cs b/LiteCharms.Features/Shop/Notifications/Queries/GetNotificationsQuery.cs
similarity index 93%
rename from LiteCharms.Features/Notifications/Queries/GetNotificationsQuery.cs
rename to LiteCharms.Features/Shop/Notifications/Queries/GetNotificationsQuery.cs
index 6eef589..6a10a4e 100644
--- a/LiteCharms.Features/Notifications/Queries/GetNotificationsQuery.cs
+++ b/LiteCharms.Features/Shop/Notifications/Queries/GetNotificationsQuery.cs
@@ -1,4 +1,4 @@
-using LiteCharms.Models;
+using LiteCharms.Features.Shop.Notifications.Models;
namespace LiteCharms.Features.Notifications.Queries;
diff --git a/LiteCharms.Features/Notifications/Queries/Handlers/GetNotificationQueryHandler.cs b/LiteCharms.Features/Shop/Notifications/Queries/Handlers/GetNotificationQueryHandler.cs
similarity index 91%
rename from LiteCharms.Features/Notifications/Queries/Handlers/GetNotificationQueryHandler.cs
rename to LiteCharms.Features/Shop/Notifications/Queries/Handlers/GetNotificationQueryHandler.cs
index 5eac5d8..11d5553 100644
--- a/LiteCharms.Features/Notifications/Queries/Handlers/GetNotificationQueryHandler.cs
+++ b/LiteCharms.Features/Shop/Notifications/Queries/Handlers/GetNotificationQueryHandler.cs
@@ -1,6 +1,6 @@
using LiteCharms.Extensions;
-using LiteCharms.Infrastructure.Database;
-using LiteCharms.Models;
+using LiteCharms.Features.Shop.Notifications.Models;
+using LiteCharms.Features.Shop.Postgres;
namespace LiteCharms.Features.Notifications.Queries.Handlers;
diff --git a/LiteCharms.Features/Notifications/Queries/Handlers/GetNotificationsQueryHandler.cs b/LiteCharms.Features/Shop/Notifications/Queries/Handlers/GetNotificationsQueryHandler.cs
similarity index 93%
rename from LiteCharms.Features/Notifications/Queries/Handlers/GetNotificationsQueryHandler.cs
rename to LiteCharms.Features/Shop/Notifications/Queries/Handlers/GetNotificationsQueryHandler.cs
index 70e448f..17e6094 100644
--- a/LiteCharms.Features/Notifications/Queries/Handlers/GetNotificationsQueryHandler.cs
+++ b/LiteCharms.Features/Shop/Notifications/Queries/Handlers/GetNotificationsQueryHandler.cs
@@ -1,6 +1,6 @@
using LiteCharms.Extensions;
-using LiteCharms.Infrastructure.Database;
-using LiteCharms.Models;
+using LiteCharms.Features.Shop.Notifications.Models;
+using LiteCharms.Features.Shop.Postgres;
namespace LiteCharms.Features.Notifications.Queries.Handlers;
diff --git a/LiteCharms.Features/Orders/Commands/CreateOrderCommand.cs b/LiteCharms.Features/Shop/Orders/Commands/CreateOrderCommand.cs
similarity index 100%
rename from LiteCharms.Features/Orders/Commands/CreateOrderCommand.cs
rename to LiteCharms.Features/Shop/Orders/Commands/CreateOrderCommand.cs
diff --git a/LiteCharms.Features/Orders/Commands/Handlers/CreateOrderCommandHandler.cs b/LiteCharms.Features/Shop/Orders/Commands/Handlers/CreateOrderCommandHandler.cs
similarity index 96%
rename from LiteCharms.Features/Orders/Commands/Handlers/CreateOrderCommandHandler.cs
rename to LiteCharms.Features/Shop/Orders/Commands/Handlers/CreateOrderCommandHandler.cs
index b97f83e..95a599a 100644
--- a/LiteCharms.Features/Orders/Commands/Handlers/CreateOrderCommandHandler.cs
+++ b/LiteCharms.Features/Shop/Orders/Commands/Handlers/CreateOrderCommandHandler.cs
@@ -1,4 +1,5 @@
-using LiteCharms.Infrastructure.Database;
+using LiteCharms.Features.Shop;
+using LiteCharms.Features.Shop.Postgres;
using LiteCharms.Models;
namespace LiteCharms.Features.Orders.Commands.Handlers;
diff --git a/LiteCharms.Features/Orders/Commands/Handlers/UpdateOrderStatusCommandHandler.cs b/LiteCharms.Features/Shop/Orders/Commands/Handlers/UpdateOrderStatusCommandHandler.cs
similarity index 95%
rename from LiteCharms.Features/Orders/Commands/Handlers/UpdateOrderStatusCommandHandler.cs
rename to LiteCharms.Features/Shop/Orders/Commands/Handlers/UpdateOrderStatusCommandHandler.cs
index 0cfe348..2c0052f 100644
--- a/LiteCharms.Features/Orders/Commands/Handlers/UpdateOrderStatusCommandHandler.cs
+++ b/LiteCharms.Features/Shop/Orders/Commands/Handlers/UpdateOrderStatusCommandHandler.cs
@@ -1,4 +1,4 @@
-using LiteCharms.Infrastructure.Database;
+using LiteCharms.Features.Shop.Postgres;
namespace LiteCharms.Features.Orders.Commands.Handlers;
diff --git a/LiteCharms.Features/Orders/Commands/UpdateOrderStatusCommand.cs b/LiteCharms.Features/Shop/Orders/Commands/UpdateOrderStatusCommand.cs
similarity index 93%
rename from LiteCharms.Features/Orders/Commands/UpdateOrderStatusCommand.cs
rename to LiteCharms.Features/Shop/Orders/Commands/UpdateOrderStatusCommand.cs
index 3e6d1c6..eefc734 100644
--- a/LiteCharms.Features/Orders/Commands/UpdateOrderStatusCommand.cs
+++ b/LiteCharms.Features/Shop/Orders/Commands/UpdateOrderStatusCommand.cs
@@ -1,4 +1,5 @@
-using LiteCharms.Models;
+using LiteCharms.Features.Shop;
+using LiteCharms.Models;
namespace LiteCharms.Features.Orders.Commands;
diff --git a/LiteCharms.Features/Shop/Orders/Entities/Order.cs b/LiteCharms.Features/Shop/Orders/Entities/Order.cs
new file mode 100644
index 0000000..f5dd1d0
--- /dev/null
+++ b/LiteCharms.Features/Shop/Orders/Entities/Order.cs
@@ -0,0 +1,17 @@
+using LiteCharms.Features.Shop.Customers.Entities;
+using LiteCharms.Features.Shop.Quotes.Entities;
+using LiteCharms.Features.Shop.ShoppingCarts.Entities;
+
+namespace LiteCharms.Features.Shop.Orders.Entities;
+
+[EntityTypeConfiguration]
+public class Order : Models.Order
+{
+ public virtual ICollection? Refunds { get; set; }
+
+ public virtual Customer? Customer { get; set; }
+
+ public virtual Quote? Quote { get; set; }
+
+ public virtual ShoppingCart? ShoppingCart { get; set; }
+}
diff --git a/LiteCharms.Features/Shop/Orders/Entities/OrderConfiguration.cs b/LiteCharms.Features/Shop/Orders/Entities/OrderConfiguration.cs
new file mode 100644
index 0000000..d79fb0e
--- /dev/null
+++ b/LiteCharms.Features/Shop/Orders/Entities/OrderConfiguration.cs
@@ -0,0 +1,25 @@
+namespace LiteCharms.Features.Shop.Orders.Entities;
+
+public class OrderConfiguration : IEntityTypeConfiguration
+{
+ public void Configure(EntityTypeBuilder builder)
+ {
+ builder.ToTable(nameof(Order));
+
+ builder.HasKey(f => f.Id);
+ builder.Property(f => f.CreatedAt).ValueGeneratedOnAdd().HasDefaultValueSql("now()");
+ builder.Property(f => f.UpdatedAt).IsRequired(false);
+ builder.Property(f => f.CustomerId).IsRequired();
+ builder.Property(f => f.Status).HasConversion().IsRequired();
+ builder.Property(f => f.Requirements).HasColumnType("jsonb").IsRequired(false);
+ builder.Property(f => f.Notes).HasColumnType("jsonb").IsRequired(false);
+ builder.Property(f => f.Terms).HasColumnType("jsonb").IsRequired(false);
+ builder.Property(f => f.InvoiceUrl).IsRequired(false).HasMaxLength(2048);
+
+ builder.HasOne(o => o.Customer)
+ .WithMany(c => c.Orders)
+ .HasForeignKey(o => o.CustomerId)
+ .IsRequired()
+ .OnDelete(DeleteBehavior.Restrict);
+ }
+}
diff --git a/LiteCharms.Entities/OrderRefund.cs b/LiteCharms.Features/Shop/Orders/Entities/OrderRefund.cs
similarity index 68%
rename from LiteCharms.Entities/OrderRefund.cs
rename to LiteCharms.Features/Shop/Orders/Entities/OrderRefund.cs
index e5a285d..33591d7 100644
--- a/LiteCharms.Entities/OrderRefund.cs
+++ b/LiteCharms.Features/Shop/Orders/Entities/OrderRefund.cs
@@ -1,6 +1,4 @@
-using LiteCharms.Entities.Configuration;
-
-namespace LiteCharms.Entities;
+namespace LiteCharms.Features.Shop.Orders.Entities;
[EntityTypeConfiguration]
public class OrderRefund : Models.OrderRefund
diff --git a/LiteCharms.Entities/Configuration/OrderRefundConfiguration.cs b/LiteCharms.Features/Shop/Orders/Entities/OrderRefundConfiguration.cs
similarity index 63%
rename from LiteCharms.Entities/Configuration/OrderRefundConfiguration.cs
rename to LiteCharms.Features/Shop/Orders/Entities/OrderRefundConfiguration.cs
index 5550805..f353123 100644
--- a/LiteCharms.Entities/Configuration/OrderRefundConfiguration.cs
+++ b/LiteCharms.Features/Shop/Orders/Entities/OrderRefundConfiguration.cs
@@ -1,4 +1,4 @@
-namespace LiteCharms.Entities.Configuration;
+namespace LiteCharms.Features.Shop.Orders.Entities;
public class OrderRefundConfiguration : IEntityTypeConfiguration
{
@@ -7,13 +7,15 @@ public class OrderRefundConfiguration : IEntityTypeConfiguration
builder.ToTable(nameof(OrderRefund));
builder.HasKey(f => f.Id);
- builder.Property(f => f.CreatedAt).ValueGeneratedOnAdd();
+ builder.Property(f => f.CreatedAt).ValueGeneratedOnAdd().HasDefaultValueSql("now()");
builder.Property(f => f.OrderId).IsRequired();
builder.Property(f => f.Reason).IsRequired();
builder.Property(f => f.Amount).IsRequired().HasPrecision(18, 2);
- builder.HasOne(f => f.Order)
- .WithOne(o => o.Refund)
- .HasForeignKey(o => o.OrderId);
+ builder.HasOne(r => r.Order)
+ .WithMany(o => o.Refunds)
+ .HasForeignKey(r => r.OrderId)
+ .IsRequired()
+ .OnDelete(DeleteBehavior.Cascade);
}
}
diff --git a/LiteCharms.Models/Order.cs b/LiteCharms.Features/Shop/Orders/Models/Order.cs
similarity index 64%
rename from LiteCharms.Models/Order.cs
rename to LiteCharms.Features/Shop/Orders/Models/Order.cs
index 3c55c81..d093993 100644
--- a/LiteCharms.Models/Order.cs
+++ b/LiteCharms.Features/Shop/Orders/Models/Order.cs
@@ -1,4 +1,4 @@
-namespace LiteCharms.Models;
+namespace LiteCharms.Features.Shop.Orders.Models;
public class Order
{
@@ -10,12 +10,6 @@ public class Order
public Guid CustomerId { get; set; }
- public Guid? QuoteId { get; set; }
-
- public Guid ShoppingCartId { get; set; }
-
- public Guid? RefundId { get; set; }
-
public OrderStatus Status { get; set; }
public string[]? Requirements { get; set; }
@@ -24,5 +18,5 @@ public class Order
public string[]? Terms { get; set; }
- public bool DepositRequired { get; set; }
+ public string? InvoiceUrl { get; set; }
}
diff --git a/LiteCharms.Models/OrderRefund.cs b/LiteCharms.Features/Shop/Orders/Models/OrderRefund.cs
similarity index 81%
rename from LiteCharms.Models/OrderRefund.cs
rename to LiteCharms.Features/Shop/Orders/Models/OrderRefund.cs
index 292e918..34668a7 100644
--- a/LiteCharms.Models/OrderRefund.cs
+++ b/LiteCharms.Features/Shop/Orders/Models/OrderRefund.cs
@@ -1,4 +1,4 @@
-namespace LiteCharms.Models;
+namespace LiteCharms.Features.Shop.Orders.Models;
public class OrderRefund
{
diff --git a/LiteCharms.Features/Orders/Queries/GetCustomerOrdersQuery.cs b/LiteCharms.Features/Shop/Orders/Queries/GetCustomerOrdersQuery.cs
similarity index 90%
rename from LiteCharms.Features/Orders/Queries/GetCustomerOrdersQuery.cs
rename to LiteCharms.Features/Shop/Orders/Queries/GetCustomerOrdersQuery.cs
index 7d11f91..f74f5c4 100644
--- a/LiteCharms.Features/Orders/Queries/GetCustomerOrdersQuery.cs
+++ b/LiteCharms.Features/Shop/Orders/Queries/GetCustomerOrdersQuery.cs
@@ -1,4 +1,4 @@
-using LiteCharms.Models;
+using LiteCharms.Features.Shop.Orders.Models;
namespace LiteCharms.Features.Orders.Queries;
diff --git a/LiteCharms.Features/Orders/Queries/GetOrderRefundQuery.cs b/LiteCharms.Features/Shop/Orders/Queries/GetOrderRefundQuery.cs
similarity index 93%
rename from LiteCharms.Features/Orders/Queries/GetOrderRefundQuery.cs
rename to LiteCharms.Features/Shop/Orders/Queries/GetOrderRefundQuery.cs
index 887e03b..01295cf 100644
--- a/LiteCharms.Features/Orders/Queries/GetOrderRefundQuery.cs
+++ b/LiteCharms.Features/Shop/Orders/Queries/GetOrderRefundQuery.cs
@@ -1,4 +1,4 @@
-using LiteCharms.Models;
+using LiteCharms.Features.Shop.Orders.Models;
namespace LiteCharms.Features.Orders.Queries;
diff --git a/LiteCharms.Features/Orders/Queries/GetOrdersQuery.cs b/LiteCharms.Features/Shop/Orders/Queries/GetOrdersQuery.cs
similarity index 93%
rename from LiteCharms.Features/Orders/Queries/GetOrdersQuery.cs
rename to LiteCharms.Features/Shop/Orders/Queries/GetOrdersQuery.cs
index c0c2c3b..0fc45d8 100644
--- a/LiteCharms.Features/Orders/Queries/GetOrdersQuery.cs
+++ b/LiteCharms.Features/Shop/Orders/Queries/GetOrdersQuery.cs
@@ -1,4 +1,4 @@
-using LiteCharms.Models;
+using LiteCharms.Features.Shop.Orders.Models;
namespace LiteCharms.Features.Orders.Queries;
diff --git a/LiteCharms.Features/Orders/Queries/Handlers/GetCustomerOrdersQueryHandler.cs b/LiteCharms.Features/Shop/Orders/Queries/Handlers/GetCustomerOrdersQueryHandler.cs
similarity index 93%
rename from LiteCharms.Features/Orders/Queries/Handlers/GetCustomerOrdersQueryHandler.cs
rename to LiteCharms.Features/Shop/Orders/Queries/Handlers/GetCustomerOrdersQueryHandler.cs
index eb9e79f..a2f65d9 100644
--- a/LiteCharms.Features/Orders/Queries/Handlers/GetCustomerOrdersQueryHandler.cs
+++ b/LiteCharms.Features/Shop/Orders/Queries/Handlers/GetCustomerOrdersQueryHandler.cs
@@ -1,6 +1,6 @@
using LiteCharms.Extensions;
-using LiteCharms.Infrastructure.Database;
-using LiteCharms.Models;
+using LiteCharms.Features.Shop.Orders.Models;
+using LiteCharms.Features.Shop.Postgres;
namespace LiteCharms.Features.Orders.Queries.Handlers;
diff --git a/LiteCharms.Features/Orders/Queries/Handlers/GetOrderRefundQueryHandler.cs b/LiteCharms.Features/Shop/Orders/Queries/Handlers/GetOrderRefundQueryHandler.cs
similarity index 92%
rename from LiteCharms.Features/Orders/Queries/Handlers/GetOrderRefundQueryHandler.cs
rename to LiteCharms.Features/Shop/Orders/Queries/Handlers/GetOrderRefundQueryHandler.cs
index 47dd481..3493b11 100644
--- a/LiteCharms.Features/Orders/Queries/Handlers/GetOrderRefundQueryHandler.cs
+++ b/LiteCharms.Features/Shop/Orders/Queries/Handlers/GetOrderRefundQueryHandler.cs
@@ -1,6 +1,6 @@
using LiteCharms.Extensions;
-using LiteCharms.Infrastructure.Database;
-using LiteCharms.Models;
+using LiteCharms.Features.Shop.Orders.Models;
+using LiteCharms.Features.Shop.Postgres;
namespace LiteCharms.Features.Orders.Queries.Handlers;
diff --git a/LiteCharms.Features/Orders/Queries/Handlers/GetOrdersQueryHandler.cs b/LiteCharms.Features/Shop/Orders/Queries/Handlers/GetOrdersQueryHandler.cs
similarity index 93%
rename from LiteCharms.Features/Orders/Queries/Handlers/GetOrdersQueryHandler.cs
rename to LiteCharms.Features/Shop/Orders/Queries/Handlers/GetOrdersQueryHandler.cs
index f244869..898f3fc 100644
--- a/LiteCharms.Features/Orders/Queries/Handlers/GetOrdersQueryHandler.cs
+++ b/LiteCharms.Features/Shop/Orders/Queries/Handlers/GetOrdersQueryHandler.cs
@@ -1,6 +1,6 @@
using LiteCharms.Extensions;
-using LiteCharms.Infrastructure.Database;
-using LiteCharms.Models;
+using LiteCharms.Features.Shop.Orders.Models;
+using LiteCharms.Features.Shop.Postgres;
namespace LiteCharms.Features.Orders.Queries.Handlers;
diff --git a/LiteCharms.Features/Refunds/Commands/Handlers/RefundCustomerCommandHandler.cs b/LiteCharms.Features/Shop/Orders/Refunds/Commands/Handlers/RefundCustomerCommandHandler.cs
similarity index 90%
rename from LiteCharms.Features/Refunds/Commands/Handlers/RefundCustomerCommandHandler.cs
rename to LiteCharms.Features/Shop/Orders/Refunds/Commands/Handlers/RefundCustomerCommandHandler.cs
index c4021f7..9013f10 100644
--- a/LiteCharms.Features/Refunds/Commands/Handlers/RefundCustomerCommandHandler.cs
+++ b/LiteCharms.Features/Shop/Orders/Refunds/Commands/Handlers/RefundCustomerCommandHandler.cs
@@ -1,6 +1,7 @@
-using LiteCharms.Infrastructure.Database;
+using LiteCharms.Features.Shop.Orders.Refunds.Commands;
+using LiteCharms.Features.Shop.Postgres;
-namespace LiteCharms.Features.Refunds.Commands.Handlers;
+namespace LiteCharms.Features.Shop.Orders.Refunds.Commands.Handlers;
public class RefundCustomerCommandHandler(IDbContextFactory contextFactory) : IRequestHandler>
{
diff --git a/LiteCharms.Features/Refunds/Commands/Handlers/UpdateOrderRefundCommandHandler.cs b/LiteCharms.Features/Shop/Orders/Refunds/Commands/Handlers/UpdateOrderRefundCommandHandler.cs
similarity index 85%
rename from LiteCharms.Features/Refunds/Commands/Handlers/UpdateOrderRefundCommandHandler.cs
rename to LiteCharms.Features/Shop/Orders/Refunds/Commands/Handlers/UpdateOrderRefundCommandHandler.cs
index 9f6fb00..ac88a49 100644
--- a/LiteCharms.Features/Refunds/Commands/Handlers/UpdateOrderRefundCommandHandler.cs
+++ b/LiteCharms.Features/Shop/Orders/Refunds/Commands/Handlers/UpdateOrderRefundCommandHandler.cs
@@ -1,6 +1,7 @@
-using LiteCharms.Infrastructure.Database;
+using LiteCharms.Features.Shop.Orders.Refunds.Commands;
+using LiteCharms.Features.Shop.Postgres;
-namespace LiteCharms.Features.Refunds.Commands.Handlers;
+namespace LiteCharms.Features.Shop.Orders.Refunds.Commands.Handlers;
public class UpdateOrderRefundCommandHandler(IDbContextFactory contextFactory) : IRequestHandler
{
diff --git a/LiteCharms.Features/Refunds/Commands/RefundCustomerCommand.cs b/LiteCharms.Features/Shop/Orders/Refunds/Commands/RefundCustomerCommand.cs
similarity index 94%
rename from LiteCharms.Features/Refunds/Commands/RefundCustomerCommand.cs
rename to LiteCharms.Features/Shop/Orders/Refunds/Commands/RefundCustomerCommand.cs
index ccfda6e..ac5c75b 100644
--- a/LiteCharms.Features/Refunds/Commands/RefundCustomerCommand.cs
+++ b/LiteCharms.Features/Shop/Orders/Refunds/Commands/RefundCustomerCommand.cs
@@ -1,4 +1,4 @@
-namespace LiteCharms.Features.Refunds.Commands;
+namespace LiteCharms.Features.Shop.Orders.Refunds.Commands;
public class RefundCustomerCommand : IRequest>
{
diff --git a/LiteCharms.Features/Refunds/Commands/UpdateOrderRefundCommand.cs b/LiteCharms.Features/Shop/Orders/Refunds/Commands/UpdateOrderRefundCommand.cs
similarity index 92%
rename from LiteCharms.Features/Refunds/Commands/UpdateOrderRefundCommand.cs
rename to LiteCharms.Features/Shop/Orders/Refunds/Commands/UpdateOrderRefundCommand.cs
index bd9ab59..9f69b2f 100644
--- a/LiteCharms.Features/Refunds/Commands/UpdateOrderRefundCommand.cs
+++ b/LiteCharms.Features/Shop/Orders/Refunds/Commands/UpdateOrderRefundCommand.cs
@@ -1,4 +1,4 @@
-namespace LiteCharms.Features.Refunds.Commands;
+namespace LiteCharms.Features.Shop.Orders.Refunds.Commands;
public class UpdateOrderRefundCommand : IRequest
{
diff --git a/LiteCharms.Features/Refunds/Queries/GetCustomerRefundsQuery.cs b/LiteCharms.Features/Shop/Orders/Refunds/Queries/GetCustomerRefundsQuery.cs
similarity index 80%
rename from LiteCharms.Features/Refunds/Queries/GetCustomerRefundsQuery.cs
rename to LiteCharms.Features/Shop/Orders/Refunds/Queries/GetCustomerRefundsQuery.cs
index 24d2cc9..56d19f6 100644
--- a/LiteCharms.Features/Refunds/Queries/GetCustomerRefundsQuery.cs
+++ b/LiteCharms.Features/Shop/Orders/Refunds/Queries/GetCustomerRefundsQuery.cs
@@ -1,6 +1,6 @@
-using LiteCharms.Models;
+using LiteCharms.Features.Shop.Orders.Models;
-namespace LiteCharms.Features.Refunds.Queries;
+namespace LiteCharms.Features.Shop.Orders.Refunds.Queries;
public class GetCustomerRefundsQuery : IRequest>
{
diff --git a/LiteCharms.Features/Refunds/Queries/GetRefundQuery.cs b/LiteCharms.Features/Shop/Orders/Refunds/Queries/GetRefundQuery.cs
similarity index 80%
rename from LiteCharms.Features/Refunds/Queries/GetRefundQuery.cs
rename to LiteCharms.Features/Shop/Orders/Refunds/Queries/GetRefundQuery.cs
index 9f4d375..ddeaa7b 100644
--- a/LiteCharms.Features/Refunds/Queries/GetRefundQuery.cs
+++ b/LiteCharms.Features/Shop/Orders/Refunds/Queries/GetRefundQuery.cs
@@ -1,6 +1,6 @@
-using LiteCharms.Models;
+using LiteCharms.Features.Shop.Orders.Models;
-namespace LiteCharms.Features.Refunds.Queries;
+namespace LiteCharms.Features.Shop.Orders.Refunds.Queries;
public class GetRefundQuery : IRequest>
{
diff --git a/LiteCharms.Features/Refunds/Queries/Handlers/GetCustomerRefundsQueryHandler.cs b/LiteCharms.Features/Shop/Orders/Refunds/Queries/Handlers/GetCustomerRefundsQueryHandler.cs
similarity index 85%
rename from LiteCharms.Features/Refunds/Queries/Handlers/GetCustomerRefundsQueryHandler.cs
rename to LiteCharms.Features/Shop/Orders/Refunds/Queries/Handlers/GetCustomerRefundsQueryHandler.cs
index c198b76..8439f88 100644
--- a/LiteCharms.Features/Refunds/Queries/Handlers/GetCustomerRefundsQueryHandler.cs
+++ b/LiteCharms.Features/Shop/Orders/Refunds/Queries/Handlers/GetCustomerRefundsQueryHandler.cs
@@ -1,9 +1,9 @@
using LiteCharms.Extensions;
-using LiteCharms.Features.Refunds.Queries;
-using LiteCharms.Infrastructure.Database;
-using LiteCharms.Models;
+using LiteCharms.Features.Shop.Orders.Models;
+using LiteCharms.Features.Shop.Orders.Refunds.Queries;
+using LiteCharms.Features.Shop.Postgres;
-namespace LiteCharms.Features.Refunds.Queries.Handlers;
+namespace LiteCharms.Features.Shop.Orders.Refunds.Queries.Handlers;
public class GetCustomerRefundsQueryHandler(IDbContextFactory contextFactory) : IRequestHandler>
{
diff --git a/LiteCharms.Features/Refunds/Queries/Handlers/GetRefundQueryHandler.cs b/LiteCharms.Features/Shop/Orders/Refunds/Queries/Handlers/GetRefundQueryHandler.cs
similarity index 80%
rename from LiteCharms.Features/Refunds/Queries/Handlers/GetRefundQueryHandler.cs
rename to LiteCharms.Features/Shop/Orders/Refunds/Queries/Handlers/GetRefundQueryHandler.cs
index 2561031..a363945 100644
--- a/LiteCharms.Features/Refunds/Queries/Handlers/GetRefundQueryHandler.cs
+++ b/LiteCharms.Features/Shop/Orders/Refunds/Queries/Handlers/GetRefundQueryHandler.cs
@@ -1,8 +1,9 @@
using LiteCharms.Extensions;
-using LiteCharms.Infrastructure.Database;
-using LiteCharms.Models;
+using LiteCharms.Features.Shop.Orders.Models;
+using LiteCharms.Features.Shop.Orders.Refunds.Queries;
+using LiteCharms.Features.Shop.Postgres;
-namespace LiteCharms.Features.Refunds.Queries.Handlers;
+namespace LiteCharms.Features.Shop.Orders.Refunds.Queries.Handlers;
public class GetRefundQueryHandler(IDbContextFactory contextFactory) : IRequestHandler>
{
diff --git a/LiteCharms.Infrastructure/Database/Migrations/20260510132008_Init.Designer.cs b/LiteCharms.Features/Shop/Postgres/Migrations/20260512065421_Init.Designer.cs
similarity index 86%
rename from LiteCharms.Infrastructure/Database/Migrations/20260510132008_Init.Designer.cs
rename to LiteCharms.Features/Shop/Postgres/Migrations/20260512065421_Init.Designer.cs
index 4624007..5900074 100644
--- a/LiteCharms.Infrastructure/Database/Migrations/20260510132008_Init.Designer.cs
+++ b/LiteCharms.Features/Shop/Postgres/Migrations/20260512065421_Init.Designer.cs
@@ -1,6 +1,6 @@
//
using System;
-using LiteCharms.Infrastructure.Database;
+using LiteCharms.Features.Shop.Postgres;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
@@ -9,10 +9,10 @@ using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
-namespace LiteCharms.Infrastructure.Database.Migrations
+namespace LiteCharms.Features.Shop.Postgres.Migrations
{
[DbContext(typeof(ShopDbContext))]
- [Migration("20260510132008_Init")]
+ [Migration("20260512065421_Init")]
partial class Init
{
///
@@ -50,7 +50,8 @@ namespace LiteCharms.Infrastructure.Database.Migrations
b.Property("CreatedAt")
.ValueGeneratedOnAdd()
- .HasColumnType("timestamp with time zone");
+ .HasColumnType("timestamp with time zone")
+ .HasDefaultValueSql("now()");
b.Property("Discord")
.HasColumnType("text");
@@ -86,7 +87,6 @@ namespace LiteCharms.Infrastructure.Database.Migrations
.HasColumnType("text");
b.Property("UpdatedAt")
- .ValueGeneratedOnUpdate()
.HasColumnType("timestamp with time zone");
b.Property("Website")
@@ -130,7 +130,8 @@ namespace LiteCharms.Infrastructure.Database.Migrations
b.Property("CreatedAt")
.ValueGeneratedOnAdd()
- .HasColumnType("timestamp with time zone");
+ .HasColumnType("timestamp with time zone")
+ .HasDefaultValueSql("now()");
b.Property("CustomerId")
.HasColumnType("uuid");
@@ -148,7 +149,6 @@ namespace LiteCharms.Infrastructure.Database.Migrations
.HasColumnType("bigint");
b.Property("UpdatedAt")
- .ValueGeneratedOnUpdate()
.HasColumnType("timestamp with time zone");
b.Property("WebClickId")
@@ -176,7 +176,8 @@ namespace LiteCharms.Infrastructure.Database.Migrations
b.Property("CreatedAt")
.ValueGeneratedOnAdd()
- .HasColumnType("timestamp with time zone");
+ .HasColumnType("timestamp with time zone")
+ .HasDefaultValueSql("now()");
b.Property("Direction")
.HasColumnType("integer");
@@ -234,7 +235,6 @@ namespace LiteCharms.Infrastructure.Database.Migrations
.HasColumnType("text");
b.Property("UpdatedAt")
- .ValueGeneratedOnUpdate()
.HasColumnType("timestamp with time zone");
b.HasKey("Id");
@@ -250,29 +250,22 @@ namespace LiteCharms.Infrastructure.Database.Migrations
b.Property("CreatedAt")
.ValueGeneratedOnAdd()
- .HasColumnType("timestamp with time zone");
+ .HasColumnType("timestamp with time zone")
+ .HasDefaultValueSql("now()");
b.Property("CustomerId")
.HasColumnType("uuid");
- b.Property("DepositRequired")
- .HasColumnType("boolean");
+ b.Property("InvoiceUrl")
+ .HasMaxLength(2048)
+ .HasColumnType("character varying(2048)");
b.PrimitiveCollection("Notes")
.HasColumnType("jsonb");
- b.Property("QuoteId")
- .HasColumnType("uuid");
-
- b.Property("RefundId")
- .HasColumnType("uuid");
-
b.PrimitiveCollection("Requirements")
.HasColumnType("jsonb");
- b.Property("ShoppingCartId")
- .HasColumnType("uuid");
-
b.Property("Status")
.HasColumnType("integer");
@@ -280,19 +273,12 @@ namespace LiteCharms.Infrastructure.Database.Migrations
.HasColumnType("jsonb");
b.Property("UpdatedAt")
- .ValueGeneratedOnUpdate()
.HasColumnType("timestamp with time zone");
b.HasKey("Id");
b.HasIndex("CustomerId");
- b.HasIndex("QuoteId")
- .IsUnique();
-
- b.HasIndex("ShoppingCartId")
- .IsUnique();
-
b.ToTable("Order", (string)null);
});
@@ -308,7 +294,8 @@ namespace LiteCharms.Infrastructure.Database.Migrations
b.Property("CreatedAt")
.ValueGeneratedOnAdd()
- .HasColumnType("timestamp with time zone");
+ .HasColumnType("timestamp with time zone")
+ .HasDefaultValueSql("now()");
b.Property("OrderId")
.HasColumnType("uuid");
@@ -319,8 +306,7 @@ namespace LiteCharms.Infrastructure.Database.Migrations
b.HasKey("Id");
- b.HasIndex("OrderId")
- .IsUnique();
+ b.HasIndex("OrderId");
b.ToTable("OrderRefund", (string)null);
});
@@ -336,27 +322,32 @@ namespace LiteCharms.Infrastructure.Database.Migrations
b.Property("CreatedAt")
.ValueGeneratedOnAdd()
- .HasColumnType("timestamp with time zone");
+ .HasColumnType("timestamp with time zone")
+ .HasDefaultValueSql("now()");
b.Property("Description")
.IsRequired()
- .HasColumnType("text");
+ .HasMaxLength(2048)
+ .HasColumnType("character varying(2048)");
+
+ b.Property("ImageUrl")
+ .HasMaxLength(2048)
+ .HasColumnType("character varying(2048)");
b.Property("Name")
.IsRequired()
.HasColumnType("text");
- b.Property("ShoppingCartId")
- .HasColumnType("uuid");
+ b.Property("Summary")
+ .IsRequired()
+ .HasMaxLength(512)
+ .HasColumnType("character varying(512)");
b.Property("UpdatedAt")
- .ValueGeneratedOnUpdate()
.HasColumnType("timestamp with time zone");
b.HasKey("Id");
- b.HasIndex("ShoppingCartId");
-
b.ToTable("Package", (string)null);
});
@@ -371,14 +362,12 @@ namespace LiteCharms.Infrastructure.Database.Migrations
b.Property("CreatedAt")
.ValueGeneratedOnAdd()
- .HasColumnType("timestamp with time zone");
+ .HasColumnType("timestamp with time zone")
+ .HasDefaultValueSql("now()");
b.Property("PackageId")
.HasColumnType("uuid");
- b.Property("PackageId1")
- .HasColumnType("uuid");
-
b.Property("ProductPriceId")
.HasColumnType("uuid");
@@ -386,7 +375,7 @@ namespace LiteCharms.Infrastructure.Database.Migrations
b.HasIndex("PackageId");
- b.HasIndex("PackageId1");
+ b.HasIndex("ProductPriceId");
b.ToTable("PackageItem", (string)null);
});
@@ -404,12 +393,25 @@ namespace LiteCharms.Infrastructure.Database.Migrations
b.Property("Description")
.IsRequired()
- .HasColumnType("text");
+ .HasMaxLength(2048)
+ .HasColumnType("character varying(2048)");
+
+ b.Property("ImageUrl")
+ .HasMaxLength(2048)
+ .HasColumnType("character varying(2048)");
b.Property("Name")
.IsRequired()
.HasColumnType("text");
+ b.Property("Summary")
+ .IsRequired()
+ .HasMaxLength(512)
+ .HasColumnType("character varying(512)");
+
+ b.PrimitiveCollection("Thumbnails")
+ .HasColumnType("jsonb");
+
b.HasKey("Id");
b.ToTable("Product", (string)null);
@@ -426,7 +428,8 @@ namespace LiteCharms.Infrastructure.Database.Migrations
b.Property("CreatedAt")
.ValueGeneratedOnAdd()
- .HasColumnType("timestamp with time zone");
+ .HasColumnType("timestamp with time zone")
+ .HasDefaultValueSql("now()");
b.Property("Discount")
.HasPrecision(18, 2)
@@ -440,7 +443,6 @@ namespace LiteCharms.Infrastructure.Database.Migrations
.HasColumnType("uuid");
b.Property("UpdatedAt")
- .ValueGeneratedOnUpdate()
.HasColumnType("timestamp with time zone");
b.HasKey("Id");
@@ -458,35 +460,40 @@ namespace LiteCharms.Infrastructure.Database.Migrations
b.Property("CreatedAt")
.ValueGeneratedOnAdd()
- .HasColumnType("timestamp with time zone");
+ .HasColumnType("timestamp with time zone")
+ .HasDefaultValueSql("now()");
b.Property("CustomerId")
.HasColumnType("uuid");
- b.Property("CustomerId1")
- .HasColumnType("uuid");
-
b.Property("ExpiredAt")
.HasColumnType("timestamp with time zone");
+ b.Property("InvoiceUrl")
+ .HasMaxLength(2048)
+ .HasColumnType("character varying(2048)");
+
+ b.Property("OrderId")
+ .HasColumnType("uuid");
+
b.Property("Reason")
.HasColumnType("text");
- b.Property("ShoppingCartId")
+ b.Property("ShoppingCartId")
.HasColumnType("uuid");
b.Property("Status")
.HasColumnType("integer");
b.Property("UpdatedAt")
- .ValueGeneratedOnUpdate()
.HasColumnType("timestamp with time zone");
b.HasKey("Id");
b.HasIndex("CustomerId");
- b.HasIndex("CustomerId1");
+ b.HasIndex("OrderId")
+ .IsUnique();
b.HasIndex("ShoppingCartId")
.IsUnique();
@@ -502,25 +509,25 @@ namespace LiteCharms.Infrastructure.Database.Migrations
b.Property("CreatedAt")
.ValueGeneratedOnAdd()
- .HasColumnType("timestamp with time zone");
+ .HasColumnType("timestamp with time zone")
+ .HasDefaultValueSql("now()");
- b.Property("CustomerId")
+ b.Property("CustomerId")
.HasColumnType("uuid");
b.Property("OrderId")
.HasColumnType("uuid");
- b.Property("QuoteId")
- .HasColumnType("uuid");
-
b.Property("UpdatedAt")
- .ValueGeneratedOnUpdate()
.HasColumnType("timestamp with time zone");
b.HasKey("Id");
b.HasIndex("CustomerId");
+ b.HasIndex("OrderId")
+ .IsUnique();
+
b.ToTable("ShoppingCart", (string)null);
});
@@ -562,7 +569,8 @@ namespace LiteCharms.Infrastructure.Database.Migrations
b.Property("CreatedAt")
.ValueGeneratedOnAdd()
- .HasColumnType("timestamp with time zone");
+ .HasColumnType("timestamp with time zone")
+ .HasDefaultValueSql("now()");
b.Property("PackageId")
.HasColumnType("uuid");
@@ -583,8 +591,7 @@ namespace LiteCharms.Infrastructure.Database.Migrations
{
b.HasOne("LiteCharms.Entities.Customer", "Customer")
.WithMany("Leads")
- .HasForeignKey("CustomerId")
- .OnDelete(DeleteBehavior.NoAction);
+ .HasForeignKey("CustomerId");
b.Navigation("Customer");
});
@@ -597,55 +604,37 @@ namespace LiteCharms.Infrastructure.Database.Migrations
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
- b.HasOne("LiteCharms.Entities.Quote", "Quote")
- .WithOne("Order")
- .HasForeignKey("LiteCharms.Entities.Order", "QuoteId")
- .OnDelete(DeleteBehavior.Restrict);
-
- b.HasOne("LiteCharms.Entities.ShoppingCart", "ShoppingCart")
- .WithOne("Order")
- .HasForeignKey("LiteCharms.Entities.Order", "ShoppingCartId")
- .OnDelete(DeleteBehavior.NoAction)
- .IsRequired();
-
b.Navigation("Customer");
-
- b.Navigation("Quote");
-
- b.Navigation("ShoppingCart");
});
modelBuilder.Entity("LiteCharms.Entities.OrderRefund", b =>
{
b.HasOne("LiteCharms.Entities.Order", "Order")
- .WithOne("Refund")
- .HasForeignKey("LiteCharms.Entities.OrderRefund", "OrderId")
+ .WithMany("Refunds")
+ .HasForeignKey("OrderId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Order");
});
- modelBuilder.Entity("LiteCharms.Entities.Package", b =>
- {
- b.HasOne("LiteCharms.Entities.ShoppingCart", null)
- .WithMany("Packages")
- .HasForeignKey("ShoppingCartId");
- });
-
modelBuilder.Entity("LiteCharms.Entities.PackageItem", b =>
{
b.HasOne("LiteCharms.Entities.Package", "Package")
- .WithMany()
+ .WithMany("PackageItems")
.HasForeignKey("PackageId")
- .OnDelete(DeleteBehavior.NoAction)
+ .OnDelete(DeleteBehavior.Cascade)
.IsRequired();
- b.HasOne("LiteCharms.Entities.Package", null)
- .WithMany("PackageItems")
- .HasForeignKey("PackageId1");
+ b.HasOne("LiteCharms.Entities.ProductPrice", "ProductPrice")
+ .WithMany()
+ .HasForeignKey("ProductPriceId")
+ .OnDelete(DeleteBehavior.Restrict)
+ .IsRequired();
b.Navigation("Package");
+
+ b.Navigation("ProductPrice");
});
modelBuilder.Entity("LiteCharms.Entities.ProductPrice", b =>
@@ -662,23 +651,23 @@ namespace LiteCharms.Infrastructure.Database.Migrations
modelBuilder.Entity("LiteCharms.Entities.Quote", b =>
{
b.HasOne("LiteCharms.Entities.Customer", "Customer")
- .WithMany()
+ .WithMany("Quotes")
.HasForeignKey("CustomerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
- b.HasOne("LiteCharms.Entities.Customer", null)
- .WithMany("Quotes")
- .HasForeignKey("CustomerId1");
+ b.HasOne("LiteCharms.Entities.Order", "Order")
+ .WithOne("Quote")
+ .HasForeignKey("LiteCharms.Entities.Quote", "OrderId");
b.HasOne("LiteCharms.Entities.ShoppingCart", "ShoppingCart")
.WithOne("Quote")
- .HasForeignKey("LiteCharms.Entities.Quote", "ShoppingCartId")
- .OnDelete(DeleteBehavior.NoAction)
- .IsRequired();
+ .HasForeignKey("LiteCharms.Entities.Quote", "ShoppingCartId");
b.Navigation("Customer");
+ b.Navigation("Order");
+
b.Navigation("ShoppingCart");
});
@@ -687,9 +676,17 @@ namespace LiteCharms.Infrastructure.Database.Migrations
b.HasOne("LiteCharms.Entities.Customer", "Customer")
.WithMany("ShoppingCarts")
.HasForeignKey("CustomerId")
- .OnDelete(DeleteBehavior.NoAction);
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("LiteCharms.Entities.Order", "Order")
+ .WithOne("ShoppingCart")
+ .HasForeignKey("LiteCharms.Entities.ShoppingCart", "OrderId")
+ .OnDelete(DeleteBehavior.SetNull);
b.Navigation("Customer");
+
+ b.Navigation("Order");
});
modelBuilder.Entity("LiteCharms.Entities.ShoppingCartItem", b =>
@@ -716,13 +713,13 @@ namespace LiteCharms.Infrastructure.Database.Migrations
b.HasOne("LiteCharms.Entities.Package", "Package")
.WithMany()
.HasForeignKey("PackageId")
- .OnDelete(DeleteBehavior.NoAction)
+ .OnDelete(DeleteBehavior.Restrict)
.IsRequired();
b.HasOne("LiteCharms.Entities.ShoppingCart", "ShoppingCart")
- .WithMany()
+ .WithMany("ShoppingCartPackages")
.HasForeignKey("ShoppingCartId")
- .OnDelete(DeleteBehavior.NoAction)
+ .OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Package");
@@ -743,7 +740,11 @@ namespace LiteCharms.Infrastructure.Database.Migrations
modelBuilder.Entity("LiteCharms.Entities.Order", b =>
{
- b.Navigation("Refund");
+ b.Navigation("Quote");
+
+ b.Navigation("Refunds");
+
+ b.Navigation("ShoppingCart");
});
modelBuilder.Entity("LiteCharms.Entities.Package", b =>
@@ -756,20 +757,13 @@ namespace LiteCharms.Infrastructure.Database.Migrations
b.Navigation("ProductPrices");
});
- modelBuilder.Entity("LiteCharms.Entities.Quote", b =>
- {
- b.Navigation("Order");
- });
-
modelBuilder.Entity("LiteCharms.Entities.ShoppingCart", b =>
{
- b.Navigation("Order");
-
- b.Navigation("Packages");
-
b.Navigation("Quote");
b.Navigation("ShoppingCartItems");
+
+ b.Navigation("ShoppingCartPackages");
});
#pragma warning restore 612, 618
}
diff --git a/LiteCharms.Infrastructure/Database/Migrations/20260510132008_Init.cs b/LiteCharms.Features/Shop/Postgres/Migrations/20260512065421_Init.cs
similarity index 86%
rename from LiteCharms.Infrastructure/Database/Migrations/20260510132008_Init.cs
rename to LiteCharms.Features/Shop/Postgres/Migrations/20260512065421_Init.cs
index 773f0d6..1220ecc 100644
--- a/LiteCharms.Infrastructure/Database/Migrations/20260510132008_Init.cs
+++ b/LiteCharms.Features/Shop/Postgres/Migrations/20260512065421_Init.cs
@@ -3,7 +3,7 @@ using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
-namespace LiteCharms.Infrastructure.Database.Migrations
+namespace LiteCharms.Features.Shop.Postgres.Migrations
{
///
public partial class Init : Migration
@@ -16,7 +16,7 @@ namespace LiteCharms.Infrastructure.Database.Migrations
columns: table => new
{
Id = table.Column(type: "uuid", nullable: false),
- CreatedAt = table.Column(type: "timestamp with time zone", nullable: false),
+ CreatedAt = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
UpdatedAt = table.Column(type: "timestamp with time zone", nullable: true),
Company = table.Column(type: "text", nullable: true),
Name = table.Column(type: "text", nullable: false),
@@ -46,7 +46,7 @@ namespace LiteCharms.Infrastructure.Database.Migrations
columns: table => new
{
Id = table.Column(type: "uuid", nullable: false),
- CreatedAt = table.Column(type: "timestamp with time zone", nullable: false),
+ CreatedAt = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
UpdatedAt = table.Column(type: "timestamp with time zone", nullable: true),
Direction = table.Column(type: "integer", nullable: false),
Platform = table.Column(type: "integer", nullable: false),
@@ -70,13 +70,34 @@ namespace LiteCharms.Infrastructure.Database.Migrations
table.PrimaryKey("PK_Notification", x => x.Id);
});
+ migrationBuilder.CreateTable(
+ name: "Package",
+ columns: table => new
+ {
+ Id = table.Column(type: "uuid", nullable: false),
+ CreatedAt = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
+ UpdatedAt = table.Column(type: "timestamp with time zone", nullable: true),
+ Name = table.Column(type: "text", nullable: false),
+ Summary = table.Column(type: "character varying(512)", maxLength: 512, nullable: false),
+ Description = table.Column(type: "character varying(2048)", maxLength: 2048, nullable: false),
+ ImageUrl = table.Column(type: "character varying(2048)", maxLength: 2048, nullable: true),
+ Active = table.Column(type: "boolean", nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_Package", x => x.Id);
+ });
+
migrationBuilder.CreateTable(
name: "Product",
columns: table => new
{
Id = table.Column(type: "uuid", nullable: false),
Name = table.Column(type: "text", nullable: false),
- Description = table.Column(type: "text", nullable: false),
+ Summary = table.Column(type: "character varying(512)", maxLength: 512, nullable: false),
+ Description = table.Column(type: "character varying(2048)", maxLength: 2048, nullable: false),
+ ImageUrl = table.Column(type: "character varying(2048)", maxLength: 2048, nullable: true),
+ Thumbnails = table.Column(type: "jsonb", nullable: true),
Active = table.Column(type: "boolean", nullable: false, defaultValue: true)
},
constraints: table =>
@@ -89,7 +110,7 @@ namespace LiteCharms.Infrastructure.Database.Migrations
columns: table => new
{
Id = table.Column(type: "uuid", nullable: false),
- CreatedAt = table.Column(type: "timestamp with time zone", nullable: false),
+ CreatedAt = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
UpdatedAt = table.Column(type: "timestamp with time zone", nullable: true),
CustomerId = table.Column(type: "uuid", nullable: true),
Source = table.Column(type: "text", nullable: true),
@@ -116,24 +137,28 @@ namespace LiteCharms.Infrastructure.Database.Migrations
});
migrationBuilder.CreateTable(
- name: "ShoppingCart",
+ name: "Order",
columns: table => new
{
Id = table.Column(type: "uuid", nullable: false),
- CreatedAt = table.Column(type: "timestamp with time zone", nullable: false),
+ CreatedAt = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
UpdatedAt = table.Column(type: "timestamp with time zone", nullable: true),
- CustomerId = table.Column(type: "uuid", nullable: true),
- OrderId = table.Column(type: "uuid", nullable: true),
- QuoteId = table.Column(type: "uuid", nullable: true)
+ CustomerId = table.Column(type: "uuid", nullable: false),
+ Status = table.Column(type: "integer", nullable: false),
+ Requirements = table.Column(type: "jsonb", nullable: true),
+ Notes = table.Column(type: "jsonb", nullable: true),
+ Terms = table.Column(type: "jsonb", nullable: true),
+ InvoiceUrl = table.Column(type: "character varying(2048)", maxLength: 2048, nullable: true)
},
constraints: table =>
{
- table.PrimaryKey("PK_ShoppingCart", x => x.Id);
+ table.PrimaryKey("PK_Order", x => x.Id);
table.ForeignKey(
- name: "FK_ShoppingCart_Customer_CustomerId",
+ name: "FK_Order_Customer_CustomerId",
column: x => x.CustomerId,
principalTable: "Customer",
- principalColumn: "Id");
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Restrict);
});
migrationBuilder.CreateTable(
@@ -141,7 +166,7 @@ namespace LiteCharms.Infrastructure.Database.Migrations
columns: table => new
{
Id = table.Column(type: "uuid", nullable: false),
- CreatedAt = table.Column(type: "timestamp with time zone", nullable: false),
+ CreatedAt = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
UpdatedAt = table.Column(type: "timestamp with time zone", nullable: true),
ProductId = table.Column(type: "uuid", nullable: false),
Price = table.Column(type: "numeric(18,2)", precision: 18, scale: 2, nullable: false),
@@ -160,25 +185,78 @@ namespace LiteCharms.Infrastructure.Database.Migrations
});
migrationBuilder.CreateTable(
- name: "Package",
+ name: "OrderRefund",
columns: table => new
{
Id = table.Column(type: "uuid", nullable: false),
- ShoppingCartId = table.Column(type: "uuid", nullable: true),
- CreatedAt = table.Column(type: "timestamp with time zone", nullable: false),
+ CreatedAt = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
+ OrderId = table.Column(type: "uuid", nullable: false),
+ Reason = table.Column(type: "text", nullable: false),
+ Amount = table.Column(type: "numeric(18,2)", precision: 18, scale: 2, nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_OrderRefund", x => x.Id);
+ table.ForeignKey(
+ name: "FK_OrderRefund_Order_OrderId",
+ column: x => x.OrderId,
+ principalTable: "Order",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "ShoppingCart",
+ columns: table => new
+ {
+ Id = table.Column(type: "uuid", nullable: false),
+ CreatedAt = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
UpdatedAt = table.Column(type: "timestamp with time zone", nullable: true),
- Name = table.Column(type: "text", nullable: false),
- Description = table.Column(type: "text", nullable: false),
+ CustomerId = table.Column(type: "uuid", nullable: false),
+ OrderId = table.Column(type: "uuid", nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_ShoppingCart", x => x.Id);
+ table.ForeignKey(
+ name: "FK_ShoppingCart_Customer_CustomerId",
+ column: x => x.CustomerId,
+ principalTable: "Customer",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ table.ForeignKey(
+ name: "FK_ShoppingCart_Order_OrderId",
+ column: x => x.OrderId,
+ principalTable: "Order",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.SetNull);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "PackageItem",
+ columns: table => new
+ {
+ Id = table.Column(type: "uuid", nullable: false),
+ PackageId = table.Column(type: "uuid", nullable: false),
+ ProductPriceId = table.Column(type: "uuid", nullable: false),
+ CreatedAt = table.Column