feat(application): Add AutoMapper profiles for all entities

- EmailProfileMappingProfile: Command→Entity, DTO→Entity, Entity→DTO
- EmailAccountMappingProfile: Command→Entity, Entity→DTO
- EmailHistoryMappingProfile: CreateDto→Entity, UpdateDto partial mapping, Entity→DTO
- EmailAttachmentMappingProfile: CreateDto→Entity, UpdateDto partial mapping, Entity→DTO

All mappings follow Repository<T> pattern with AutoMapper-based CRUD
This commit is contained in:
2026-07-14 16:37:11 +02:00
parent eda6257145
commit 1ed489532d
4 changed files with 182 additions and 0 deletions

View File

@@ -0,0 +1,27 @@
using AutoMapper;
using DigitalData.EmailProfiler.Application.Common.Dtos;
using DigitalData.EmailProfiler.Application.Features.EmailAccounts.Commands;
using DigitalData.EmailProfiler.Domain.Entities;
namespace DigitalData.EmailProfiler.Application.Common.Mappings;
/// <summary>
/// AutoMapper profile for EmailAccount entity mappings.
/// </summary>
public class EmailAccountMappingProfile : Profile
{
public EmailAccountMappingProfile()
{
// Command -> Entity (for Create)
CreateMap<CreateEmailAccountCommand, EmailAccount>()
.ForMember(dest => dest.Id, opt => opt.Ignore()) // Auto-generated
.ForMember(dest => dest.AddedWhen, opt => opt.MapFrom(_ => DateTime.Now))
.ForMember(dest => dest.AddedWho, opt => opt.MapFrom(_ => "System")) // TODO: Get from user context
.ForMember(dest => dest.ChangedWhen, opt => opt.Ignore())
.ForMember(dest => dest.ChangedWho, opt => opt.Ignore())
.ForMember(dest => dest.Profiles, opt => opt.Ignore());
// Entity -> DTO (for Queries)
CreateMap<EmailAccount, EmailAccountDto>();
}
}

View File

@@ -0,0 +1,51 @@
using AutoMapper;
using DigitalData.EmailProfiler.Application.Common.Dtos.EmailAttachments;
using DigitalData.EmailProfiler.Domain.Entities;
using DigitalData.EmailProfiler.Domain.Enums;
namespace DigitalData.EmailProfiler.Application.Common.Mappings;
/// <summary>
/// AutoMapper profile for EmailAttachment entity mappings.
/// </summary>
public class EmailAttachmentMappingProfile : Profile
{
public EmailAttachmentMappingProfile()
{
// DTO -> Entity (for Create)
CreateMap<CreateEmailAttachmentDto, EmailAttachment>()
.ForMember(dest => dest.Id, opt => opt.Ignore()) // Auto-generated
.ForMember(dest => dest.Status, opt => opt.MapFrom(_ => AttachmentStatus.Pending.ToString()))
.ForMember(dest => dest.AddedWhen, opt => opt.MapFrom(_ => DateTime.Now))
.ForMember(dest => dest.IsEmbeddedFile, opt => opt.MapFrom(_ => false))
.ForMember(dest => dest.ParentAttachmentId, opt => opt.Ignore())
.ForMember(dest => dest.AttachmentPosition, opt => opt.MapFrom(_ => 0))
.ForMember(dest => dest.ValidationErrorCode, opt => opt.Ignore())
.ForMember(dest => dest.ValidationErrorMessage, opt => opt.Ignore())
.ForMember(dest => dest.Comment, opt => opt.Ignore())
.ForMember(dest => dest.EmailHistory, opt => opt.Ignore())
.ForMember(dest => dest.ParentAttachment, opt => opt.Ignore())
.ForMember(dest => dest.EmbeddedFiles, opt => opt.Ignore());
// DTO -> Entity (for Update Status)
CreateMap<UpdateEmailAttachmentStatusDto, EmailAttachment>()
.ForMember(dest => dest.Id, opt => opt.Ignore())
.ForMember(dest => dest.EmailHistoryId, opt => opt.Ignore())
.ForMember(dest => dest.OriginalFileName, opt => opt.Ignore())
.ForMember(dest => dest.SavedFileName, opt => opt.Ignore())
.ForMember(dest => dest.FilePath, opt => opt.Ignore())
.ForMember(dest => dest.FileSize, opt => opt.Ignore())
.ForMember(dest => dest.Extension, opt => opt.Ignore())
.ForMember(dest => dest.IsEmbeddedFile, opt => opt.Ignore())
.ForMember(dest => dest.ParentAttachmentId, opt => opt.Ignore())
.ForMember(dest => dest.AttachmentPosition, opt => opt.Ignore())
.ForMember(dest => dest.Comment, opt => opt.Ignore())
.ForMember(dest => dest.AddedWhen, opt => opt.Ignore())
.ForMember(dest => dest.EmailHistory, opt => opt.Ignore())
.ForMember(dest => dest.ParentAttachment, opt => opt.Ignore())
.ForMember(dest => dest.EmbeddedFiles, opt => opt.Ignore());
// Entity -> DTO (for Queries)
CreateMap<EmailAttachment, EmailAttachmentDto>();
}
}

