[PM-22450] Bump Collection.RevisionDate on edits and access changes#7380
[PM-22450] Bump Collection.RevisionDate on edits and access changes#7380
Conversation
…d update corresponding tests. Adjust tests to verify correct RevisionDate assignment during collection updates.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #7380 +/- ##
==========================================
+ Coverage 62.43% 62.74% +0.30%
==========================================
Files 2060 2060
Lines 90974 91245 +271
Branches 8087 8119 +32
==========================================
+ Hits 56803 57251 +448
+ Misses 32216 32019 -197
- Partials 1955 1975 +20 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
New Issues (119)Checkmarx found the following issues in this Pull Request
|
There was a problem hiding this comment.
The ticket says we need to bump the revision date in these scenarios:
- Whenever a collection has its name updated (including when it’s nested)
- Whenever a collection has its user/group assignment updated
- Whenever a user has their access to a collection updated
- Whenever a group has their access to a collection updated
I'm guessing this covers 1 and 2. What about 3 and 4? (That said - this PR is still good to merge.)
…cess updates. Update ICollectionRepository and its implementations to accept revision date parameter. Modify stored procedure to update collection revision dates accordingly. Add tests to verify correct behavior of access creation and revision date updates.
… affected collections during group creation and updates. Enhance integration tests to verify that collection revision dates are correctly updated when groups are created or modified.
…ionUserRepository and related stored procedures. Add integration tests to ensure revision dates are correctly bumped during organization user creation and updates.
Bitwarden Claude Code ReviewOverall Assessment: APPROVE This PR fixes Code Review DetailsNo findings. |
|
Great callout! I went even further and also updated when user is invited with collection access. |
| C.[Id] IN (SELECT [Id] FROM @Collections) -- New/updated assignments | ||
| OR C.[Id] IN ( | ||
| SELECT CG.[CollectionId] | ||
| FROM [dbo].[CollectionGroup] CG | ||
| WHERE CG.[GroupId] = @Id -- Existing assignments (includes ones being removed) | ||
| ) |
There was a problem hiding this comment.
Interested in @bitwarden/dept-dbops ' advice as to CTE vs. nested query here.
|
|
||
| -- Bump RevisionDate on all affected collections | ||
| UPDATE C | ||
| SET C.[RevisionDate] = GETUTCDATE() |
| FROM [dbo].[Collection] C | ||
| WHERE C.[Id] IN ( | ||
| SELECT OUC.[CollectionId] | ||
| FROM OPENJSON(@collectionData) |
There was a problem hiding this comment.
I think we want to avoid repeatedly parsing this json.
| @@ -1,4 +1,4 @@ | |||
| CREATE PROCEDURE [dbo].[OrganizationUser_UpdateWithCollections] | |||
| CREATE PROCEDURE [dbo].[OrganizationUser_UpdateWithCollections] | |||
There was a problem hiding this comment.
What's going on here in the diff? Sometimes claude can introduce invisible characters or change the encoding, just double check that's not happening here.
| foreach (var c in availableCollections.Where(a => filteredCollections.Any(fc => fc.Id == a.Id))) | ||
| { | ||
| c.RevisionDate = grp.RevisionDate; | ||
| } |
There was a problem hiding this comment.
Not sure about this nested Where/Any logic, particularly because this is filtering availableCollections to make sure they exist in filteredCollections, but filteredCollections is already a filter on availableCollections. I'm not sure what the purpose of this is.
| }); | ||
| await dbContext.CollectionUsers.AddRangeAsync(collectionUsers); | ||
| // Bump RevisionDate on all affected collections | ||
| foreach (var c in availableCollections.Where(a => filteredCollections.Any(fc => fc.Id == a.Id))) |
There was a problem hiding this comment.
Same here for the available/filtered logic.
| var affectedCollections = await dbContext.Collections | ||
| .Where(c => affectedCollectionIds.Contains(c.Id)) | ||
| .ToListAsync(); | ||
| var now = DateTime.UtcNow; |
| var affectedCollections = await dbContext.Collections | ||
| .Where(c => affectedCollectionIds.Contains(c.Id)) |
| Assert.True(actualCollection.RevisionDate > originalRevisionDate); | ||
| Assert.Equal(revisionDate, actualCollection.RevisionDate, TimeSpan.FromSeconds(1)); |
There was a problem hiding this comment.
You're setting it to a precise revisionDate, a 1 second allowance shouldn't be required.
|
|
||
| var (actualCollection, _) = await collectionRepository.GetByIdWithAccessAsync(collectionId); | ||
| Assert.NotNull(actualCollection); | ||
| Assert.True(actualCollection.RevisionDate > originalCollectionRevisionDate); |
There was a problem hiding this comment.
Same here, should be able to assert a precise revision date. (and throughout all other tests)






🎟️ Tracking
https://bitwarden.atlassian.net/browse/PM-22450
📔 Objective
Collection.RevisionDatewas not updated when a collection was edited or when its access changed. Clients rely on this date to know when to re-sync. This PR bumps it across all code paths: collection edits viaUpdateCollectionCommand, user/group assignment changes, and bulk access operations -- in both stored procedures and EF repositories.