refactor(core): Extract participant resolution from the review inbox service (no-changelog) - #36918
Open
kgrhartlage wants to merge 1 commit into
Conversation
…e (no-changelog) Move requester/author/reviewer resolution out of WorkflowReviewInboxService into a WorkflowReviewParticipantResolver with a single resolve(requests) entry point. The resolver owns the reviewer, author and user repositories, so deleted-user handling and the user projection live in one place and both the inbox list and the detail view share them.
Contributor
Author
|
@cubic-dev-ai roast my PR |
Contributor
@kgrhartlage I have started the AI code review. It will take a few minutes to complete. |
Contributor
PR review overviewBased on ownership of the 5 changed files in this PR:
|
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
Contributor
There was a problem hiding this comment.
No issues found across 5 files
Architecture diagram
sequenceDiagram
participant Client as Client (Frontend)
participant InboxService as WorkflowReviewInboxService
participant Gate as WorkflowReviewFeatureGate
participant Resolver as NEW: WorkflowReviewParticipantResolver
participant JunctionRepos as Reviewer & Author Repositories
participant UserRepo as UserRepository
Note over Client,UserRepo: Workflow Review Inbox / Detail Flow
Client->>InboxService: getDetail(user, requestId) OR listForInbox(user)
InboxService->>Gate: isWorkflowReviewsLicensed()
Gate-->>InboxService: boolean
alt Feature Enabled
InboxService->>InboxService: Fetch Request/Workflow data from DB
InboxService->>Resolver: NEW: resolve(WorkflowReviewRequest[])
activate Resolver
Resolver->>JunctionRepos: findByRequestIds(ids)
JunctionRepos-->>Resolver: Junction Rows (Reviewers/Authors)
Resolver->>Resolver: Deduplicate User IDs (Requester + Authors + Reviewers)
opt User IDs present
Resolver->>UserRepo: findManyByIds(uniqueIds)
UserRepo-->>Resolver: User entities
end
Resolver-->>InboxService: NEW: WorkflowReviewParticipantLookup object
deactivate Resolver
InboxService->>InboxService: CHANGED: Map items using lookup.for(requestId)
Note right of InboxService: lookup.for() provides fallback defaults <br/>if request is missing from batch.
InboxService-->>Client: 200 OK (InboxItem or Detail)
else Feature Disabled
InboxService-->>Client: Error / Empty State
end
kgrhartlage
marked this pull request as ready for review
August 24, 2026 12:28
Contributor
There was a problem hiding this comment.
No issues found across 5 files
Architecture diagram
sequenceDiagram
participant Client as Client (Frontend)
participant InboxService as WorkflowReviewInboxService
participant Gate as WorkflowReviewFeatureGate
participant Resolver as NEW: WorkflowReviewParticipantResolver
participant JunctionRepos as Reviewer & Author Repositories
participant UserRepo as UserRepository
Note over Client,UserRepo: Workflow Review Inbox / Detail Flow
Client->>InboxService: getDetail(user, requestId) OR listForInbox(user)
InboxService->>Gate: isWorkflowReviewsLicensed()
Gate-->>InboxService: boolean
alt Feature Enabled
InboxService->>InboxService: Fetch Request/Workflow data from DB
InboxService->>Resolver: NEW: resolve(WorkflowReviewRequest[])
activate Resolver
Resolver->>JunctionRepos: findByRequestIds(ids)
JunctionRepos-->>Resolver: Junction Rows (Reviewers/Authors)
Resolver->>Resolver: Deduplicate User IDs (Requester + Authors + Reviewers)
opt User IDs present
Resolver->>UserRepo: findManyByIds(uniqueIds)
UserRepo-->>Resolver: User entities
end
Resolver-->>InboxService: NEW: WorkflowReviewParticipantLookup object
deactivate Resolver
InboxService->>InboxService: CHANGED: Map items using lookup.for(requestId)
Note right of InboxService: lookup.for() provides fallback defaults <br/>if request is missing from batch.
InboxService-->>Client: 200 OK (InboxItem or Detail)
else Feature Disabled
InboxService-->>Client: Error / Empty State
end
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.
Summary
WorkflowReviewInboxServicedid two jobs: it assembled the inbox and detail payloads, and it resolved who is involved in each review. This PR moves the second job into a newWorkflowReviewParticipantResolver.The resolver has one entry point,
resolve(requests). It owns the reviewer, author, and user repositories. It batches the two junction queries, does one deduplicated user lookup, and returns the requester, the authors, and the reviewers for each request id.resolvereturns a small lookup object with afor(requestId)method, so the "no entry" fallback stays inside the resolver.The inbox service now injects the resolver instead of the three repositories. The list view and the detail view both use it.
hydrateParticipantsandresolveParticipantsare removed, andtoInboxItemtakes one participants object instead of three positional parameters.The change is behavior preserving. The query fan-out is unchanged: the list still resolves participants in the same
Promise.allas the linked-workflow lookup, and the detail still resolves them in the samePromise.allas the workflow details and the eligibility check.Test changes:
workflow-review-participant.resolver.test.tsholds the participant behavior. It covers the requester, the authors, the reviewers, the keying across a batch, the deduplicated single user lookup, a deleted user that drops out, an unresolvable requester, and a request id outside the batch.How to test
This is an internal refactor with no API change. The inbox and detail responses are identical.
Automated:
Result: 243 unit tests pass and 240 integration tests pass. The integration run includes the 169-test workflow reviews controller suite, which exercises the participants end to end.
Manual (optional): the workflow reviews module needs
N8N_ENABLED_MODULES=workflow-reviewsand an enterprise license with the workflow reviews feature. Open the review inbox and then open a review. The requester, the authors, and the reviewers must show as before.Related Linear tickets, Github issues, and Community forum posts
https://linear.app/n8n/issue/LIGO-1042
Review / Merge checklist
Backport to Beta,Backport to Stable, orBackport to v1(if the PR is an urgent fix that needs to be backported)🤖 PR Summary generated by AI