View File

@@ -0,0 +1,59 @@
using AutoMapper;
using DigitalData.EmailProfiler.Application.Common.Dtos.EmailHistories;
using DigitalData.EmailProfiler.Domain.Entities;
using DigitalData.EmailProfiler.Domain.Enums;
namespace DigitalData.EmailProfiler.Application.Common.Mappings;
/// <summary>
/// AutoMapper profile for EmailHistory entity mappings.
/// </summary>
public class EmailHistoryMappingProfile : Profile
{
public EmailHistoryMappingProfile()
{
// DTO -> Entity (for Create)
CreateMap<CreateEmailHistoryDto, EmailHistory>()
.ForMember(dest => dest.Id, opt => opt.Ignore()) // Auto-generated
.ForMember(dest => dest.EmailMessageId, opt => opt.Ignore()) // Auto-generated
.ForMember(dest => dest.Status, opt => opt.MapFrom(_ => EmailStatus.Processing.ToString()))
.ForMember(dest => dest.AddedWhen, opt => opt.MapFrom(_ => DateTime.Now))
.ForMember(dest => dest.ProcessedDate, opt => opt.Ignore())
.ForMember(dest => dest.ErrorCodeValue, opt => opt.Ignore())
.ForMember(dest => dest.ErrorMessage, opt => opt.Ignore())
.ForMember(dest => dest.WindreamDocumentId, opt => opt.Ignore())
.ForMember(dest => dest.Comment, opt => opt.Ignore())
.ForMember(dest => dest.WorkProcess, opt => opt.Ignore())
.ForMember(dest => dest.ImapUid, opt => opt.Ignore())
.ForMember(dest => dest.EmailSubstring1, opt => opt.Ignore())
.ForMember(dest => dest.EmailSubstring2, opt => opt.Ignore())
.ForMember(dest => dest.Profile, opt => opt.Ignore())
.ForMember(dest => dest.Attachments, opt => opt.Ignore());
// DTO -> Entity (for Update Status)
CreateMap<UpdateEmailHistoryStatusDto, EmailHistory>()
.ForMember(dest => dest.Id, opt => opt.Ignore())
.ForMember(dest => dest.ProfileId, opt => opt.Ignore())
.ForMember(dest => dest.MessageIdHash, opt => opt.Ignore())
.ForMember(dest => dest.OriginalMessageId, opt => opt.Ignore())
.ForMember(dest => dest.SenderAddress, opt => opt.Ignore())
.ForMember(dest => dest.EmailDate, opt => opt.Ignore())
.ForMember(dest => dest.Subject, opt => opt.Ignore())
.ForMember(dest => dest.EmailBodyText, opt => opt.Ignore())
.ForMember(dest => dest.EmailBodyHtml, opt => opt.Ignore())
.ForMember(dest => dest.EmailMessageId, opt => opt.Ignore())
.ForMember(dest => dest.AddedWhen, opt => opt.Ignore())
.ForMember(dest => dest.WindreamDocumentId, opt => opt.Ignore())
.ForMember(dest => dest.Comment, opt => opt.Ignore())
.ForMember(dest => dest.WorkProcess, opt => opt.Ignore())
.ForMember(dest => dest.ImapUid, opt => opt.Ignore())
.ForMember(dest => dest.EmailSubstring1, opt => opt.Ignore())
.ForMember(dest => dest.EmailSubstring2, opt => opt.Ignore())
.ForMember(dest => dest.Profile, opt => opt.Ignore())
.ForMember(dest => dest.Attachments, opt => opt.Ignore());
// Entity -> DTO (for Queries)
CreateMap<EmailHistory, EmailHistoryDto>()
.ForMember(dest => dest.ProfileName, opt => opt.MapFrom(src => src.Profile != null ? src.Profile.ProfileName : null));
}
}

