feat(email): include drafts in user exports
CI and Deploy / test (pull_request) Successful in 4m14s
CI and Deploy / deploy (pull_request) Has been skipped

Export readable private draft content only through existing owner-filtered encrypted and daily export boundaries, with cross-tenant regression coverage.
This commit is contained in:
cesnimda
2026-08-10 10:00:34 +02:00
parent 10740fd8c3
commit 2fa4e38ba9
5 changed files with 98 additions and 1 deletions
@@ -89,6 +89,21 @@ namespace JobTrackerApi.Controllers
attempt.StartedAtUtc,
attempt.CompletedAtUtc))
.ToListAsync(cancellationToken);
var emailDrafts = await _db.EmailDrafts.AsNoTracking()
.Where(draft => jobIds.Contains(draft.JobApplicationId))
.OrderBy(draft => draft.UpdatedAtUtc)
.Select(draft => new EmailDraftExport(
draft.Id,
draft.JobApplicationId,
draft.Provider,
draft.To,
draft.Subject,
draft.BodyText,
draft.ThreadId,
draft.Revision,
draft.CreatedAtUtc,
draft.UpdatedAtUtc))
.ToListAsync(cancellationToken);
var rules = await _db.RuleSettings.AsNoTracking().FirstOrDefaultAsync(cancellationToken);
return new
@@ -99,6 +114,7 @@ namespace JobTrackerApi.Controllers
Attachments = attachments,
Events = events,
EmailSendAttempts = emailSendAttempts,
EmailDrafts = emailDrafts,
Rules = rules
};
}
+12
View File
@@ -15,3 +15,15 @@ public sealed class EmailDraft
public DateTime CreatedAtUtc { get; set; }
public DateTime UpdatedAtUtc { get; set; }
}
public sealed record EmailDraftExport(
Guid Id,
int JobApplicationId,
string Provider,
string To,
string Subject,
string BodyText,
string? ThreadId,
long Revision,
DateTime CreatedAtUtc,
DateTime UpdatedAtUtc);
@@ -77,6 +77,21 @@ public sealed class DailyExportHostedService(
attempt.StartedAtUtc,
attempt.CompletedAtUtc))
.ToListAsync(cancellationToken),
EmailDrafts = await db.EmailDrafts.AsNoTracking()
.Where(draft => jobIds.Contains(draft.JobApplicationId))
.OrderBy(draft => draft.UpdatedAtUtc)
.Select(draft => new EmailDraftExport(
draft.Id,
draft.JobApplicationId,
draft.Provider,
draft.To,
draft.Subject,
draft.BodyText,
draft.ThreadId,
draft.Revision,
draft.CreatedAtUtc,
draft.UpdatedAtUtc))
.ToListAsync(cancellationToken),
Rules = await RulesEngine.GetSettings(db, cancellationToken),
};