diff --git a/src/DigitalData.EmailProfiler.Domain/Entities/EmailAccount.cs b/src/DigitalData.EmailProfiler.Domain/Entities/EmailAccount.cs new file mode 100644 index 0000000..444bb34 --- /dev/null +++ b/src/DigitalData.EmailProfiler.Domain/Entities/EmailAccount.cs @@ -0,0 +1,107 @@ +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using DigitalData.EmailProfiler.Domain.Common; +using DigitalData.EmailProfiler.Domain.Enums; + +namespace DigitalData.EmailProfiler.Domain.Entities; + +[Table("TBDD_EMAIL_ACCOUNT")] +public class EmailAccount : BaseEntity, IAggregateRoot +{ + [Key] + [Column("EMAIL_ACCOUNT_ID", Order = 0)] + [DatabaseGenerated(DatabaseGeneratedOption.Identity)] + public int Id { get; set; } + + [Column("ACCOUNT_NAME", TypeName = "varchar(100)")] + [Required] + [MaxLength(100)] + public string AccountName { get; set; } = string.Empty; + + // IMAP Configuration + [Column("IMAP_SERVER", TypeName = "varchar(200)")] + [Required] + [MaxLength(200)] + public string ImapServer { get; set; } = string.Empty; + + [Column("IMAP_PORT")] + [Required] + public int ImapPort { get; set; } + + [Column("IMAP_USE_SSL")] + public bool ImapUseSsl { get; set; } = true; + + // SMTP Configuration + [Column("SMTP_SERVER", TypeName = "varchar(200)")] + [Required] + [MaxLength(200)] + public string SmtpServer { get; set; } = string.Empty; + + [Column("SMTP_PORT")] + [Required] + public int SmtpPort { get; set; } + + [Column("SMTP_USE_SSL")] + public bool SmtpUseSsl { get; set; } = true; + + // Authentication + [Column("USERNAME", TypeName = "varchar(200)")] + [Required] + [MaxLength(200)] + public string Username { get; set; } = string.Empty; + + [Column("PASSWORD", TypeName = "varchar(500)")] + [MaxLength(500)] + public string? EncryptedPassword { get; set; } + + [Column("USE_OAUTH2")] + public bool UseOAuth2 { get; set; } + + // OAuth2 (nullable) + [Column("CLIENT_ID", TypeName = "varchar(200)")] + [MaxLength(200)] + public string? ClientId { get; set; } + + [Column("TENANT_ID", TypeName = "varchar(200)")] + [MaxLength(200)] + public string? TenantId { get; set; } + + [Column("CLIENT_SECRET", TypeName = "varchar(500)")] + [MaxLength(500)] + public string? EncryptedClientSecret { get; set; } + + // Status + [Column("ACTIVE")] + public bool IsActive { get; set; } = true; + + [Column("SEQUENCE")] + public int? Sequence { get; set; } + + [Column("COMMENT", TypeName = "varchar(500)")] + [MaxLength(500)] + public string? Comment { get; set; } + + // Audit fields + [Column("ADDED_WHO", TypeName = "varchar(50)")] + [MaxLength(50)] + public string? AddedWho { get; set; } + + [Column("ADDED_WHEN")] + public DateTime? AddedWhen { get; set; } + + [Column("CHANGED_WHO", TypeName = "varchar(50)")] + [MaxLength(50)] + public string? ChangedWho { get; set; } + + [Column("CHANGED_WHEN")] + public DateTime? ChangedWhen { get; set; } + + // Navigation properties + public virtual ICollection Profiles { get; set; } = new List(); + + // Domain methods + public AuthenticationType GetAuthenticationType() => UseOAuth2 ? AuthenticationType.OAuth2 : AuthenticationType.UsernamePassword; + + public void Activate() => IsActive = true; + public void Deactivate() => IsActive = false; +} diff --git a/src/DigitalData.EmailProfiler.Domain/Entities/EmailAttachment.cs b/src/DigitalData.EmailProfiler.Domain/Entities/EmailAttachment.cs new file mode 100644 index 0000000..69a127f --- /dev/null +++ b/src/DigitalData.EmailProfiler.Domain/Entities/EmailAttachment.cs @@ -0,0 +1,93 @@ +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using DigitalData.EmailProfiler.Domain.Common; +using DigitalData.EmailProfiler.Domain.Enums; + +namespace DigitalData.EmailProfiler.Domain.Entities; + +[Table("TBEMLP_HISTORY_ATTACHMENT")] +public class EmailAttachment : BaseEntity +{ + [Key] + [Column("GUID", Order = 0)] + [DatabaseGenerated(DatabaseGeneratedOption.Identity)] + public int Id { get; set; } + + [Column("EMAIL_HISTORY_ID")] + [Required] + public int EmailHistoryId { get; set; } + + // File information + [Column("ORIGINAL_FILE_NAME", TypeName = "varchar(500)")] + [Required] + [MaxLength(500)] + public string OriginalFileName { get; set; } = string.Empty; + + [Column("SAVED_FILE_NAME", TypeName = "varchar(500)")] + [Required] + [MaxLength(500)] + public string SavedFileName { get; set; } = string.Empty; + + [Column("FILE_PATH", TypeName = "varchar(1000)")] + [Required] + [MaxLength(1000)] + public string FilePath { get; set; } = string.Empty; + + [Column("FILE_SIZE")] + public long FileSize { get; set; } + + [Column("EXTENSION", TypeName = "varchar(20)")] + [MaxLength(20)] + public string Extension { get; set; } = string.Empty; + + // Attachment hierarchy + [Column("IS_EMBEDDED_FILE")] + public bool IsEmbeddedFile { get; set; } + + [Column("PARENT_ATTACHMENT_ID")] + public int? ParentAttachmentId { get; set; } + + [Column("ATTACHMENT_POSITION")] + public int AttachmentPosition { get; set; } + + // Validation + [Column("STATUS", TypeName = "varchar(50)")] + [MaxLength(50)] + public string? Status { get; set; } + + [Column("VALIDATION_ERROR_CODE")] + public int? ValidationErrorCode { get; set; } + + [Column("VALIDATION_ERROR_MESSAGE", TypeName = "nvarchar(max)")] + public string? ValidationErrorMessage { get; set; } + + [Column("COMMENT", TypeName = "varchar(500)")] + [MaxLength(500)] + public string? Comment { get; set; } + + // Audit field + [Column("ADDED_WHEN")] + public DateTime? AddedWhen { get; set; } + + // Navigation properties + [ForeignKey("EmailHistoryId")] + public virtual EmailHistory? EmailHistory { get; set; } + + [ForeignKey("ParentAttachmentId")] + public virtual EmailAttachment? ParentAttachment { get; set; } + + public virtual ICollection EmbeddedFiles { get; set; } = new List(); + + // Domain methods + public void MarkAsValid() + { + Status = AttachmentStatus.Valid.ToString(); + } + + public void MarkAsCorrupt(ErrorCode errorCode, string message) + { + Status = AttachmentStatus.Corrupt.ToString(); + ValidationErrorCode = (int)errorCode; + ValidationErrorMessage = message; + } +} diff --git a/src/DigitalData.EmailProfiler.Domain/Entities/EmailHistory.cs b/src/DigitalData.EmailProfiler.Domain/Entities/EmailHistory.cs new file mode 100644 index 0000000..a262d64 --- /dev/null +++ b/src/DigitalData.EmailProfiler.Domain/Entities/EmailHistory.cs @@ -0,0 +1,112 @@ +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using DigitalData.EmailProfiler.Domain.Common; +using DigitalData.EmailProfiler.Domain.Enums; + +namespace DigitalData.EmailProfiler.Domain.Entities; + +[Table("TBEMLP_HISTORY")] +public class EmailHistory : BaseEntity +{ + [Key] + [Column("GUID", Order = 0)] + [DatabaseGenerated(DatabaseGeneratedOption.Identity)] + public int Id { get; set; } + + [Column("PROFILE_ID")] + public int? ProfileId { get; set; } + + [Column("WORK_PROCESS", TypeName = "varchar(100)")] + [MaxLength(100)] + public string? WorkProcess { get; set; } + + // Email identification + [Column("EMAIL_MSGID")] + [Required] + public int EmailMessageId { get; set; } + + [Column("EMAIL_MSGID_HASH", TypeName = "varchar(100)")] + [MaxLength(100)] + public string? MessageIdHash { get; set; } + + [Column("EMAIL_MSGID_ORIGINAL", TypeName = "varchar(500)")] + [MaxLength(500)] + public string? OriginalMessageId { get; set; } + + [Column("IMAP_UID")] + public int? ImapUid { get; set; } + + // Email metadata + [Column("EMAIL_SENDER", TypeName = "varchar(200)")] + [MaxLength(200)] + public string? SenderAddress { get; set; } + + [Column("EMAIL_SUBJECT", TypeName = "varchar(500)")] + [MaxLength(500)] + public string? Subject { get; set; } + + [Column("EMAIL_DATE")] + public DateTime? EmailDate { get; set; } + + [Column("EMAIL_BODY", TypeName = "nvarchar(max)")] + public string? EmailBodyHtml { get; set; } + + [Column("EMAIL_BODY_TEXT", TypeName = "nvarchar(max)")] + public string? EmailBodyText { get; set; } + + [Column("EMAIL_SUBSTRING1", TypeName = "varchar(500)")] + [MaxLength(500)] + public string? EmailSubstring1 { get; set; } + + [Column("EMAIL_SUBSTRING2", TypeName = "varchar(500)")] + [MaxLength(500)] + public string? EmailSubstring2 { get; set; } + + // Processing + [Column("PROCESSED_DATE")] + public DateTime? ProcessedDate { get; set; } + + [Column("STATUS", TypeName = "varchar(50)")] + [MaxLength(50)] + public string? Status { get; set; } + + [Column("ERROR_CODE")] + public int? ErrorCodeValue { get; set; } + + [Column("ERROR_MESSAGE", TypeName = "nvarchar(max)")] + public string? ErrorMessage { get; set; } + + // windream + [Column("WINDREAM_DOCUMENT_ID", TypeName = "varchar(100)")] + [MaxLength(100)] + public string? WindreamDocumentId { get; set; } + + [Column("COMMENT", TypeName = "varchar(500)")] + [MaxLength(500)] + public string? Comment { get; set; } + + // Audit field + [Column("ADDED_WHEN")] + public DateTime? AddedWhen { get; set; } + + // Navigation properties + [ForeignKey("ProfileId")] + public virtual EmailProfile? Profile { get; set; } + + public virtual ICollection Attachments { get; set; } = new List(); + + // Domain methods + public void MarkAsProcessed() + { + Status = EmailStatus.Processed.ToString(); + ProcessedDate = DateTime.UtcNow; + } + + public void MarkAsFailed(ErrorCode errorCode, string message) + { + Status = EmailStatus.Failed.ToString(); + ErrorCodeValue = (int)errorCode; + ErrorMessage = message; + ProcessedDate = DateTime.UtcNow; + } +} diff --git a/src/DigitalData.EmailProfiler.Domain/Entities/EmailOutbox.cs b/src/DigitalData.EmailProfiler.Domain/Entities/EmailOutbox.cs new file mode 100644 index 0000000..f6c4833 --- /dev/null +++ b/src/DigitalData.EmailProfiler.Domain/Entities/EmailOutbox.cs @@ -0,0 +1,60 @@ +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using DigitalData.EmailProfiler.Domain.Common; + +namespace DigitalData.EmailProfiler.Domain.Entities; + +[Table("TBEMLP_EMAIL_OUT")] +public class EmailOutbox : BaseEntity +{ + [Key] + [Column("GUID", Order = 0)] + [DatabaseGenerated(DatabaseGeneratedOption.Identity)] + public int Id { get; set; } + + [Column("EMAIL_ACCOUNT_ID")] + [Required] + public int EmailAccountId { get; set; } + + [Column("RECIPIENT", TypeName = "varchar(200)")] + [Required] + [MaxLength(200)] + public string Recipient { get; set; } = string.Empty; + + [Column("SUBJECT", TypeName = "nvarchar(500)")] + [Required] + [MaxLength(500)] + public string Subject { get; set; } = string.Empty; + + [Column("BODY", TypeName = "nvarchar(max)")] + [Required] + public string Body { get; set; } = string.Empty; + + [Column("IS_HTML")] + public bool IsHtml { get; set; } = true; + + [Column("SENT")] + public bool Sent { get; set; } + + [Column("SENT_DATE")] + public DateTime? SentDate { get; set; } + + [Column("RETRY_COUNT")] + public int RetryCount { get; set; } + + [Column("REFERENCE_STRING", TypeName = "varchar(200)")] + [MaxLength(200)] + public string? ReferenceId { get; set; } + + [Column("COMMENT", TypeName = "varchar(500)")] + [MaxLength(500)] + public string? Comment { get; set; } + + // Audit field + [Column("ADDED_WHEN")] + public DateTime? AddedWhen { get; set; } + + // Navigation properties + [ForeignKey("EmailAccountId")] + public virtual EmailAccount? EmailAccount { get; set; } +} diff --git a/src/DigitalData.EmailProfiler.Domain/Entities/EmailProcess.cs b/src/DigitalData.EmailProfiler.Domain/Entities/EmailProcess.cs new file mode 100644 index 0000000..d310933 --- /dev/null +++ b/src/DigitalData.EmailProfiler.Domain/Entities/EmailProcess.cs @@ -0,0 +1,114 @@ +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using DigitalData.EmailProfiler.Domain.Common; +using DigitalData.EmailProfiler.Domain.Enums; + +namespace DigitalData.EmailProfiler.Domain.Entities; + +[Table("TBEMLP_POLL_PROCESS")] +public class EmailProcess : BaseEntity +{ + [Key] + [Column("GUID", Order = 0)] + [DatabaseGenerated(DatabaseGeneratedOption.Identity)] + public int Id { get; set; } + + [Column("PROCESS_NAME", TypeName = "varchar(100)")] + [Required] + [MaxLength(100)] + public string ProcessName { get; set; } = string.Empty; + + [Column("STEP_NAME", TypeName = "varchar(100)")] + [Required] + [MaxLength(100)] + public string StepName { get; set; } = string.Empty; + + [Column("PROFILE_ID")] + public int? ProfileId { get; set; } + + // Configuration + [Column("COPY_2_HDD")] + public bool CopyToHdd { get; set; } + + [Column("DELETE_MAIL")] + public bool DeleteEmailAfterProcessing { get; set; } + + // Paths + [Column("PATH_EMAIL_TEMP", TypeName = "varchar(500)")] + [Required] + [MaxLength(500)] + public string TempPath { get; set; } = string.Empty; + + [Column("PATH_EMAIL_ERRORS", TypeName = "varchar(500)")] + [Required] + [MaxLength(500)] + public string ErrorPath { get; set; } = string.Empty; + + [Column("PATH_ORIGINAL", TypeName = "varchar(500)")] + [MaxLength(500)] + public string? ArchivePath { get; set; } + + // windream + [Column("WM_IMPORT")] + public bool EnableWindreamImport { get; set; } + + [Column("WM_OBJEKTTYPE", TypeName = "varchar(100)")] + [MaxLength(100)] + public string? WindreamObjectType { get; set; } + + [Column("WM_VECTOR_LOG", TypeName = "varchar(500)")] + [MaxLength(500)] + public string? WindreamVectorLog { get; set; } + + [Column("WM_PATH", TypeName = "varchar(500)")] + [MaxLength(500)] + public string? WindreamPath { get; set; } + + [Column("WM_FILE_NAME", TypeName = "varchar(200)")] + [MaxLength(200)] + public string? WindreamFileName { get; set; } + + [Column("WM_REFERENCE_INDEX", TypeName = "varchar(100)")] + [MaxLength(100)] + public string? WindreamReferenceIndex { get; set; } + + [Column("WM_IDX_BODY_TEXT", TypeName = "varchar(100)")] + [MaxLength(100)] + public string? WindreamIndexBodyText { get; set; } + + [Column("WM_IDX_BODY_SUBSTR_LENGTH")] + public int WindreamIndexBodySubstrLength { get; set; } + + [Column("ALLOW_XML_RECEIPTS")] + public bool? AllowXmlReceipts { get; set; } + + // Status + [Column("ACTIVE")] + public bool IsActive { get; set; } = true; + + [Column("SEQUENCE")] + public int? Sequence { get; set; } + + [Column("COMMENT", TypeName = "varchar(500)")] + [MaxLength(500)] + public string? Comment { get; set; } + + // Audit fields + [Column("ADDED_WHO", TypeName = "varchar(50)")] + [MaxLength(50)] + public string? AddedWho { get; set; } + + [Column("ADDED_WHEN")] + public DateTime? AddedWhen { get; set; } + + [Column("CHANGED_WHO", TypeName = "varchar(50)")] + [MaxLength(50)] + public string? ChangedWho { get; set; } + + [Column("CHANGED_WHEN")] + public DateTime? ChangedWhen { get; set; } + + // Navigation properties + public virtual ICollection Steps { get; set; } = new List(); + public virtual ICollection Profiles { get; set; } = new List(); +} diff --git a/src/DigitalData.EmailProfiler.Domain/Entities/EmailProfile.cs b/src/DigitalData.EmailProfiler.Domain/Entities/EmailProfile.cs new file mode 100644 index 0000000..b6b965e --- /dev/null +++ b/src/DigitalData.EmailProfiler.Domain/Entities/EmailProfile.cs @@ -0,0 +1,88 @@ +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using DigitalData.EmailProfiler.Domain.Common; + +namespace DigitalData.EmailProfiler.Domain.Entities; + +[Table("TBEMLP_POLL_PROFILES")] +public class EmailProfile : BaseEntity, IAggregateRoot +{ + [Key] + [Column("GUID", Order = 0)] + [DatabaseGenerated(DatabaseGeneratedOption.Identity)] + public int Id { get; set; } + + [Column("PROFILE_NAME", TypeName = "varchar(100)")] + [Required] + [MaxLength(100)] + public string ProfileName { get; set; } = string.Empty; + + [Column("POLL_TYPE", TypeName = "varchar(100)")] + [Required] + [MaxLength(100)] + public string PollType { get; set; } = "IMAP"; + + [Column("EMAIL_CONF_ID")] + [Required] + public int EmailAccountId { get; set; } + + [Column("PROCESS_ID")] + public int? ProcessId { get; set; } + + // Polling Configuration + [Column("POLL_INTERVAL")] + public int PollIntervalMinutes { get; set; } = 5; + + [Column("LAST_TICK")] + public DateTime? LastPollTime { get; set; } + + // Validation + [Column("VALIDATION_SQL", TypeName = "nvarchar(1024)")] + [MaxLength(1024)] + public string? ValidationSql { get; set; } + + // Status + [Column("ACTIVE")] + public bool IsActive { get; set; } + + [Column("SEQUENCE")] + public int? Sequence { get; set; } + + [Column("COMMENT", TypeName = "varchar(500)")] + [MaxLength(500)] + public string? Comment { get; set; } + + // Audit fields + [Column("ADDED_WHO", TypeName = "varchar(50)")] + [MaxLength(50)] + public string? AddedWho { get; set; } + + [Column("ADDED_WHEN")] + public DateTime? AddedWhen { get; set; } + + [Column("CHANGED_WHO", TypeName = "varchar(50)")] + [MaxLength(50)] + public string? ChangedWho { get; set; } + + [Column("CHANGED_WHEN")] + public DateTime? ChangedWhen { get; set; } + + // Navigation properties + [ForeignKey("EmailAccountId")] + public virtual EmailAccount? EmailAccount { get; set; } + + [ForeignKey("ProcessId")] + public virtual EmailProcess? EmailProcess { get; set; } + + public virtual ICollection EmailHistories { get; set; } = new List(); + + // Domain methods + public void UpdateLastPollTime() => LastPollTime = DateTime.UtcNow; + + public bool ShouldPoll() + { + if (!IsActive) return false; + if (!LastPollTime.HasValue) return true; + return DateTime.UtcNow >= LastPollTime.Value.AddMinutes(PollIntervalMinutes); + } +} diff --git a/src/DigitalData.EmailProfiler.Domain/Entities/IndexingStep.cs b/src/DigitalData.EmailProfiler.Domain/Entities/IndexingStep.cs new file mode 100644 index 0000000..2c7b0c6 --- /dev/null +++ b/src/DigitalData.EmailProfiler.Domain/Entities/IndexingStep.cs @@ -0,0 +1,56 @@ +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using DigitalData.EmailProfiler.Domain.Common; + +namespace DigitalData.EmailProfiler.Domain.Entities; + +[Table("TBEMLP_POLL_INDEXING_STEPS")] +public class IndexingStep : BaseEntity +{ + [Key] + [Column("GUID", Order = 0)] + [DatabaseGenerated(DatabaseGeneratedOption.Identity)] + public int Id { get; set; } + + [Column("STEP_ID")] + [Required] + public int StepId { get; set; } + + [Column("INDEXNAME", TypeName = "varchar(100)")] + [Required] + [MaxLength(100)] + public string IndexName { get; set; } = string.Empty; + + [Column("INDEXVALUE", TypeName = "varchar(100)")] + [Required] + [MaxLength(100)] + public string IndexValue { get; set; } = string.Empty; + + [Column("ACTIVE")] + public bool IsActive { get; set; } = true; + + [Column("USE_FOR_DIRECT_ANSWER")] + public bool UseForDirectAnswer { get; set; } + + [Column("SEQUENCE")] + public int? Sequence { get; set; } + + // Audit fields + [Column("ADDED_WHO", TypeName = "varchar(50)")] + [MaxLength(50)] + public string? AddedWho { get; set; } + + [Column("ADDED_WHEN")] + public DateTime? AddedWhen { get; set; } + + [Column("CHANGED_WHO", TypeName = "varchar(50)")] + [MaxLength(50)] + public string? ChangedWho { get; set; } + + [Column("CHANGED_WHEN")] + public DateTime? ChangedWhen { get; set; } + + // Navigation properties + [ForeignKey("StepId")] + public virtual ProcessStep? ProcessStep { get; set; } +} diff --git a/src/DigitalData.EmailProfiler.Domain/Entities/ProcessStep.cs b/src/DigitalData.EmailProfiler.Domain/Entities/ProcessStep.cs new file mode 100644 index 0000000..d656d3f --- /dev/null +++ b/src/DigitalData.EmailProfiler.Domain/Entities/ProcessStep.cs @@ -0,0 +1,58 @@ +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using DigitalData.EmailProfiler.Domain.Common; + +namespace DigitalData.EmailProfiler.Domain.Entities; + +[Table("TBEMLP_POLL_STEPS")] +public class ProcessStep : BaseEntity +{ + [Key] + [Column("GUID", Order = 0)] + [DatabaseGenerated(DatabaseGeneratedOption.Identity)] + public int Id { get; set; } + + [Column("PROCESS_ID")] + [Required] + public int ProcessId { get; set; } + + [Column("STEP_NAME", TypeName = "varchar(50)")] + [Required] + [MaxLength(50)] + public string StepName { get; set; } = string.Empty; + + [Column("KEYWORDS_BODY", TypeName = "varchar(1000)")] + [MaxLength(1000)] + public string? KeywordsBody { get; set; } + + [Column("ACTIVE")] + public bool IsActive { get; set; } = true; + + [Column("SEQUENCE")] + public int? Sequence { get; set; } + + [Column("COMMENT", TypeName = "varchar(500)")] + [MaxLength(500)] + public string? Comment { get; set; } + + // Audit fields + [Column("ADDED_WHO", TypeName = "varchar(50)")] + [MaxLength(50)] + public string? AddedWho { get; set; } + + [Column("ADDED_WHEN")] + public DateTime? AddedWhen { get; set; } + + [Column("CHANGED_WHO", TypeName = "varchar(50)")] + [MaxLength(50)] + public string? ChangedWho { get; set; } + + [Column("CHANGED_WHEN")] + public DateTime? ChangedWhen { get; set; } + + // Navigation properties + [ForeignKey("ProcessId")] + public virtual EmailProcess? EmailProcess { get; set; } + + public virtual ICollection IndexingSteps { get; set; } = new List(); +}