View File

@@ -0,0 +1,45 @@
using AutoMapper;
using DigitalData.EmailProfiler.Application.Common.Dtos;
using DigitalData.EmailProfiler.Application.Features.EmailProfiles.Commands;
using DigitalData.EmailProfiler.Domain.Entities;
namespace DigitalData.EmailProfiler.Application.Common.Mappings;
/// <summary>
/// AutoMapper profile for EmailProfile entity mappings.
/// </summary>
public class EmailProfileMappingProfile : Profile
{
public EmailProfileMappingProfile()
{
// Command -> Entity (for Create)
CreateMap<CreateEmailProfileCommand, EmailProfile>()
.ForMember(dest => dest.Id, opt => opt.Ignore()) // Auto-generated
.ForMember(dest => dest.AddedWhen, opt => opt.MapFrom(_ => DateTime.Now))
.ForMember(dest => dest.AddedWho, opt => opt.MapFrom(_ => "System")) // TODO: Get from user context
.ForMember(dest => dest.ChangedWhen, opt => opt.Ignore())
.ForMember(dest => dest.ChangedWho, opt => opt.Ignore())
.ForMember(dest => dest.LastPollTime, opt => opt.Ignore())
.ForMember(dest => dest.EmailAccount, opt => opt.Ignore())
.ForMember(dest => dest.EmailProcess, opt => opt.Ignore());
// Command -> Entity (for Update)
CreateMap<UpdateEmailProfileCommand, EmailProfile>()
.ForMember(dest => dest.Id, opt => opt.Ignore()) // Don't update ID
.ForMember(dest => dest.EmailAccountId, opt => opt.Ignore()) // Don't change account
.ForMember(dest => dest.ProcessId, opt => opt.Ignore()) // Don't change process
.ForMember(dest => dest.AddedWhen, opt => opt.Ignore())
.ForMember(dest => dest.AddedWho, opt => opt.Ignore())
.ForMember(dest => dest.ChangedWhen, opt => opt.MapFrom(_ => DateTime.Now))
.ForMember(dest => dest.ChangedWho, opt => opt.MapFrom(_ => "System")) // TODO: Get from user context
.ForMember(dest => dest.LastPollTime, opt => opt.Ignore())
.ForMember(dest => dest.EmailAccount, opt => opt.Ignore())
.ForMember(dest => dest.EmailProcess, opt => opt.Ignore());
// Entity -> DTO (for Queries)
CreateMap<EmailProfile, EmailProfileDto>()
.ForMember(dest => dest.EmailAccountName, opt => opt.MapFrom(src => src.EmailAccount != null ? src.EmailAccount.AccountName : null))
.ForMember(dest => dest.ProcessName, opt => opt.MapFrom(src => src.EmailProcess != null ? src.EmailProcess.ProcessName : null))
.ForMember(dest => dest.LastPollTime, opt => opt.MapFrom(src => src.LastPollTime));
}
}