Refactor monolithic IErrorMessageDataStore into specialized interfaces - #5661
Open
johnsimons wants to merge 1 commit into
Open
Refactor monolithic IErrorMessageDataStore into specialized interfaces#5661johnsimons wants to merge 1 commit into
johnsimons wants to merge 1 commit into
Conversation
This change decomposes the single, large `IErrorMessageDataStore` interface into several smaller, more focused interfaces such as `IMessagesViewDataStore`, `IFailedMessageQueryDataStore`, `IFailedMessageLifecycleDataStore`, `IFailedMessageRetryDataStore`, `IEditFailedMessagesDataStore`, and `INotificationsDataStore`. This refactoring improves the separation of concerns, enhances testability, and aligns the codebase with the Interface Segregation and Single Responsibility Principles. Existing implementations and consumers across both EFCore and RavenDB persistence layers, as well as application logic, have been updated to utilize these new, more specific contracts.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Split
IErrorMessageDataStoreIErrorMessageDataStorehad grown to 32 members referenced from 41 files, spanning message views, failed-message queries, status transitions, retry support, failure groups, notifications, message editing, failed-import writes, and event-log writes. This splits it along those seams and deletes it.Two things drove the grouping:
ArchiveMessageHandler,LegacyMessageFailureResolvedHandler,MessageFailureResolvedHandler, andEditFailedMessagesController, which each touch exactly two and now take two dependencies.// must set StatusChangedAt + LastModifiedcomment, and those are precisely the status-mutating writes. That shared invariant is now one interface.New interfaces
IMessagesViewDataStoreCompositeViews/MessagesIFailedMessageQueryDataStoreGetAllErrorsController,GetErrorByIdController,EditFailedMessagesController,ArchiveMessageHandler,MessageFailedPublisherIFailedMessageLifecycleDataStoreReturnToSenderDequeuerIFailedMessageRetryDataStorePendingRetriesHandler,RetriesHandler,FailedMessageRetryCleaner,ReturnToSender,MessageFailureResolvedHandlerINotificationsDataStoreNotificationsController,SendEmailNotificationHandlerIEditFailedMessagesDataStoreEditFailedMessagesController,EditHandlerIFailedMessageRetryDataStoreis deliberately separate fromIRetryDocumentDataStore, which is about retry batches.Absorbed into existing interfaces
IGroupsDataStoregains 7 members:GetGroup,GetGroupErrors,GetGroupErrorsCount,GetFailureGroupView,EditComment,DeleteComment, andGetArchivedFailureGroupsByClassifier. That last one was calledGetFailureGroupsByClassifier, which collided with the method of the same name already onIGroupsDataStore. They are different queries (ArchivedGroupsViewIndexvsFailureGroupsViewIndex), so the incoming one is renamed.IFailedErrorImportDataStoregainsStoreFailedErrorImport. It already owned the read side (ProcessFailedErrorImports,QueryContainsFailedImports); only the write half was orphaned.StoreEventLogItemfolds intoIEventLogDataStore.Add. See below.Renames
ErrorGetGetFailedMessagesErrorsHeadGetFailedMessagesStatsErrorsByEndpointNameGetFailedMessagesByEndpointErrorsSummaryGetFailedMessagesSummaryErrorLastByGetLatestFailedMessageViewErrorByGetFailedMessageFailedMessagesFetchGetFailedMessagesByIdsFailedMessageMarkAsArchivedMarkAsArchivedMarkMessageAsResolvedMarkAsResolvedRemoveFailedMessageRetryDocumentRemoveFailedMessageRetryFetchFromFailedMessageGetFailedMessageBody"Document" was RavenDB vocabulary leaking into a provider-agnostic abstraction, and
FetchFromFailedMessagereturns the body bytes. HTTP action names and routes are untouched, so there is no API surface change.One behavioural decision worth reviewing
StoreEventLogItemandIEventLogDataStore.Addwere near-duplicates in RavenDB: the former calledexpirationManager.EnableExpiration(session, logItem), the latter did not.Addhad no production caller, and the only writer of event-log items (AuditEventLogWriter) went throughStoreEventLogItem, so expiration was in effect for every event-log item actually written. The consolidatedAddkeeps the expiration call, preserving current behaviour rather than silently dropping it. Flagging it explicitly because it is the one change here that is not purely structural.Implementation shape
Interface segregation did not force class segregation:
ErrorMessagesDataStoreimplementing four of the new interfaces, wired with forwarding registrations, matching the pattern already used forExternalIntegrationRequestsDataStore. The group members moved intoRecoverability/GroupsDataStore, the import writer plus itsMakeDocumentId/CollectionNamestatics intoFailedErrorImportDataStore, and the two factory methods into small new stores underEditing/.StoreFailedErrorImportwas already implemented and moves across as-is.Tests
The two full-interface test doubles shrink from 32 members to 16 and 8.
PersistenceTestBasenow exposes one accessor per interface instead of two overlappingIErrorMessageDataStoreproperties, and gains a sharedFailedImportStore(the local copy inFailedErrorImportTestsis removed).