many fixes and improvements - rework for modules/ and common/

feat(emailer): add Postmark and Resend providers
This commit is contained in:
2025-06-06 12:21:43 -04:00
parent 31ba18fa8d
commit 25b94d3e02
313 changed files with 6586 additions and 18260 deletions

View File

@@ -0,0 +1,32 @@
using System.ComponentModel.DataAnnotations;
namespace Hutopy.Modules.Creators.Data;
public class Creator
{
public Guid Id { get; set; }
public Guid CreatedBy { get; set; }
public DateTimeOffset CreatedAt { get; init; }
public Guid? DeletedBy { get; set; }
public DateTimeOffset? DeletedAt { get; set; }
/// <summary>
/// Softdelete flag (false by default, true once DeletedAt is set)
/// </summary>
public bool IsDeleted { get; private set; } // private set → EF updates it
[MaxLength(2048)] public string? BannerUrl { get; set; }
[MaxLength(2048)] public string? PortraitUrl { get; set; }
public bool Verified { get; set; }
[MaxLength(256)] public required string Name { get; set; }
[MaxLength(128)] public required string Slug { get; set; }
[MaxLength(256)] public string? Title { get; set; }
[MaxLength(21)] public string? StripeAccountId { get; set; }
public bool IsStripeDetailsSubmitted { get; set; }
public bool IsStripePayoutReady { get; set; }
public bool IsStripeChargesEnabled { get; set; }
public Socials Socials { get; set; } = new();
public Presentation Presentation { get; set; } = new() { Description = "Welcome to my profile!" };
}

View File

@@ -0,0 +1,46 @@
namespace Hutopy.Modules.Creators.Data;
public class CreatorsDbContext(
DbContextOptions<CreatorsDbContext> options)
: DbContext(options)
{
public const string SchemaName = "Creators";
public DbSet<Creator> Creators => Set<Creator>();
public DbSet<Slugs> Slugs => Set<Slugs>();
protected override void OnModelCreating(
ModelBuilder modelBuilder)
{
modelBuilder.HasDefaultSchema(SchemaName);
modelBuilder
.Entity<Slugs>()
.Property(x => x.NormalizedName)
.HasComputedColumnSql("LOWER(\"Name\")", stored: true);
modelBuilder
.Entity<Slugs>()
.HasIndex(x => x.NormalizedName)
.IsUnique();
modelBuilder
.Entity<Creator>()
.Property(c => c.IsDeleted)
.HasComputedColumnSql("\"DeletedAt\" IS NOT NULL", stored: true); // bool
modelBuilder
.Entity<Creator>()
.OwnsOne<Socials>(x => x.Socials)
.ToTable(nameof(Socials));
modelBuilder
.Entity<Creator>()
.OwnsOne<Presentation>(x => x.Presentation)
.ToTable(nameof(Presentation));
modelBuilder
.Entity<Creator>()
.HasQueryFilter(c => !c.IsDeleted);
}
}

View File

@@ -0,0 +1,11 @@
using System.ComponentModel.DataAnnotations;
namespace Hutopy.Modules.Creators.Data;
public class Presentation
{
public string Description { get; set; } = null!;
[MaxLength(2048)] public string? VideoUrl { get; set; }
[MaxLength(256)] public string? PhoneNumber { get; set; }
[MaxLength(256)] public string? Email { get; set; }
}

View File

@@ -0,0 +1,14 @@
using System.ComponentModel.DataAnnotations;
namespace Hutopy.Modules.Creators.Data;
public class Slugs
{
public Guid Id { get; set; }
public Guid CreatedBy { get; set; }
public DateTimeOffset CreatedAt { get; init; }
public Guid? UsedBy { get; set; }
[MaxLength(128)] public string Name { get; set; } = null!;
[MaxLength(128)] public string NormalizedName { get; set; } = null!;
public DateTimeOffset ReservedUntil { get; set; }
}

View File

@@ -0,0 +1,15 @@
using System.ComponentModel.DataAnnotations;
namespace Hutopy.Modules.Creators.Data;
public class Socials
{
[MaxLength(2048)] public string? FacebookUrl { get; set; }
[MaxLength(2048)] public string? InstagramUrl { get; set; }
[MaxLength(2048)] public string? XUrl { get; set; }
[MaxLength(2048)] public string? LinkedInUrl { get; set; }
[MaxLength(2048)] public string? TikTokUrl { get; set; }
[MaxLength(2048)] public string? YoutubeUrl { get; set; }
[MaxLength(2048)] public string? RedditUrl { get; set; }
[MaxLength(2048)] public string? WebsiteUrl { get; set; }
}