refactor: enhance email service#62
Conversation
✅ Deploy Preview for bookwormdev canceled.
|
WalkthroughThis update restructures and modernizes the notification service's email infrastructure. It replaces the legacy Changes
Sequence Diagram(s)sequenceDiagram
participant App as IHostApplicationBuilder
participant DI as Dependency Injection
participant MailKitExt as MailKitExtensions
participant MailKitFactory as MailKitClientFactory
participant MailKitSender as MailKitSender
participant Smtp as SMTP Server
App->>MailKitExt: AddMailKitClient(connectionName)
MailKitExt->>DI: Register MailKitSettings, MailKitClientFactory, MailKitSender
MailKitSender->>MailKitFactory: GetSmtpClientAsync()
MailKitFactory->>Smtp: Connect & Authenticate
MailKitSender->>Smtp: SendAsync(MimeMessage)
Note right of MailKitSender: On error, log and flush buffer
sequenceDiagram
participant App as IHostApplicationBuilder
participant DI as Dependency Injection
participant OutboxExt as OutboxExtensions
participant Outbox as EmailOutboxService
participant Sender as ISender (MailKit/SendGrid)
App->>OutboxExt: AddEmailOutbox()
OutboxExt->>DI: Register EmailOutboxService as ISender
Outbox->>Sender: SendAsync(MimeMessage)
Sender->>...: (MailKitSender or SendGridSender logic)
Poem
✨ Finishing Touches
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Pull Request Overview
This pull request refactors components of the email service and related infrastructure while aligning configuration and logging behavior across tests, state management, and exception handling.
- Replaces EmailOptions with MailKitSettings in tests for improved consistency with production email configuration.
- Introduces GlobalLogBuffer dependency and flush calls in ConversationState, MessageBuffer, ChatStreaming, and exception handlers to enhance logging reliability.
- Updates namespaces and minor configuration settings across various Aspire projects, including adjustments in health check and testing extensions.
Reviewed Changes
Copilot reviewed 59 out of 59 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| src/Services/Notification/BookWorm.Notification.UnitTests/Consumers/CancelOrderConsumerTests.cs | Replaces EmailOptions with MailKitSettings and updates DI registration. |
| src/Services/Chat/BookWorm.Chat/Infrastructure/ConversationState/RedisConversationState.cs | Adds GlobalLogBuffer dependency and flushes log buffer on dispose and error handling. |
| src/Services/Chat/BookWorm.Chat/Infrastructure/ConversationState/MessageBuffer.cs | Introduces GlobalLogBuffer and adjusts the return statement in CoalesceFragments. |
| src/Services/Chat/BookWorm.Chat/Infrastructure/ChatStreaming/ChatStreaming.cs | Incorporates GlobalLogBuffer with flush calls after processing to streamline logging. |
| src/BuildingBlocks/BookWorm.Chassis/Exceptions/* | Passes a log buffer to various exception handlers and flushes after logging errors. |
| src/Aspire/BookWorm.AppHost/Extensions/* | Updates namespace organization and minor adjustments in health checks and testing extensions. |
| Directory.Packages.props | Removes the AspNetCore.HealthChecks.Network package. |
Comments suppressed due to low confidence (3)
src/Services/Notification/BookWorm.Notification.UnitTests/Consumers/CancelOrderConsumerTests.cs:41
- Ensure that replacing EmailOptions with MailKitSettings in the test setup is consistent with the production configuration of the email service.
_mailKitSettings = new() { From = "[email protected]" };
Directory.Packages.props:73
- Confirm that the removal of the AspNetCore.HealthChecks.Network package does not adversely affect any health check functionality within the services.
<PackageVersion Include="AspNetCore.HealthChecks.Network" Version="$(HealthChecksVersion)" />
src/Aspire/BookWorm.AppHost/Extensions/Testing/K6Extensions.cs:45
- [nitpick] Verify that using the string literal "true" for the K6WebDashboard environment variable meets downstream requirements, replacing the previous ToString() conversion.
.WithEnvironment(K6WebDashboard, "true")
There was a problem hiding this comment.
Actionable comments posted: 19
🔭 Outside diff range comments (1)
src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/Outbox/EmailOutboxService.cs (1)
19-24: Gracefully handle plain-text emails
mailMessage.HtmlBodycan benullwhen only aTextBodyis supplied. Persistingnullin the outbox will later break HTML renderers in the admin portal.- mailMessage.HtmlBody + mailMessage.HtmlBody ?? mailMessage.TextBodyOptionally persist both fields so that downstream consumers can decide which flavour to display.
♻️ Duplicate comments (2)
src/Aspire/BookWorm.AppHost/Extensions/Infrastructure/AzureExtensions.Provision.cs (1)
99-115: Same tag duplication comment applies here
See earlier note; consider centralising tag logic for the PostgreSQL path as well.src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/SendGrid/SendGridSender.cs (1)
37-47: Preserve cancellation semantics as inMailKitSenderSame concern as above – wrap
OperationCanceledExceptionseparately to avoid masking cancellations.- if (response.StatusCode is not (HttpStatusCode.OK or HttpStatusCode.Accepted)) + if (response.StatusCode is not (HttpStatusCode.OK or HttpStatusCode.Accepted))(Apply the same try/catch refactor suggested for
MailKitSender.)
🧹 Nitpick comments (31)
src/Aspire/BookWorm.ServiceDefaults/Extensions.cs (1)
145-145: Unnecessary extra blank lines introducedThe added blank lines break the existing one-blank-line separation style used throughout the file. Consider reverting to a single blank line after each variable block to keep formatting consistent.
Also applies to: 154-154
src/Services/Notification/BookWorm.Notification/Infrastructure/Job/Extensions.cs (1)
42-44: Variable naming drift
jobOptionsno longer reflects the type; consider renaming tojobSettingsfor clarity and to match the class rename.src/Services/Notification/BookWorm.Notification/Infrastructure/Job/JobSettings.cs (1)
10-23: Possible missingusing System.ComponentModel.DataAnnotationsAttributes such as
[Required]and[RegularExpression]are defined inSystem.ComponentModel.DataAnnotations.
If a global-using isn’t already present, this file will fail to compile.src/Aspire/BookWorm.AppHost/Extensions/Infrastructure/AzureExtensions.Provision.cs (1)
50-55: Tag-adding logic is duplicated across resourcesIdentical
Environment/Projectstags are set in every provisioning block.
Extract a small helper (e.g.,AddStandardTags(this ITaggable res, IDistributedApplicationBuilder app)) to keep these sections DRY and lower maintenance overhead.src/Aspire/BookWorm.AppHost/Extensions/Network/EndpointExtensions.cs (1)
11-15: Doc-comment sentence is truncated
/// This ensures thatends abruptly. Complete or remove to avoid stale documentation.src/Aspire/BookWorm.AppHost/Extensions/Testing/K6Extensions.cs (1)
45-45: Explicit"true"string is fine—consider constant reuse.Hard-coding
"true"is clearer thantrue.ToString(), but you might expose a small helper/constant to avoid magic strings if the flag is reused elsewhere.src/Services/Notification/BookWorm.Notification/Workers/CleanUpSentEmailWorker.cs (1)
8-10: Prefer injecting via an abstraction rather than the concreteGlobalLogBuffer
GlobalLogBufferis being injected directly. If a lightweight façade (e.g.ILogBuffer) were introduced you could:
- keep production code tied to the concrete buffer,
- but still mock the interface in tests,
- and avoid leaking a 3rd-party type through your public surface.
This minor change improves decoupling and future-proofs the class should the underlying buffering implementation change.
src/Services/Notification/BookWorm.Notification/IntegrationEvents/EventHandlers/CancelOrderCommandHandler.cs (1)
30-33: Minor: avoid theusingalias for a single typeThe alias
using MailKitSettings = ...adds indirection with little benefit—
MailKitSettingsis already an unambiguous name across the solution. Dropping the alias reduces noise in stack traces and IDE “go to definition”.src/Services/Notification/BookWorm.Notification/Domain/Builders/OrderMimeMessageBuilder.cs (1)
29-32: Validate settings before constructing theFromaddress
mailKitSettings.Name/Fromare used directly; if configuration is missing the resultingMimeMessagecontains an empty address and the SMTP transaction will fail late. Quick guard:public OrderMimeMessageBuilder WithFrom(MailKitSettings mailKitSettings) { - From = new(mailKitSettings.Name, mailKitSettings.From); + if (string.IsNullOrWhiteSpace(mailKitSettings.From)) + throw new ArgumentException("Sender address is not configured", nameof(mailKitSettings)); + + From = new(mailKitSettings.Name, mailKitSettings.From); return this; }Failing fast here produces a clear exception and surfaces misconfiguration during testing rather than at runtime.
src/Services/Notification/BookWorm.Notification.UnitTests/Workers/CleanUpSentEmailWorkerTests.cs (1)
23-24: Add an assertion thatlogBuffer.Flush()is invoked on failureThe new dependency is mocked but never verified. A simple expectation strengthens the test and protects the behaviour introduced in the PR:
logBufferMock .Verify(x => x.Flush(), Times.Once);Place it in
GivenException_WhenCleaningUp_ThenShouldLogError.Also applies to: 39-40
src/BuildingBlocks/BookWorm.Chassis/Exceptions/ValidationExceptionHandler.cs (1)
10-13: Inject abstraction, not concrete buffer
PerRequestLogBufferis a concrete type. Depending directly on it couples the handler to the Microsoft-specific implementation and complicates testing/mocking. If possible, depend on theILogBuffer(or similar abstraction exposed byMicrosoft.Extensions.Diagnostics.Buffering) to respect the Dependency-Inversion Principle.src/Services/Notification/BookWorm.Notification/IntegrationEvents/EventHandlers/PlaceOrderCommandHandler.cs (1)
1-1: Remove aliasing—prefer ordinary usingThe file-level alias
MailKitSettings = …MailKitSettings;adds unnecessary cognitive load; the fully-qualified name is already concise. Unless you alias multiple conflicting types, drop the alias for clarity.src/Services/Notification/BookWorm.Notification/IntegrationEvents/EventHandlers/CompleteOrderCommandHandler.cs (1)
1-1: Same aliasing concern as inPlaceOrderCommandHandlerDrop the using-alias unless a real name clash exists.
src/BuildingBlocks/BookWorm.Chassis/Exceptions/NotFoundExceptionHandler.cs (1)
21-24: Depend on abstraction rather than concrete bufferSame concern as in
ValidationExceptionHandler—inject an interface if available.src/BuildingBlocks/BookWorm.Chassis/Exceptions/GlobalExceptionHandler.cs (1)
9-12: Inject abstraction for easier testing
GlobalLogBufferis concrete; prefer an abstraction to decouple.src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/Outbox/EmailOutboxService.cs (1)
5-5: Preferstatic readonlyfor immutable constants
_partitionKeynever changes after construction and is identical for every instance.
Making itstatic readonlyavoids recomputing the same string for each service instance and communicates intent.-private readonly string _partitionKey = nameof(Domain.Models.Outbox).ToLowerInvariant(); +private static readonly string _partitionKey = + nameof(Domain.Models.Outbox).ToLowerInvariant();src/Services/Notification/BookWorm.Notification.UnitTests/Workers/ResendErrorEmailWorkerTests.cs (1)
43-48: MockGlobalLogBuffermore realistically
GlobalLogBuffer.Flush()is invoked inside the worker.
Consider configuring the mock to verify thatFlush()is called at least once in the failure paths to keep the test meaningful.logBufferMock.Setup(b => b.Flush());src/Services/Chat/BookWorm.Chat/Infrastructure/ChatStreaming/ChatStreaming.cs (1)
164-165: Flush success path too?You flush the global log buffer on both exception branches but not after the normal completion of streaming.
If the intention is to guarantee log persistence after every streamed message, add a flush afterSaveAssistantMessageToDatabasesucceeds.await SaveAssistantMessageToDatabase(...); _logBuffer.Flush();Ignore if log batching is preferred for the happy path.
src/Services/Notification/BookWorm.Notification.UnitTests/Consumers/CancelOrderConsumerTests.cs (1)
41-42: Minor: include required fields in settings
MailKitSettingsusually requires host, port and credentials. Supplying onlyFrommay hide mis-configuration in tests.
Populate minimal valid values or use a faker to keep the tests realistic.src/Services/Notification/BookWorm.Notification/Workers/ResendErrorEmailWorker.cs (1)
10-12: Prefer the options pattern for settings injectionInjecting
MailKitSettingsas a concrete type works, but wiring it throughIOptions<MailKitSettings>(orIOptionsSnapshot<>) provides consistency with the rest of the ASP .NET configuration story and enables validation & reload-on-change for free.-public sealed class ResendErrorEmailWorker( - ILogger<ResendErrorEmailWorker> logger, - MailKitSettings mailKitSettings, +public sealed class ResendErrorEmailWorker( + ILogger<ResendErrorEmailWorker> logger, + IOptions<MailKitSettings> mailKitSettings,src/Services/Notification/BookWorm.Notification.UnitTests/Consumers/PlaceOrderConsumerTests.cs (1)
33-45: Nit: rename test faker for clarity
TestDataFakers.EmailOptionsnow returnsMailKitSettings, which can confuse future readers.-public static readonly Faker<MailKitSettings> EmailOptions = new Faker<MailKitSettings>() +public static readonly Faker<MailKitSettings> MailKitSettings = new Faker<MailKitSettings>()src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/MailKit/MailKitHealthCheck.cs (1)
3-19: Health-check implementation solid, tiny enhancement possibleFetching an SMTP client is enough for a basic probe, but you could improve granularity by returning
Degradedwhen the client is retrieved but not connected/authenticated (checkclient.IsConnected). Not blocking the PR.src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/Outbox/OutboxExtensions.cs (1)
21-30: Underlying senders must be registered before the outbox
AddEmailOutboxresolvesMailKitSender/SendGridSenderdirectly. If neitherAddMailKitClientnorAddSendGridClienthas been invoked earlier, the container build will fail at runtime.Document the ordering or defensively call the required registrations here to make the extension self-contained.
src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/MailKit/MailKitClientFactory.cs (1)
8-12: ImplementIAsyncDisposableor callDisconnectAsync()
SmtpClient.Dispose()does not sendQUIT; preferDisconnectAsync(true)to gracefully close the connection. ProvidingIAsyncDisposableenables callers to await it during shutdown.src/Services/Notification/BookWorm.Notification.UnitTests/Fakers/TestDataFakers.cs (1)
9-11: Rename variable to match type
EmailOptionsstill appears as the field name although the type isMailKitSettings, which is misleading.-public static readonly Faker<MailKitSettings> EmailOptions = … +public static readonly Faker<MailKitSettings> MailKitSettingsFaker = …src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/MailKit/MailKitSettings.cs (2)
27-39: Error messages reference the value, not the keyThe interpolated string uses
{connectionString}inside the “ConnectionStrings:” placeholder, yielding confusing output (it prints the whole connection string). Capture the key name separately or adjust wording.-It should be provided in 'ConnectionStrings:{connectionString}' +It should be provided in the 'ConnectionStrings' section or the +'{ConfigurationSection}:Endpoint' key
59-67: UseUri.TryCreateresult variableYou already stored
uriabove; re-using the out var hides potential misuse. Minor readability fix.- if (Uri.TryCreate(endpoint.ToString(), UriKind.Absolute, out uri) is false) + if (Uri.TryCreate(endpoint.ToString(), UriKind.Absolute, out var parsed) is false) … - Endpoint = uri; + Endpoint = parsed;src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/MailKit/MailKitExtensions.cs (1)
61-84: RepeatedAddOpenTelemetry()may override prior configurationChaining
AddOpenTelemetry()twice can drop earlier tracing/metric configuration set by other libraries. Prefer configuring both tracing and metrics in one builder or usingConfigureOpenTelemetrypattern.src/Services/Notification/BookWorm.Notification.UnitTests/Fakers/FakerExtensions.cs (1)
15-28: Consider null-forgiving operator removal
null!suppresses nullable warnings but hides potential regressions. For tests, explicitly passnulland annotate constructor parameter as nullable where appropriate.src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/SendGrid/SendGridSettings.cs (2)
11-13:[Key]attribute is misleading on a settings DTO
[Key]is an Entity Framework/Data-Annotations hint for primary keys; this class is never persisted.
Keeping it here conveys the wrong semantics and adds an unnecessary dependency on EF‐Core packages.-[Key] public string ApiKey { get; set; } = string.Empty;
15-20: Prefer the built-in[EmailAddress]attribute to a custom regex
[EmailAddress]fromSystem.ComponentModel.DataAnnotationsalready validates most RFC-compliant addresses and is
maintained by the BCL. The custom regex is harder to read, duplicate maintenance burden, and could reject future-valid
addresses (e.g., new single-character TLDs).-[RegularExpression( - @"^[a-zA-Z0-9._%+-]+@(?!.*\.\.)[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$", - ErrorMessage = "Invalid email format" -)] +[EmailAddress]
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (59)
Directory.Packages.props(0 hunks)src/Aspire/BookWorm.AppHost/Extensions/AI/ModelExtensions.cs(1 hunks)src/Aspire/BookWorm.AppHost/Extensions/Infrastructure/AzureExtensions.Provision.cs(5 hunks)src/Aspire/BookWorm.AppHost/Extensions/Infrastructure/AzureExtensions.Run.cs(1 hunks)src/Aspire/BookWorm.AppHost/Extensions/Infrastructure/DashboardExtensions.cs(1 hunks)src/Aspire/BookWorm.AppHost/Extensions/Infrastructure/RedisResourceExtensions.cs(1 hunks)src/Aspire/BookWorm.AppHost/Extensions/Network/EmailExtensions.cs(1 hunks)src/Aspire/BookWorm.AppHost/Extensions/Network/EndpointExtensions.cs(1 hunks)src/Aspire/BookWorm.AppHost/Extensions/Network/LaunchProfileExtensions.cs(1 hunks)src/Aspire/BookWorm.AppHost/Extensions/Security/KeycloakExtensions.cs(1 hunks)src/Aspire/BookWorm.AppHost/Extensions/Testing/K6Extensions.cs(2 hunks)src/Aspire/BookWorm.AppHost/GlobalUsings.cs(1 hunks)src/Aspire/BookWorm.ServiceDefaults/Extensions.cs(2 hunks)src/BuildingBlocks/BookWorm.Chassis/Exceptions/GlobalExceptionHandler.cs(2 hunks)src/BuildingBlocks/BookWorm.Chassis/Exceptions/NotFoundExceptionHandler.cs(3 hunks)src/BuildingBlocks/BookWorm.Chassis/Exceptions/ValidationExceptionHandler.cs(2 hunks)src/Services/Chat/BookWorm.Chat/Infrastructure/ChatStreaming/ChatStreaming.cs(6 hunks)src/Services/Chat/BookWorm.Chat/Infrastructure/ConversationState/MessageBuffer.cs(5 hunks)src/Services/Chat/BookWorm.Chat/Infrastructure/ConversationState/RedisConversationState.cs(6 hunks)src/Services/Notification/BookWorm.Notification.UnitTests/Consumers/CancelOrderConsumerTests.cs(6 hunks)src/Services/Notification/BookWorm.Notification.UnitTests/Consumers/CompleteOrderConsumerTests.cs(7 hunks)src/Services/Notification/BookWorm.Notification.UnitTests/Consumers/PlaceOrderConsumerTests.cs(6 hunks)src/Services/Notification/BookWorm.Notification.UnitTests/Domain/EmailOptionsTests.cs(0 hunks)src/Services/Notification/BookWorm.Notification.UnitTests/Domain/JobOptionsTests.cs(0 hunks)src/Services/Notification/BookWorm.Notification.UnitTests/Domain/SendGridOptionsTests.cs(0 hunks)src/Services/Notification/BookWorm.Notification.UnitTests/Fakers/FakerExtensions.cs(1 hunks)src/Services/Notification/BookWorm.Notification.UnitTests/Fakers/TestDataFakers.cs(1 hunks)src/Services/Notification/BookWorm.Notification.UnitTests/Workers/CleanUpSentEmailWorkerTests.cs(3 hunks)src/Services/Notification/BookWorm.Notification.UnitTests/Workers/ResendErrorEmailWorkerTests.cs(3 hunks)src/Services/Notification/BookWorm.Notification/BookWorm.Notification.csproj(0 hunks)src/Services/Notification/BookWorm.Notification/Domain/Builders/OrderMimeMessageBuilder.cs(2 hunks)src/Services/Notification/BookWorm.Notification/Domain/Settings/EmailOptions.cs(0 hunks)src/Services/Notification/BookWorm.Notification/Extensions/Extensions.cs(2 hunks)src/Services/Notification/BookWorm.Notification/GlobalUsings.cs(0 hunks)src/Services/Notification/BookWorm.Notification/Infrastructure/Job/Extensions.cs(1 hunks)src/Services/Notification/BookWorm.Notification/Infrastructure/Job/JobSettings.cs(1 hunks)src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/Extensions/Extensions.cs(0 hunks)src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/Extensions/MailPitEndpointExtensions.cs(0 hunks)src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/Extensions/SenderWithTelemetryExtensions.cs(0 hunks)src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/Factories/ISmtpClientFactory.cs(0 hunks)src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/Factories/SmtpClientFactory.cs(0 hunks)src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/Factories/SmtpClientFactoryObjectPoolPolicy.cs(0 hunks)src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/MailKit/MailKitClientFactory.cs(1 hunks)src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/MailKit/MailKitExtensions.cs(1 hunks)src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/MailKit/MailKitHealthCheck.cs(1 hunks)src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/MailKit/MailKitSender.cs(1 hunks)src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/MailKit/MailKitSettings.cs(1 hunks)src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/Outbox/EmailOutboxService.cs(2 hunks)src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/Outbox/OutboxExtensions.cs(1 hunks)src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/Providers/MailKitSender.cs(0 hunks)src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/SendGrid/SendGridExtensions.cs(1 hunks)src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/SendGrid/SendGridSender.cs(2 hunks)src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/SendGrid/SendGridSettings.cs(1 hunks)src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/TelemetryTags.cs(0 hunks)src/Services/Notification/BookWorm.Notification/IntegrationEvents/EventHandlers/CancelOrderCommandHandler.cs(2 hunks)src/Services/Notification/BookWorm.Notification/IntegrationEvents/EventHandlers/CompleteOrderCommandHandler.cs(2 hunks)src/Services/Notification/BookWorm.Notification/IntegrationEvents/EventHandlers/PlaceOrderCommandHandler.cs(2 hunks)src/Services/Notification/BookWorm.Notification/Workers/CleanUpSentEmailWorker.cs(2 hunks)src/Services/Notification/BookWorm.Notification/Workers/ResendErrorEmailWorker.cs(4 hunks)
💤 Files with no reviewable changes (15)
- src/Services/Notification/BookWorm.Notification/BookWorm.Notification.csproj
- Directory.Packages.props
- src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/Factories/ISmtpClientFactory.cs
- src/Services/Notification/BookWorm.Notification/GlobalUsings.cs
- src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/Factories/SmtpClientFactoryObjectPoolPolicy.cs
- src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/Extensions/MailPitEndpointExtensions.cs
- src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/Factories/SmtpClientFactory.cs
- src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/Extensions/SenderWithTelemetryExtensions.cs
- src/Services/Notification/BookWorm.Notification.UnitTests/Domain/JobOptionsTests.cs
- src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/TelemetryTags.cs
- src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/Providers/MailKitSender.cs
- src/Services/Notification/BookWorm.Notification.UnitTests/Domain/SendGridOptionsTests.cs
- src/Services/Notification/BookWorm.Notification.UnitTests/Domain/EmailOptionsTests.cs
- src/Services/Notification/BookWorm.Notification/Domain/Settings/EmailOptions.cs
- src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/Extensions/Extensions.cs
🧰 Additional context used
🧬 Code Graph Analysis (8)
src/Services/Chat/BookWorm.Chat/Infrastructure/ChatStreaming/ChatStreaming.cs (2)
src/Services/Chat/BookWorm.Chat/Extensions/Extensions.cs (1)
Extensions(3-60)src/Services/Chat/BookWorm.Chat/Infrastructure/ChatStreaming/Extensions.cs (1)
Extensions(3-51)
src/Services/Notification/BookWorm.Notification/IntegrationEvents/EventHandlers/CompleteOrderCommandHandler.cs (2)
src/Services/Notification/BookWorm.Notification/IntegrationEvents/EventHandlers/CancelOrderCommandHandler.cs (1)
AsyncApi(5-40)src/Services/Notification/BookWorm.Notification/IntegrationEvents/EventHandlers/PlaceOrderCommandHandler.cs (1)
AsyncApi(5-40)
src/Services/Notification/BookWorm.Notification/Extensions/Extensions.cs (4)
src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/MailKit/MailKitExtensions.cs (1)
AddMailKitClient(18-30)src/BuildingBlocks/BookWorm.Constants/Aspire/Components.cs (1)
Components(3-43)src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/SendGrid/SendGridExtensions.cs (1)
AddSendGridClient(12-15)src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/Outbox/OutboxExtensions.cs (1)
AddEmailOutbox(17-31)
src/Services/Notification/BookWorm.Notification.UnitTests/Consumers/PlaceOrderConsumerTests.cs (2)
src/Services/Notification/BookWorm.Notification.UnitTests/Fakers/TestDataFakers.cs (1)
TestDataFakers(7-27)src/Services/Notification/BookWorm.Notification.UnitTests/Fakers/FakerExtensions.cs (1)
FakerExtensions(6-44)
src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/Outbox/OutboxExtensions.cs (4)
src/Services/Notification/BookWorm.Notification/Infrastructure/Table/Extensions.cs (1)
AddTableService(7-14)src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/MailKit/MailKitSender.cs (1)
MailKitSender(6-38)src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/SendGrid/SendGridSender.cs (1)
SendGridSender(8-51)src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/Outbox/EmailOutboxService.cs (1)
EmailOutboxService(3-34)
src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/MailKit/MailKitSettings.cs (1)
src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/SendGrid/SendGridSettings.cs (1)
OptionsValidator(6-25)
src/Services/Notification/BookWorm.Notification/Infrastructure/Job/JobSettings.cs (2)
src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/MailKit/MailKitSettings.cs (1)
OptionsValidator(6-80)src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/SendGrid/SendGridSettings.cs (1)
OptionsValidator(6-25)
src/Services/Notification/BookWorm.Notification.UnitTests/Fakers/TestDataFakers.cs (1)
src/Services/Notification/BookWorm.Notification.UnitTests/Fakers/FakerExtensions.cs (3)
Outbox(8-13)PlaceOrderCommand(15-28)PlaceOrderCommand(30-43)
⏰ Context from checks skipped due to timeout of 90000ms (5)
- GitHub Check: Analyzers
- GitHub Check: Style
- GitHub Check: Security Scan
- GitHub Check: Build and analyze
- GitHub Check: Security Scan
🔇 Additional comments (27)
src/Services/Notification/BookWorm.Notification/Infrastructure/Job/JobSettings.cs (1)
5-9: Access modifier change may limit re-use
ConfigurationSectionwas changed frompublictointernal.
If other projects (e.g. tests, out-of-process tools, or central configuration helpers) need this constant, they will no longer compile. Verify that the constant isn’t referenced outsideBookWorm.Notificationbefore committing to the restriction.src/Aspire/BookWorm.AppHost/Extensions/Network/LaunchProfileExtensions.cs (1)
1-1: Consistent namespace relocation
The namespace has been correctly updated toBookWorm.AppHost.Extensions.Network, aligning with the folder structure and other network-related extensions. No functional impact.src/Aspire/BookWorm.AppHost/Extensions/Infrastructure/RedisResourceExtensions.cs (1)
6-6: Namespace aligned with infrastructure domain
The change toBookWorm.AppHost.Extensions.Infrastructureaccurately clusters Redis resource extensions with other infrastructure-related extensions. No further edits needed.src/Aspire/BookWorm.AppHost/Extensions/Security/KeycloakExtensions.cs (1)
1-1: Security namespace introduced
MovingKeycloakExtensionsintoBookWorm.AppHost.Extensions.Securitycleanly separates security concerns. Implementation remains untouched.src/Aspire/BookWorm.AppHost/Extensions/Infrastructure/DashboardExtensions.cs (1)
1-1: Infrastructure namespace reorganization
TheDashboardExtensionsclass now resides underBookWorm.AppHost.Extensions.Infrastructure, matching its role in telemetry setup. No behavior changes.src/Aspire/BookWorm.AppHost/Extensions/Infrastructure/AzureExtensions.Run.cs (2)
1-1: Namespace updated for Azure run-time extensions
The namespace switch toBookWorm.AppHost.Extensions.Infrastructureis consistent with other Azure-related infrastructure extensions.
3-29: Enhanced XML documentation
The added<summary>and<remarks>blocks provide comprehensive guidance on the development-time emulator support, improving discoverability and maintainability.src/Aspire/BookWorm.AppHost/Extensions/Infrastructure/AzureExtensions.Provision.cs (1)
71-76: VerifyPublicNetworkAccessAPI surface
SignalRService.PublicNetworkAccessis typed as an enum (PublicNetworkAccess.Enabled/Disabled) in recent SDKs.
The literal string"Enabled"may produce a compile-time error when the SDK is upgraded.#!/bin/bash # Check the property type in the generated SDK rg --context 2 $'class SignalRService' | rg -n PublicNetworkAccesssrc/Aspire/BookWorm.AppHost/Extensions/Network/EmailExtensions.cs (1)
1-1: Namespace move looks goodPure namespace relocation; no functional impact detected.
src/Aspire/BookWorm.AppHost/Extensions/AI/ModelExtensions.cs (1)
1-1: Namespace update acknowledgedNo behavioural change; implementation remains intact.
src/Aspire/BookWorm.AppHost/GlobalUsings.cs (1)
5-9: Check for type collisions with new global usingsAdding five broad namespaces increases the chance of ambiguous type names (e.g., multiple
Extensionsclasses). Monitor for CS0104 warnings during build.src/Aspire/BookWorm.AppHost/Extensions/Testing/K6Extensions.cs (2)
3-3: Namespace move looks correct—verify callers/imports.The namespace now matches the physical folder (
Extensions/Testing). Please run a quick IDE-wide search or build to catch any leftoverusing BookWorm.AppHost.Extensions;directives referencing the old location.
52-53: EnsureWithK6OtlpEnvironment()extension is referenced.Nice addition for OTLP, but double-check that the extension is included via a referenced package/namespace in this compilation unit; otherwise the fluent chain will fail to resolve.
src/Services/Notification/BookWorm.Notification/IntegrationEvents/EventHandlers/PlaceOrderCommandHandler.cs (1)
32-33: Pass the cancellation token toSendAsync
sender.SendAsyncalready receivescontext.CancellationToken, but the preceding fluent builder (WithFrom/WithBody) does not honour it. If any of those steps allocate resources (e.g. render Razor views) they should be cancellable. Consider extending the builder API or at least documenting that it is safe to block.src/Services/Notification/BookWorm.Notification/IntegrationEvents/EventHandlers/CompleteOrderCommandHandler.cs (1)
32-33: Cancellation token propagationBuilder chain (
WithFrom, etc.) still ignorescontext.CancellationToken. Propagate or expose async alternatives.src/Services/Chat/BookWorm.Chat/Infrastructure/ConversationState/MessageBuffer.cs (1)
169-170: Potential double flushing
_logBuffer.Flush()is called only on exception paths.
If successful flushes are important to capture before process shutdown, consider flushing in thefinallyblock as well (or rely on the built-in periodic flush interval).
No change needed if the current behaviour is intentional.src/Services/Notification/BookWorm.Notification.UnitTests/Consumers/CompleteOrderConsumerTests.cs (1)
21-48: Configuration object injection looks goodThe switch from
EmailOptionstoMailKitSettingsis clean and the DI registration viaAddSingletonensures all collaborators receive the same instance. No functional or test-isolation issues spotted.Also applies to: 78-110, 145-189
src/Services/Notification/BookWorm.Notification/Workers/ResendErrorEmailWorker.cs (2)
29-33:GlobalLogBuffer.Flush()is synchronous – consider async overloadFlushing the buffer inside an async job path can cause thread-pool starvation if the flush operation is heavy.
GlobalLogBufferexposesFlushAsync(); using it inside thecatchblocks would keep the method fully asynchronous.- logBuffer.Flush(); + await logBuffer.FlushAsync(cancellationToken);[ suggest_optional_refactor ]
Also applies to: 74-77
60-66: Verify the “From” address completeness
WithFrom(mailKitSettings)will typically use bothFromandName.ResendErrorEmailWorkerpasses only the settings coming from configuration; double-check thatNameis also configured, otherwise you may send messages with an empty display name which some mail providers treat as spam.src/Services/Notification/BookWorm.Notification/Extensions/Extensions.cs (1)
37-47: Service-registration sequence LGTMThe new
AddMailKitClient/AddSendGridClientAPIs plusAddEmailOutboxare in the correct order — the concrete senders are registered before the outbox decorator. Nothing else to flag.src/Services/Notification/BookWorm.Notification.UnitTests/Consumers/PlaceOrderConsumerTests.cs (1)
85-112: New faker helpers integrate nicelyThe switch to
WithNullEmail/WithEmptyEmailAddresshelpers simplifies the test intent; good improvement.src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/SendGrid/SendGridExtensions.cs (1)
24-24:Configure<T>overload likely mis-used
services.Configure<SendGridSettings>(configurationSection);passes only the section name, not theIConfigurationSection. Unless you have a custom extension, the typical call is:services.Configure<SendGridSettings>( builder.Configuration.GetSection(configurationSection));Double-check the overload to ensure the options are actually bound.
src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/MailKit/MailKitSender.cs (1)
19-25:nameof(Notification)may not resolve – verify pipeline key
Notificationis a namespace segment, not a type.nameofaccepts namespace names only from C# 11 onward. If you’re compiling with an older language version this will fail. Consider hard-coding the key or moving it to aconst string:private const string PipelineName = "Notification"; ... var pipeline = provider.GetPipeline(PipelineName);src/Services/Chat/BookWorm.Chat/Infrastructure/ConversationState/RedisConversationState.cs (1)
154-168: Good practice – explicit log buffer flush on disposeExplicitly flushing
_logBufferin the disposal path ensures no buffered entries are lost. Nice catch.src/Services/Notification/BookWorm.Notification.UnitTests/Fakers/TestDataFakers.cs (1)
17-24: Constructor argument order drift – verify correctnessThe new instantiation order inserts the second
GuidbeforePlaceOrderCommand’s signature really changed; otherwise tests will silently generate invalid commands.src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/SendGrid/SendGridSettings.cs (2)
9-9: ChangingConfigurationSectiontointernalmay break external registration code
ConfigurationSectionwas previouslypublic. Any code outside theBookWorm.Notificationassembly that relied on
SendGridSettings.ConfigurationSection(e.g., inAppHostor test projects that bind options) will now fail to compile.
Double-check all callers and, if the constant really shouldn’t leak, expose a helper in the new registration extension so
consumers don’t need to hard-code the string.
1-24: Verify thatSystem.ComponentModel.DataAnnotationsis in the global-usings setAll of the attributes used (
Required,MaxLength, etc.) come fromSystem.ComponentModel.DataAnnotations.
If noglobal usingexists, add the explicit import to avoid build errors in IDEs that don’t honour the SDK’s implicit-using list.+using System.ComponentModel.DataAnnotations;
Test Results913 tests - 33 913 ✅ - 33 5m 21s ⏱️ + 3m 15s Results for commit 5406e19. ± Comparison against base commit 8618443. This pull request removes 33 tests.♻️ This comment has been updated with latest results. |
752648d to
1b80b3a
Compare
There was a problem hiding this comment.
Actionable comments posted: 4
🔭 Outside diff range comments (1)
src/Services/Chat/BookWorm.Chat/Infrastructure/ChatStreaming/Extensions.cs (1)
35-57:IMcpClientis no longer resolvable – missing generic overloadDropping the generic overload registers the instance with service-type
object(or its concrete runtime type), soIMcpClientinjections will fail at runtime:-services.AddSingleton(_ => +services.AddSingleton<IMcpClient>(_ => { … return mcpClient; });Without the explicit service-type, any class that requests
IMcpClient(e.g.ChatStreaming) will receive nothing and triggerInvalidOperationException: Unable to resolve service for type 'IMcpClient' ….
♻️ Duplicate comments (2)
src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/MailKit/MailKitExtensions.cs (2)
43-43: Building a second rootServiceProvideris still present
Previous feedback about avoidingservices.BuildServiceProvider()has not been addressed. This creates a parallel container, duplicates singletons and leaks disposables.
Use the options pattern or access configuration directly (see prior suggestion).
55-55:MailKitClientFactoryshould beSingleton, notScopedA scoped registration spawns a factory (and SMTP client) per request, defeating the “one client per application” goal.
Switch toAddSingleton.- services.AddScoped(_ => new MailKitClientFactory(settings)); + services.AddSingleton(_ => new MailKitClientFactory(settings));
🧹 Nitpick comments (4)
src/Aspire/BookWorm.AppHost/Extensions/Infrastructure/AzureExtensions.Provision.cs (2)
9-23: XML documentation no longer matches the code — update the narrativeThe remarks still talk about “Premium ZRS + Hot access tier”, “Premium_P1 SKU with 10 capacity units”, etc., while the implementation now provisions
StandardLrs,Free_F1, and noAccessTier. The mismatch will mislead maintainers and reviewers.-/// - Storage accounts with Premium ZRS and Hot access tier -/// - SignalR services with Premium_P1 SKU and 10 capacity units +/// - Storage accounts with Standard LRS +/// - SignalR services with Free_F1 SKUAdjust the rest of the bullet list accordingly (PostgreSQL tier/capacity, Redis, etc.).
49-54: Duplicate tagging logic: extract a helper to improve DRYnessThe same
Tags.Add(nameof(Environment)…/Tags.Add(nameof(Projects)…block appears four times. A small extension method keeps the intent clear and future-proof:-resource.Tags.Add(nameof(Environment), builder.ApplicationBuilder.Environment.EnvironmentName); -resource.Tags.Add(nameof(Projects), nameof(BookWorm)); +resource.ApplyStandardTags(builder.ApplicationBuilder.Environment.EnvironmentName);// elsewhere internal static void ApplyStandardTags(this ITaggedResource resource, string environment) { resource.Tags.Add(nameof(Environment), environment); resource.Tags.Add(nameof(Projects), nameof(BookWorm)); }Also applies to: 75-80, 108-113, 167-172
src/Services/Chat/BookWorm.Chat/Infrastructure/ChatStreaming/ChatStreaming.cs (1)
135-136: Flush on success path as well for symmetrical logging
logBuffer.Flush()is invoked only on error/cancel branches. If everything succeeds, buffered logs may remain unflushed until an unrelated trigger occurs. Adding a flush in the success path (immediately after persisting the assistant message) keeps behaviour consistent.src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/MailKit/MailKitClientFactory.cs (1)
20-34: Reconnect also when authentication is lost
IsConnecteddoes not guarantee the session is still authenticated (many servers drop auth after idling).
Consider checking!_client.IsAuthenticatedtogether with!_client.IsConnectedso callers never receive a live-but-unauthenticated client.- if (_client is null || !_client.IsConnected) + if (_client is null || !_client.IsConnected || !_client.IsAuthenticated)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (61)
Directory.Packages.props(0 hunks)src/Aspire/BookWorm.AppHost/Extensions/AI/ModelExtensions.cs(1 hunks)src/Aspire/BookWorm.AppHost/Extensions/Infrastructure/AzureExtensions.Provision.cs(5 hunks)src/Aspire/BookWorm.AppHost/Extensions/Infrastructure/AzureExtensions.Run.cs(1 hunks)src/Aspire/BookWorm.AppHost/Extensions/Infrastructure/DashboardExtensions.cs(1 hunks)src/Aspire/BookWorm.AppHost/Extensions/Infrastructure/RedisResourceExtensions.cs(1 hunks)src/Aspire/BookWorm.AppHost/Extensions/Network/EmailExtensions.cs(1 hunks)src/Aspire/BookWorm.AppHost/Extensions/Network/EndpointExtensions.cs(1 hunks)src/Aspire/BookWorm.AppHost/Extensions/Network/LaunchProfileExtensions.cs(1 hunks)src/Aspire/BookWorm.AppHost/Extensions/Security/KeycloakExtensions.cs(1 hunks)src/Aspire/BookWorm.AppHost/Extensions/Testing/K6Extensions.cs(2 hunks)src/Aspire/BookWorm.AppHost/GlobalUsings.cs(1 hunks)src/Aspire/BookWorm.ServiceDefaults/Extensions.cs(2 hunks)src/BuildingBlocks/BookWorm.Chassis/Exceptions/GlobalExceptionHandler.cs(2 hunks)src/BuildingBlocks/BookWorm.Chassis/Exceptions/NotFoundExceptionHandler.cs(3 hunks)src/BuildingBlocks/BookWorm.Chassis/Exceptions/ValidationExceptionHandler.cs(2 hunks)src/Services/Chat/BookWorm.Chat/Infrastructure/ChatStreaming/ChatContext.cs(1 hunks)src/Services/Chat/BookWorm.Chat/Infrastructure/ChatStreaming/ChatStreaming.cs(13 hunks)src/Services/Chat/BookWorm.Chat/Infrastructure/ChatStreaming/Extensions.cs(2 hunks)src/Services/Chat/BookWorm.Chat/Infrastructure/ConversationState/MessageBuffer.cs(5 hunks)src/Services/Chat/BookWorm.Chat/Infrastructure/ConversationState/RedisConversationState.cs(6 hunks)src/Services/Notification/BookWorm.Notification.UnitTests/Consumers/CancelOrderConsumerTests.cs(6 hunks)src/Services/Notification/BookWorm.Notification.UnitTests/Consumers/CompleteOrderConsumerTests.cs(7 hunks)src/Services/Notification/BookWorm.Notification.UnitTests/Consumers/PlaceOrderConsumerTests.cs(6 hunks)src/Services/Notification/BookWorm.Notification.UnitTests/Domain/EmailOptionsTests.cs(0 hunks)src/Services/Notification/BookWorm.Notification.UnitTests/Domain/JobOptionsTests.cs(0 hunks)src/Services/Notification/BookWorm.Notification.UnitTests/Domain/SendGridOptionsTests.cs(0 hunks)src/Services/Notification/BookWorm.Notification.UnitTests/Fakers/FakerExtensions.cs(1 hunks)src/Services/Notification/BookWorm.Notification.UnitTests/Fakers/TestDataFakers.cs(1 hunks)src/Services/Notification/BookWorm.Notification.UnitTests/Workers/CleanUpSentEmailWorkerTests.cs(3 hunks)src/Services/Notification/BookWorm.Notification.UnitTests/Workers/ResendErrorEmailWorkerTests.cs(3 hunks)src/Services/Notification/BookWorm.Notification/BookWorm.Notification.csproj(0 hunks)src/Services/Notification/BookWorm.Notification/Domain/Builders/OrderMimeMessageBuilder.cs(2 hunks)src/Services/Notification/BookWorm.Notification/Domain/Settings/EmailOptions.cs(0 hunks)src/Services/Notification/BookWorm.Notification/Extensions/Extensions.cs(2 hunks)src/Services/Notification/BookWorm.Notification/GlobalUsings.cs(0 hunks)src/Services/Notification/BookWorm.Notification/Infrastructure/Job/Extensions.cs(1 hunks)src/Services/Notification/BookWorm.Notification/Infrastructure/Job/JobSettings.cs(1 hunks)src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/Extensions/Extensions.cs(0 hunks)src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/Extensions/MailPitEndpointExtensions.cs(0 hunks)src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/Extensions/SenderWithTelemetryExtensions.cs(0 hunks)src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/Factories/ISmtpClientFactory.cs(0 hunks)src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/Factories/SmtpClientFactory.cs(0 hunks)src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/Factories/SmtpClientFactoryObjectPoolPolicy.cs(0 hunks)src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/MailKit/MailKitClientFactory.cs(1 hunks)src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/MailKit/MailKitExtensions.cs(1 hunks)src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/MailKit/MailKitHealthCheck.cs(1 hunks)src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/MailKit/MailKitSender.cs(1 hunks)src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/MailKit/MailKitSettings.cs(1 hunks)src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/Outbox/EmailOutboxService.cs(2 hunks)src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/Outbox/OutboxExtensions.cs(1 hunks)src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/Providers/MailKitSender.cs(0 hunks)src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/SendGrid/SendGridExtensions.cs(1 hunks)src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/SendGrid/SendGridSender.cs(2 hunks)src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/SendGrid/SendGridSettings.cs(1 hunks)src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/TelemetryTags.cs(0 hunks)src/Services/Notification/BookWorm.Notification/IntegrationEvents/EventHandlers/CancelOrderCommandHandler.cs(2 hunks)src/Services/Notification/BookWorm.Notification/IntegrationEvents/EventHandlers/CompleteOrderCommandHandler.cs(2 hunks)src/Services/Notification/BookWorm.Notification/IntegrationEvents/EventHandlers/PlaceOrderCommandHandler.cs(2 hunks)src/Services/Notification/BookWorm.Notification/Workers/CleanUpSentEmailWorker.cs(3 hunks)src/Services/Notification/BookWorm.Notification/Workers/ResendErrorEmailWorker.cs(4 hunks)
💤 Files with no reviewable changes (15)
- src/Services/Notification/BookWorm.Notification/BookWorm.Notification.csproj
- Directory.Packages.props
- src/Services/Notification/BookWorm.Notification/GlobalUsings.cs
- src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/Factories/ISmtpClientFactory.cs
- src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/Factories/SmtpClientFactory.cs
- src/Services/Notification/BookWorm.Notification.UnitTests/Domain/JobOptionsTests.cs
- src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/Extensions/MailPitEndpointExtensions.cs
- src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/Extensions/SenderWithTelemetryExtensions.cs
- src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/Factories/SmtpClientFactoryObjectPoolPolicy.cs
- src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/TelemetryTags.cs
- src/Services/Notification/BookWorm.Notification.UnitTests/Domain/EmailOptionsTests.cs
- src/Services/Notification/BookWorm.Notification.UnitTests/Domain/SendGridOptionsTests.cs
- src/Services/Notification/BookWorm.Notification/Domain/Settings/EmailOptions.cs
- src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/Providers/MailKitSender.cs
- src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/Extensions/Extensions.cs
✅ Files skipped from review due to trivial changes (2)
- src/Aspire/BookWorm.ServiceDefaults/Extensions.cs
- src/Services/Chat/BookWorm.Chat/Infrastructure/ChatStreaming/ChatContext.cs
🚧 Files skipped from review as they are similar to previous changes (39)
- src/Aspire/BookWorm.AppHost/Extensions/Network/EndpointExtensions.cs
- src/Aspire/BookWorm.AppHost/Extensions/Network/LaunchProfileExtensions.cs
- src/Aspire/BookWorm.AppHost/Extensions/Network/EmailExtensions.cs
- src/Aspire/BookWorm.AppHost/Extensions/Infrastructure/DashboardExtensions.cs
- src/Aspire/BookWorm.AppHost/Extensions/Security/KeycloakExtensions.cs
- src/Aspire/BookWorm.AppHost/Extensions/Infrastructure/RedisResourceExtensions.cs
- src/Aspire/BookWorm.AppHost/Extensions/AI/ModelExtensions.cs
- src/Services/Notification/BookWorm.Notification/Domain/Builders/OrderMimeMessageBuilder.cs
- src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/SendGrid/SendGridSettings.cs
- src/Services/Notification/BookWorm.Notification/Infrastructure/Job/Extensions.cs
- src/BuildingBlocks/BookWorm.Chassis/Exceptions/NotFoundExceptionHandler.cs
- src/Services/Notification/BookWorm.Notification/Workers/CleanUpSentEmailWorker.cs
- src/Aspire/BookWorm.AppHost/GlobalUsings.cs
- src/BuildingBlocks/BookWorm.Chassis/Exceptions/ValidationExceptionHandler.cs
- src/Services/Notification/BookWorm.Notification/IntegrationEvents/EventHandlers/CompleteOrderCommandHandler.cs
- src/BuildingBlocks/BookWorm.Chassis/Exceptions/GlobalExceptionHandler.cs
- src/Services/Notification/BookWorm.Notification/Infrastructure/Job/JobSettings.cs
- src/Services/Notification/BookWorm.Notification.UnitTests/Workers/CleanUpSentEmailWorkerTests.cs
- src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/Outbox/EmailOutboxService.cs
- src/Services/Notification/BookWorm.Notification.UnitTests/Workers/ResendErrorEmailWorkerTests.cs
- src/Services/Notification/BookWorm.Notification/IntegrationEvents/EventHandlers/CancelOrderCommandHandler.cs
- src/Aspire/BookWorm.AppHost/Extensions/Testing/K6Extensions.cs
- src/Services/Chat/BookWorm.Chat/Infrastructure/ConversationState/MessageBuffer.cs
- src/Services/Notification/BookWorm.Notification.UnitTests/Consumers/CancelOrderConsumerTests.cs
- src/Services/Notification/BookWorm.Notification/Workers/ResendErrorEmailWorker.cs
- src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/SendGrid/SendGridExtensions.cs
- src/Services/Notification/BookWorm.Notification.UnitTests/Consumers/CompleteOrderConsumerTests.cs
- src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/MailKit/MailKitHealthCheck.cs
- src/Services/Notification/BookWorm.Notification/IntegrationEvents/EventHandlers/PlaceOrderCommandHandler.cs
- src/Services/Notification/BookWorm.Notification.UnitTests/Consumers/PlaceOrderConsumerTests.cs
- src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/SendGrid/SendGridSender.cs
- src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/Outbox/OutboxExtensions.cs
- src/Services/Chat/BookWorm.Chat/Infrastructure/ConversationState/RedisConversationState.cs
- src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/MailKit/MailKitSender.cs
- src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/MailKit/MailKitSettings.cs
- src/Services/Notification/BookWorm.Notification.UnitTests/Fakers/TestDataFakers.cs
- src/Aspire/BookWorm.AppHost/Extensions/Infrastructure/AzureExtensions.Run.cs
- src/Services/Notification/BookWorm.Notification.UnitTests/Fakers/FakerExtensions.cs
- src/Services/Notification/BookWorm.Notification/Extensions/Extensions.cs
🧰 Additional context used
🧬 Code Graph Analysis (2)
src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/MailKit/MailKitClientFactory.cs (2)
src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/MailKit/MailKitHealthCheck.cs (1)
Task(5-19)src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/MailKit/MailKitSender.cs (1)
Task(13-40)
src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/MailKit/MailKitExtensions.cs (5)
src/Aspire/BookWorm.ServiceDefaults/Configuration/ConfigurationExtensions.cs (1)
GetRequiredConnectionString(25-37)src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/MailKit/MailKitSettings.cs (1)
ParseConnectionString(27-89)src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/MailKit/MailKitClientFactory.cs (1)
MailKitClientFactory(3-52)src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/MailKit/MailKitHealthCheck.cs (1)
MailKitHealthCheck(3-20)src/BuildingBlocks/BookWorm.Constants/Aspire/Components.cs (1)
Components(3-43)
⏰ Context from checks skipped due to timeout of 90000ms (7)
- GitHub Check: Analyzers
- GitHub Check: Style
- GitHub Check: Security Scan
- GitHub Check: Security Scan
- GitHub Check: Style
- GitHub Check: Analyzers
- GitHub Check: Build and analyze
🔇 Additional comments (3)
src/Aspire/BookWorm.AppHost/Extensions/Infrastructure/AzureExtensions.Provision.cs (1)
45-48: Good catch switching to.Single()Using
Single()removes the silent-failure path previously discussed and aligns with the stricter provisioning style. No further concerns here.src/Services/Chat/BookWorm.Chat/Infrastructure/ChatStreaming/Extensions.cs (1)
11-17: Registration ofChatContextlooks goodThe composite object is resolved purely from existing singleton services and is itself registered as a singleton – perfect fit.
src/Services/Chat/BookWorm.Chat/Infrastructure/ChatStreaming/ChatStreaming.cs (1)
170-172: Cancellation token disposal race
await chatContext.CancellationManager.CancelAsync(assistantReplyId)runs after the final fragment is published. If any consumer awaits that fragment beforeCancelAsynccompletes, they may observe an already-cancelled token. Typically you’d cancel before signalling completion to downstream consumers. Please double-check the intended order.
1b80b3a to
5406e19
Compare
There was a problem hiding this comment.
Actionable comments posted: 0
♻️ Duplicate comments (2)
src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/MailKit/MailKitExtensions.cs (2)
41-43: Compile error & duplicated-root-provider pattern persist
services.Configure<MailKitSettings>(sectionName);targets a non-existent overload, and the subsequentBuildServiceProvider()creates a second root container – both problems were flagged in the last review.- services.Configure<MailKitSettings>(sectionName); - - var settings = services.BuildServiceProvider().GetRequiredService<MailKitSettings>(); +var settings = builder.Configuration // avoid extra root provider + .GetSection(sectionName) + .Get<MailKitSettings>() ?? new();This binds the section correctly and removes the extra service provider.
55-56:MailKitClientFactoryshould be a singletonCreating the factory per scope recreates the underlying SMTP client, defeating connection reuse and increasing resource consumption. Register it once:
- services.AddScoped(_ => new MailKitClientFactory(settings)); + services.AddSingleton(_ => new MailKitClientFactory(settings));
🧹 Nitpick comments (1)
src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/MailKit/MailKitExtensions.cs (1)
1-3: Unused using directive
using MailKit;is never referenced in this file and can be removed to keep the compilation unit tidy.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (61)
Directory.Packages.props(0 hunks)src/Aspire/BookWorm.AppHost/Extensions/AI/ModelExtensions.cs(1 hunks)src/Aspire/BookWorm.AppHost/Extensions/Infrastructure/AzureExtensions.Provision.cs(5 hunks)src/Aspire/BookWorm.AppHost/Extensions/Infrastructure/AzureExtensions.Run.cs(1 hunks)src/Aspire/BookWorm.AppHost/Extensions/Infrastructure/DashboardExtensions.cs(1 hunks)src/Aspire/BookWorm.AppHost/Extensions/Infrastructure/RedisResourceExtensions.cs(1 hunks)src/Aspire/BookWorm.AppHost/Extensions/Network/EmailExtensions.cs(1 hunks)src/Aspire/BookWorm.AppHost/Extensions/Network/EndpointExtensions.cs(1 hunks)src/Aspire/BookWorm.AppHost/Extensions/Network/LaunchProfileExtensions.cs(1 hunks)src/Aspire/BookWorm.AppHost/Extensions/Security/KeycloakExtensions.cs(1 hunks)src/Aspire/BookWorm.AppHost/Extensions/Testing/K6Extensions.cs(2 hunks)src/Aspire/BookWorm.AppHost/GlobalUsings.cs(1 hunks)src/Aspire/BookWorm.ServiceDefaults/Extensions.cs(2 hunks)src/BuildingBlocks/BookWorm.Chassis/Exceptions/GlobalExceptionHandler.cs(2 hunks)src/BuildingBlocks/BookWorm.Chassis/Exceptions/NotFoundExceptionHandler.cs(3 hunks)src/BuildingBlocks/BookWorm.Chassis/Exceptions/ValidationExceptionHandler.cs(2 hunks)src/Services/Chat/BookWorm.Chat/Infrastructure/ChatStreaming/ChatContext.cs(1 hunks)src/Services/Chat/BookWorm.Chat/Infrastructure/ChatStreaming/ChatStreaming.cs(13 hunks)src/Services/Chat/BookWorm.Chat/Infrastructure/ChatStreaming/Extensions.cs(2 hunks)src/Services/Chat/BookWorm.Chat/Infrastructure/ConversationState/MessageBuffer.cs(5 hunks)src/Services/Chat/BookWorm.Chat/Infrastructure/ConversationState/RedisConversationState.cs(6 hunks)src/Services/Notification/BookWorm.Notification.UnitTests/Consumers/CancelOrderConsumerTests.cs(6 hunks)src/Services/Notification/BookWorm.Notification.UnitTests/Consumers/CompleteOrderConsumerTests.cs(7 hunks)src/Services/Notification/BookWorm.Notification.UnitTests/Consumers/PlaceOrderConsumerTests.cs(6 hunks)src/Services/Notification/BookWorm.Notification.UnitTests/Domain/EmailOptionsTests.cs(0 hunks)src/Services/Notification/BookWorm.Notification.UnitTests/Domain/JobOptionsTests.cs(0 hunks)src/Services/Notification/BookWorm.Notification.UnitTests/Domain/SendGridOptionsTests.cs(0 hunks)src/Services/Notification/BookWorm.Notification.UnitTests/Fakers/FakerExtensions.cs(1 hunks)src/Services/Notification/BookWorm.Notification.UnitTests/Fakers/TestDataFakers.cs(1 hunks)src/Services/Notification/BookWorm.Notification.UnitTests/Workers/CleanUpSentEmailWorkerTests.cs(3 hunks)src/Services/Notification/BookWorm.Notification.UnitTests/Workers/ResendErrorEmailWorkerTests.cs(3 hunks)src/Services/Notification/BookWorm.Notification/BookWorm.Notification.csproj(0 hunks)src/Services/Notification/BookWorm.Notification/Domain/Builders/OrderMimeMessageBuilder.cs(2 hunks)src/Services/Notification/BookWorm.Notification/Domain/Settings/EmailOptions.cs(0 hunks)src/Services/Notification/BookWorm.Notification/Extensions/Extensions.cs(2 hunks)src/Services/Notification/BookWorm.Notification/GlobalUsings.cs(0 hunks)src/Services/Notification/BookWorm.Notification/Infrastructure/Job/Extensions.cs(1 hunks)src/Services/Notification/BookWorm.Notification/Infrastructure/Job/JobSettings.cs(1 hunks)src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/Extensions/Extensions.cs(0 hunks)src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/Extensions/MailPitEndpointExtensions.cs(0 hunks)src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/Extensions/SenderWithTelemetryExtensions.cs(0 hunks)src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/Factories/ISmtpClientFactory.cs(0 hunks)src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/Factories/SmtpClientFactory.cs(0 hunks)src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/Factories/SmtpClientFactoryObjectPoolPolicy.cs(0 hunks)src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/MailKit/MailKitClientFactory.cs(1 hunks)src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/MailKit/MailKitExtensions.cs(1 hunks)src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/MailKit/MailKitHealthCheck.cs(1 hunks)src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/MailKit/MailKitSender.cs(1 hunks)src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/MailKit/MailKitSettings.cs(1 hunks)src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/Outbox/EmailOutboxService.cs(2 hunks)src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/Outbox/OutboxExtensions.cs(1 hunks)src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/Providers/MailKitSender.cs(0 hunks)src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/SendGrid/SendGridExtensions.cs(1 hunks)src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/SendGrid/SendGridSender.cs(2 hunks)src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/SendGrid/SendGridSettings.cs(1 hunks)src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/TelemetryTags.cs(0 hunks)src/Services/Notification/BookWorm.Notification/IntegrationEvents/EventHandlers/CancelOrderCommandHandler.cs(2 hunks)src/Services/Notification/BookWorm.Notification/IntegrationEvents/EventHandlers/CompleteOrderCommandHandler.cs(2 hunks)src/Services/Notification/BookWorm.Notification/IntegrationEvents/EventHandlers/PlaceOrderCommandHandler.cs(2 hunks)src/Services/Notification/BookWorm.Notification/Workers/CleanUpSentEmailWorker.cs(3 hunks)src/Services/Notification/BookWorm.Notification/Workers/ResendErrorEmailWorker.cs(4 hunks)
💤 Files with no reviewable changes (15)
- src/Services/Notification/BookWorm.Notification/BookWorm.Notification.csproj
- src/Services/Notification/BookWorm.Notification.UnitTests/Domain/JobOptionsTests.cs
- Directory.Packages.props
- src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/TelemetryTags.cs
- src/Services/Notification/BookWorm.Notification/GlobalUsings.cs
- src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/Factories/ISmtpClientFactory.cs
- src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/Factories/SmtpClientFactory.cs
- src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/Extensions/SenderWithTelemetryExtensions.cs
- src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/Factories/SmtpClientFactoryObjectPoolPolicy.cs
- src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/Extensions/MailPitEndpointExtensions.cs
- src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/Providers/MailKitSender.cs
- src/Services/Notification/BookWorm.Notification/Domain/Settings/EmailOptions.cs
- src/Services/Notification/BookWorm.Notification.UnitTests/Domain/EmailOptionsTests.cs
- src/Services/Notification/BookWorm.Notification.UnitTests/Domain/SendGridOptionsTests.cs
- src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/Extensions/Extensions.cs
✅ Files skipped from review due to trivial changes (1)
- src/Aspire/BookWorm.ServiceDefaults/Extensions.cs
🚧 Files skipped from review as they are similar to previous changes (44)
- src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/SendGrid/SendGridSettings.cs
- src/Aspire/BookWorm.AppHost/Extensions/Infrastructure/DashboardExtensions.cs
- src/Aspire/BookWorm.AppHost/Extensions/Network/LaunchProfileExtensions.cs
- src/Aspire/BookWorm.AppHost/Extensions/Infrastructure/RedisResourceExtensions.cs
- src/Aspire/BookWorm.AppHost/Extensions/Network/EmailExtensions.cs
- src/Aspire/BookWorm.AppHost/GlobalUsings.cs
- src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/MailKit/MailKitClientFactory.cs
- src/Aspire/BookWorm.AppHost/Extensions/AI/ModelExtensions.cs
- src/Services/Notification/BookWorm.Notification.UnitTests/Workers/CleanUpSentEmailWorkerTests.cs
- src/Aspire/BookWorm.AppHost/Extensions/Security/KeycloakExtensions.cs
- src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/Outbox/EmailOutboxService.cs
- src/Aspire/BookWorm.AppHost/Extensions/Network/EndpointExtensions.cs
- src/Services/Chat/BookWorm.Chat/Infrastructure/ChatStreaming/Extensions.cs
- src/BuildingBlocks/BookWorm.Chassis/Exceptions/GlobalExceptionHandler.cs
- src/Services/Notification/BookWorm.Notification/Workers/CleanUpSentEmailWorker.cs
- src/Services/Notification/BookWorm.Notification/IntegrationEvents/EventHandlers/PlaceOrderCommandHandler.cs
- src/BuildingBlocks/BookWorm.Chassis/Exceptions/ValidationExceptionHandler.cs
- src/Services/Notification/BookWorm.Notification/IntegrationEvents/EventHandlers/CompleteOrderCommandHandler.cs
- src/Services/Chat/BookWorm.Chat/Infrastructure/ChatStreaming/ChatContext.cs
- src/Services/Notification/BookWorm.Notification/Domain/Builders/OrderMimeMessageBuilder.cs
- src/Services/Notification/BookWorm.Notification/Infrastructure/Job/Extensions.cs
- src/Aspire/BookWorm.AppHost/Extensions/Testing/K6Extensions.cs
- src/Services/Chat/BookWorm.Chat/Infrastructure/ConversationState/MessageBuffer.cs
- src/Services/Notification/BookWorm.Notification/Extensions/Extensions.cs
- src/Services/Notification/BookWorm.Notification/Workers/ResendErrorEmailWorker.cs
- src/Services/Notification/BookWorm.Notification.UnitTests/Consumers/CompleteOrderConsumerTests.cs
- src/Services/Notification/BookWorm.Notification/IntegrationEvents/EventHandlers/CancelOrderCommandHandler.cs
- src/Services/Notification/BookWorm.Notification/Infrastructure/Job/JobSettings.cs
- src/BuildingBlocks/BookWorm.Chassis/Exceptions/NotFoundExceptionHandler.cs
- src/Services/Notification/BookWorm.Notification.UnitTests/Workers/ResendErrorEmailWorkerTests.cs
- src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/SendGrid/SendGridExtensions.cs
- src/Services/Notification/BookWorm.Notification.UnitTests/Consumers/CancelOrderConsumerTests.cs
- src/Services/Notification/BookWorm.Notification.UnitTests/Consumers/PlaceOrderConsumerTests.cs
- src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/MailKit/MailKitHealthCheck.cs
- src/Aspire/BookWorm.AppHost/Extensions/Infrastructure/AzureExtensions.Run.cs
- src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/MailKit/MailKitSender.cs
- src/Services/Chat/BookWorm.Chat/Infrastructure/ConversationState/RedisConversationState.cs
- src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/SendGrid/SendGridSender.cs
- src/Services/Notification/BookWorm.Notification.UnitTests/Fakers/TestDataFakers.cs
- src/Services/Chat/BookWorm.Chat/Infrastructure/ChatStreaming/ChatStreaming.cs
- src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/Outbox/OutboxExtensions.cs
- src/Aspire/BookWorm.AppHost/Extensions/Infrastructure/AzureExtensions.Provision.cs
- src/Services/Notification/BookWorm.Notification/Infrastructure/Senders/MailKit/MailKitSettings.cs
- src/Services/Notification/BookWorm.Notification.UnitTests/Fakers/FakerExtensions.cs
⏰ Context from checks skipped due to timeout of 90000ms (7)
- GitHub Check: Style
- GitHub Check: Analyzers
- GitHub Check: Security Scan
- GitHub Check: Style
- GitHub Check: Analyzers
- GitHub Check: Security Scan
- GitHub Check: Build and analyze
|



Pull Request Description
This pull request refactors components of the email service and related infrastructure while aligning configuration and logging behavior across tests, state management, and exception handling.
Checklist
Summary by CodeRabbit
New Features
ChatContextservice to unify conversation state and cancellation management.Refactor
EmailOptions,SendGridOptions,JobOptions) with new settings classes (MailKitSettings,SendGridSettings,JobSettings).Bug Fixes
Tests
Chores