feat(email): add durable send ledger
Tracks only idempotency and delivery metadata; recipient, subject, and body are excluded. No provider send path is enabled.
This commit is contained in:
@@ -61,6 +61,7 @@ namespace JobTrackerApi.Data
|
||||
public DbSet<InterviewPrepItem> InterviewPrepItems => Set<InterviewPrepItem>();
|
||||
public DbSet<UserOperation> UserOperations => Set<UserOperation>();
|
||||
public DbSet<UserNotification> UserNotifications => Set<UserNotification>();
|
||||
public DbSet<EmailSendAttempt> EmailSendAttempts => Set<EmailSendAttempt>();
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||
{
|
||||
@@ -259,6 +260,26 @@ namespace JobTrackerApi.Data
|
||||
.HasForeignKey<UserNotification>(x => x.OperationId)
|
||||
.OnDelete(DeleteBehavior.SetNull);
|
||||
|
||||
modelBuilder.Entity<EmailSendAttempt>()
|
||||
.HasQueryFilter(x => CurrentUserId != null && x.OwnerUserId == CurrentUserId);
|
||||
modelBuilder.Entity<EmailSendAttempt>().Property(x => x.OwnerUserId).HasMaxLength(255);
|
||||
modelBuilder.Entity<EmailSendAttempt>().Property(x => x.Provider).HasMaxLength(32);
|
||||
modelBuilder.Entity<EmailSendAttempt>().Property(x => x.ClientRequestId).HasMaxLength(128);
|
||||
modelBuilder.Entity<EmailSendAttempt>().Property(x => x.PayloadHash).HasMaxLength(64);
|
||||
modelBuilder.Entity<EmailSendAttempt>().Property(x => x.Status).HasMaxLength(32);
|
||||
modelBuilder.Entity<EmailSendAttempt>().Property(x => x.ProviderMessageId).HasMaxLength(256);
|
||||
modelBuilder.Entity<EmailSendAttempt>().Property(x => x.FailureCategory).HasMaxLength(64);
|
||||
modelBuilder.Entity<EmailSendAttempt>()
|
||||
.HasIndex(x => new { x.OwnerUserId, x.ClientRequestId })
|
||||
.IsUnique();
|
||||
modelBuilder.Entity<EmailSendAttempt>()
|
||||
.HasIndex(x => new { x.OwnerUserId, x.CreatedAtUtc });
|
||||
modelBuilder.Entity<EmailSendAttempt>()
|
||||
.HasOne(x => x.JobApplication)
|
||||
.WithMany()
|
||||
.HasForeignKey(x => x.JobApplicationId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
modelBuilder.Entity<TailoredCvDraft>()
|
||||
.HasQueryFilter(x => CurrentUserId != null && x.OwnerUserId == CurrentUserId);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user