Removed `DequeueAsync` from `IOutgoingEmailQueue` and added `GetQueueDepthAsync` to query the queue's message count. Updated RabbitMQ connection and channel creation methods to support `CancellationToken`. Removed `DequeueAsync` implementation from `OutgoingEmailQueue`, signaling a shift away from direct message consumption. These changes improve cancellation handling and simplify the queue's responsibilities.
Renamed the `IEmailQueue` interface to `IOutgoingEmailQueue` to improve clarity and better reflect its purpose as an outgoing email queue. Updated all references to the interface across the codebase, including:
- Replaced `IEmailQueue` with `IOutgoingEmailQueue` in `EmailSenderWorker.cs`.
- Renamed the interface in `IOutgoingEmailQueue.cs`.
- Updated `SendEmailCommandHandler` in `SendEmailCommand.cs` to use `IOutgoingEmailQueue`.
- Modified dependency injection in `DependencyInjection.cs` to register `OutgoingEmailQueue` with `IOutgoingEmailQueue`.
- Updated `OutgoingEmailQueue.cs` to implement `IOutgoingEmailQueue`.
These changes improve code readability, maintainability, and naming consistency.
Replaced `RabbitMqEmailQueue` with `OutgoingEmailQueue` in the
dependency injection container to reflect the updated class name.
Renamed the class `RabbitMqEmailQueue` to `OutgoingEmailQueue`
in `OutgoingEmailQueue.cs`, including updates to the constructor
and logger type. This refactor aligns the class name with its
purpose and improves clarity in the codebase.
Centralized email processing logic in `RabbitMqEmailQueue` by moving it from `EmailSenderWorker`. Updated `IEmailQueue` to replace `StartConsumerAsync` with `InitAsync`, shifting to an initialization-based model for RabbitMQ.
Refactored `RabbitMqEmailQueue` to handle email processing inline, including deserialization, logging, and sending emails via `IEmailService`. Enhanced error handling with detailed logging for failures. Removed lazy initialization (`Lazy<Task>`) in favor of explicit initialization via `InitAsync`.
Simplified `EmailSenderWorker` by removing `ProcessEmailAsync` and its dependency on `IEmailService`. Updated it to call `EmailQueue.InitAsync` for initialization.
Improved logging and error handling for better visibility into email processing and failure scenarios. Updated RabbitMQ acknowledgment and rejection logic to use `args.CancellationToken`.
Updated `RabbitMqConfiguration` to include properties for queue and exchange names, replacing hardcoded constants in `RabbitMqEmailQueue`. All RabbitMQ operations now use dynamic values from the configuration object, improving flexibility and configurability. Updated logging to reflect these changes.
The application no longer uses RabbitMQ for command publishing and consumption. This commit removes all RabbitMQ-related code, including:
- Removed RabbitMQ service registrations in `DependencyInjection.cs`.
- Deleted `RabbitMqCommandConsumer.cs`, which implemented a background service for consuming commands.
- Deleted `RabbitMqCommandPublisher.cs`, which implemented a publisher for RabbitMQ-based commands.
- Removed RabbitMQ-specific properties (`ExchangeName`, `QueueName`, `RoutingKey`) from `RabbitMqConfiguration.cs`.
These changes reflect a shift in the application's messaging strategy or architecture.
Introduced a dedicated `EmailSenderWorkerConfiguration` class to centralize and simplify configuration management for the `EmailSenderWorker`. Updated `Program.cs` to use this class for dependency injection and removed the inline configuration logic from `EmailSenderWorker.cs`.
Simplified the worker's constructor by leveraging `IOptions<EmailSenderWorkerConfiguration>`. Removed the unused `MaxRetryCount` property from the configuration class and `appsettings.json`.
Cleaned up `using` directives in `Program.cs` and `EmailSenderWorker.cs` to include the new namespace and remove redundant imports. These changes improve maintainability and align with best practices.
Added a reference to the `System.Security.Cryptography.Xml`
package (version 10.0.10) in the project file to enable
XML cryptographic operations such as signing, verifying,
and encrypting XML data. This change enhances the project's
capabilities for handling secure XML processing.
Replaced the `EncryptedPassword` property in `EmailAccountDto` with `Password` and `PasswordEncrypted` to support both plain text and encrypted passwords. Updated `LimilabsEmailService` to use the new properties, checking the `PasswordEncrypted` flag to determine whether decryption is needed.
The `EmailAccount` section has been removed entirely, including
properties such as `Username`, `SmtpServer`, `SmtpPort`,
`SmtpUseSsl`, and `UseOAuth2`. No changes were made to the
`EmailSender` section or the `LuckyPennySoftLicenseKey`.
Refactored `EmailAccountDto` to focus on SMTP-related properties, removing unused fields. Updated `DependencyInjection` to configure data protection with a new key storage path. Simplified `DataProtectionEncryptionService` by removing redundant checks and error handling for encryption and decryption methods.
- Add static constructor to register System.Text.Encoding.CodePages
- Required for windows-1252 and other extended code page support
- Fixes encoding issues with international email content
- Add license key reading from appsettings.json
- Configure AutoMapper 16.2.0+ with built-in DI extension and license key
- Configure MediatR 14.2.0+ with license key
- Update Program.cs to pass IConfiguration to AddApplicationServices
The `DigitalData.EmailProfiler.Application.csproj` file was updated to downgrade `AutoMapper` and `AutoMapper.Extensions.Microsoft.DependencyInjection` from versions `16.2.0` and `12.0.0` to `12.0.1`. Additionally, a new dependency on `FluentValidation.DependencyInjectionExtensions` version `12.1.1` was added.
The `DigitalData.EmailProfiler.Infrastructure.csproj` file was updated to downgrade the `AutoMapper` package from version `16.2.0` to `12.0.1`.
These changes address potential compatibility issues and introduce FluentValidation for dependency injection.
Controllers:
- EmailProfilesController: CRUD operations (GET sync, POST/PUT/DELETE async via RabbitMQ)
* GET /api/emailprofiles - List all profiles
* GET /api/emailprofiles/{id} - Get profile by ID
* GET /api/emailprofiles/active - List active profiles
* POST /api/emailprofiles - Create (202 Accepted, queued to RabbitMQ)
* PUT /api/emailprofiles/{id} - Update (202 Accepted, queued to RabbitMQ)
* DELETE /api/emailprofiles/{id} - Delete (202 Accepted, queued to RabbitMQ)
- EmailAccountsController: CRUD operations
* GET /api/emailaccounts - List all accounts
* GET /api/emailaccounts/{id} - Get account by ID
* POST /api/emailaccounts - Create (202 Accepted, queued to RabbitMQ)
- EmailHistoryController: Read-only operations
* GET /api/emailhistory/profile/{profileId} - Get history with pagination
* GET /api/emailhistory/{id} - Get history by ID
Changes:
- Fix ICommandPublisher constraint: IRequest → IBaseRequest (supports IRequest<T>)
- All POST/PUT/DELETE return HTTP 202 Accepted (async processing)
- All GET operations return HTTP 200 OK (synchronous via MediatR)
- Proper error handling: 404 Not Found for missing resources
- Move EmailAccountDto.cs to Dtos/ (was in EmailAccounts/ subfolder)
- Move EmailProfileDto.cs to Dtos/ (was in EmailProfiles/ subfolder)
- Keep EmailAttachments/ (3 DTOs) and EmailHistories/ (3 DTOs) subfolders
- Update all namespace imports from Dtos.EmailAccounts/EmailProfiles to Dtos
- Simpler structure: single DTOs at root, multiple DTOs in subfolders
- Consolidated commands and handlers into single files for better organization.
- Updated file naming conventions for commands and queries.
- Added explicit Git operation rules to prevent automatic commits/pushes.
- Introduced new projects and restructured solution file (`legacy` folder).
- Refactored `CreateEmailAccountCommand`, `ProcessEmailCommand`, and others to use `IUnitOfWork`.
- Enhanced `ProcessEmailCommandHandler` with attachment validation and error handling.
- Removed redundant handler files after consolidation.
- Improved code consistency and added `TODO` comments for future enhancements.
CRITICAL FIX: Replace all DateTime.UtcNow with DateTime.Now throughout the application.
Reason: Legacy VB.NET system uses local server time, and database stores all
timestamps as local time. Using UTC breaks compatibility and causes incorrect
time comparisons.
Changes:
- EmailProcessedEvent: ProcessedDate now uses DateTime.Now
- EmailHistory.MarkAsProcessed(): ProcessedDate now uses DateTime.Now
- EmailHistory.MarkAsFailed(): ProcessedDate now uses DateTime.Now
- EmailProfile.UpdateLastPollTime(): LastPollTime now uses DateTime.Now
- EmailProfile.ShouldPoll(): Poll interval comparison now uses DateTime.Now
Documentation:
- Added critical note to agents.md about DateTime usage
- Includes examples and detailed explanation for future developers
This ensures all date/time operations remain compatible with legacy database.
DTOs:
- EmailProfileDto: Profile data transfer object
- EmailAccountDto: Email account data transfer object
- EmailHistoryDto: Email history data transfer object
- EmailAttachmentDto: Attachment data transfer object
Dependencies:
- MediatR 14.2.0 for CQRS (Commands/Queries)
- AutoMapper 12.0.1 for entity-DTO mapping
- FluentValidation 12.1.1 for input validation
This provides the foundation for the application layer implementation.
- MessageId: Unique message identifier with SHA256 hash
Uses same algorithm as legacy system for duplicate detection compatibility
Hash format: SHA256({originalMessageId}|{sender}|{date}|{subject})
- EmailAddress: Email address validation and parsing with name support
Value objects ensure immutability and value-based equality.
- ErrorCode: All error codes from legacy system (10001-10010)
- ProcessType: Email process types (ProcessManager, AttachmentSniffer, ZugFeRDParser)
- AuthenticationType: Authentication methods (UsernamePassword, OAuth2)
- EmailStatus: Email processing status tracking
- AttachmentStatus: Attachment validation status
These enums maintain compatibility with the legacy VB.NET system.
- Add BaseEntity with audit fields (CreatedDate, CreatedBy, ModifiedDate, ModifiedBy)
- Add IAggregateRoot marker interface for DDD aggregate roots
- Add ValueObject base class with equality comparison by value
These classes provide the foundation for all domain entities and value objects.
Added project references to establish dependencies between
the API, Application, Domain, and Infrastructure projects.
Updated `DigitalData.EmailProfiler.Tests.csproj` to include
references to all layers for testing purposes. Fixed a BOM
encoding issue in the test project file. Added xUnit usage
directive to ensure proper test framework integration.