-
Notifications
You must be signed in to change notification settings - Fork 19
feat[event]: emit structured user role change event #833
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
Warning Rate limit exceeded@nevil-mathew has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 28 minutes and 0 seconds before requesting another review. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. 📒 Files selected for processing (1)
WalkthroughRefactors updateRoleForApprovedRequest to async/try-catch: captures old organizations, creates role association, refetches updated user, computes organizations diff, builds eventBodyDTO (with timestamps), broadcasts via broadcastUserEvent (internal, userEvents), invalidates Redis user cache, returns { success: true } or throws on error. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant OA as OrgAdmin Service
participant DB as Data Store
participant BC as Broadcaster
participant RC as Redis Cache
rect rgba(230,245,255,0.6)
note right of OA: updateRoleForApprovedRequest (async)
OA->>DB: Read user (oldOrganizations)
DB-->>OA: user (oldOrganizations)
OA->>DB: Create/Update role association
DB-->>OA: role result
OA->>DB: Fetch updated user (newOrganizations, timestamps)
DB-->>OA: updatedUser
OA->>OA: Build eventBodyDTO (old vs new orgs, created_at, updated_at)
end
rect rgba(235,255,235,0.6)
OA->>BC: broadcastUserEvent(eventBodyDTO, internal: true, type: userEvents)
BC-->>OA: Ack
OA->>RC: Delete Redis user cache key
RC-->>OA: Done
end
rect rgba(255,240,240,0.6)
alt Error
OA-->>OA: throw error
end
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
Warning Review ran into problems🔥 ProblemsGit: Failed to clone repository. Please run the Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🧪 Early access (Sonnet 4.5): enabledWe are currently testing the Sonnet 4.5 model, which is expected to improve code review quality. However, this model may lead to increased noise levels in the review comments. Please disable the early access features if the noise level causes any inconvenience. Note:
Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (2)
src/services/org-admin.js (2)
652-656: Consider race conditions when refetching user data.Refetching the user after creating the role assignment is necessary to get the updated organizations array. However, if other concurrent operations modify the user between lines 645-650 and 652-656, you might capture unrelated changes in the event payload.
While this is unlikely in practice for role assignments, consider whether the event should only reflect the specific role change rather than all organization differences.
684-686: Cache invalidation occurs after event broadcast - verify this order is intentional.The user cache is cleared after broadcasting the event. If downstream event consumers query the user service expecting fresh data, they might receive stale cached data before this invalidation completes.
Consider whether cache invalidation should occur before broadcasting to ensure consistency for event consumers.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
src/services/org-admin.js(3 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
src/services/**
⚙️ CodeRabbit configuration file
This is core business logic. Please check for correctness, efficiency, and potential edge cases.
Files:
src/services/org-admin.js
🧠 Learnings (4)
📓 Common learnings
Learnt from: praveenKDass
PR: ELEVATE-Project/user#816
File: src/services/organization.js:831-0
Timestamp: 2025-09-12T10:40:34.860Z
Learning: In the ELEVATE-Project/user codebase, the organizationDTO.eventBodyDTO is designed to handle empty changes arrays properly, so organization update events should always be emitted even when changedValues is empty. The DTO handles this scenario correctly and there may be other reasons to emit events beyond just field changes (like metadata updates).
📚 Learning: 2025-09-12T10:40:34.860Z
Learnt from: praveenKDass
PR: ELEVATE-Project/user#816
File: src/services/organization.js:831-0
Timestamp: 2025-09-12T10:40:34.860Z
Learning: In the ELEVATE-Project/user codebase, the organizationDTO.eventBodyDTO is designed to handle empty changes arrays properly, so organization update events should always be emitted even when changedValues is empty. The DTO handles this scenario correctly and there may be other reasons to emit events beyond just field changes (like metadata updates).
Applied to files:
src/services/org-admin.js
📚 Learning: 2025-09-12T11:02:51.008Z
Learnt from: praveenKDass
PR: ELEVATE-Project/user#816
File: src/dtos/organizationDTO.js:14-43
Timestamp: 2025-09-12T11:02:51.008Z
Learning: In the ELEVATE-Project/user codebase, oldValue and newValue in the changedValues array for organizationDTO.eventBodyDTO are guaranteed to not be undefined by the business logic, and filtering out falsy values (0, false, '') from changes is the intended behavior.
Applied to files:
src/services/org-admin.js
📚 Learning: 2025-09-12T10:35:28.285Z
Learnt from: praveenKDass
PR: ELEVATE-Project/user#816
File: src/services/admin.js:704-704
Timestamp: 2025-09-12T10:35:28.285Z
Learning: In ELEVATE-Project/user admin.js, there's an inconsistency in organizationQueries.update usage: addOrgAdmin calls it without options (returns number), while deactivateOrg calls it with { returning: true, raw: true } (returns object). The validation logic 'if (orgRowsAffected === 0)' only works for the first case - the second case needs 'if (orgRowsAffected.rowsAffected === 0)' to properly validate updates.
Applied to files:
src/services/org-admin.js
🧬 Code graph analysis (1)
src/services/org-admin.js (4)
src/services/admin.js (11)
require(11-11)require(27-27)require(34-34)require(36-36)require(37-37)user(54-54)user(200-203)user(338-338)user(449-449)eventBody(63-80)eventBody(207-218)src/services/account.js (16)
require(26-26)require(27-27)require(37-37)require(41-41)user(136-145)user(703-703)user(848-848)user(898-898)user(1051-1051)user(1204-1213)user(1385-1393)user(1733-1733)user(1956-1959)user(2067-2067)eventBody(604-623)eventBody(1754-1769)src/database/queries/users.js (1)
user(225-270)src/services/user.js (1)
eventBody(191-201)
🔇 Additional comments (4)
src/services/org-admin.js (4)
31-32: LGTM!The new imports for structured event broadcasting align with the codebase's event-driven architecture.
662-668: Event may be emitted even when organizations array is identical.If the role assignment doesn't materially change the organizations array structure (e.g., the organization was already present with different roles),
oldOrganizationsandnewOrganizationscould be identical or very similar. The event will still be emitted with a changedValues array containing the same data in both fields.Based on learnings, empty or unchanged changedValues arrays are acceptable as the DTO handles them properly. However, verify this is the intended behavior for role changes where the organizations array structure remains unchanged.
Based on learnings
670-682: eventBodyDTO usage is correct.The eventBodyDTO function signature accepts
changedValuesas a top-level parameter (not withinargs). The function is defined insrc/dtos/userDTO.js:80as:eventBodyDTO({ entity, eventType, entityId, changedValues = [], args = {} })The calling code correctly passes
changedValuesat the top level andargscontainingcreated_atandupdated_at. The DTO transforms thechangedValuesarray into achangesobject and spreadsargsinto the returned event body.Likely an incorrect or invalid review comment.
641-642: The concern aboutuser.organizationsbeing undefined is not valid.The
UserTransformDTO.transformfunction (called infindUserWithOrganizationat line 274 ofsrc/database/queries/users.js) explicitly mapsuser.user_organizationstouser.organizationswith a built-in fallback to an empty array:organizations: (user.user_organizations || []).map((orgLink) => { ... })Since
findUserWithOrganizationis called without therawparameter on line 653, the transform is applied, guaranteeing thatuser.organizationswill always be an array (empty or populated). The fallback|| []on line 642 is redundant but harmless.Likely an incorrect or invalid review comment.
|
@coderabbitai summary |
✅ Actions performedSummary regeneration triggered. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (1)
src/services/org-admin.js (1)
681-684: Enhance error handling with context.The error handling logs and rethrows the error, but doesn't add context about which operation failed. This makes debugging difficult in production.
Consider adding contextual information to the error:
} catch (error) { - console.log(error, 'error') + console.error('Error updating role for approved request:', { + requestId: requestDetails.id, + userId: requestDetails.requester_id, + roleId: requestDetails.role, + error: error.message, + stack: error.stack + }) throw error }
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
src/services/org-admin.js(2 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
src/services/**
⚙️ CodeRabbit configuration file
This is core business logic. Please check for correctness, efficiency, and potential edge cases.
Files:
src/services/org-admin.js
🔇 Additional comments (5)
src/services/org-admin.js (5)
31-32: LGTM!The new imports for
broadcastUserEventandeventBodyDTOare appropriate for the structured event emission functionality introduced in this PR.
656-673: Well-structured event body construction.The changed values computation and event body DTO construction correctly capture:
- Old and new organizations state
- Entity metadata (id, type, eventType)
- Timestamps (created_at, updated_at)
This provides consumers with comprehensive information about the role change.
677-678: Cache invalidation correctly targets the updated user.The Redis key construction uses the tenant code and user ID, properly invalidating the cached user data after the role assignment.
642-647: Verify handling of duplicate role assignments.The
createoperation does not check if the user already has this role in the organization. If a user requests the same role multiple times and all are approved, this could create duplicate entries.Run the following script to check if the database schema or query method prevents duplicates:
675-675: Verify theisInternalflag behavior.The
isInternal: trueflag is passed tobroadcastUserEvent. Ensure this flag correctly limits the event to internal consumers and does not inadvertently suppress necessary external notifications.Run the following script to understand how the
isInternalflag is handled:
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
Summary by CodeRabbit
Bug Fixes
Refactor
Chores