Skip to content

[PM-22450] Bump Collection.RevisionDate on edits and access changes#7380

Open
r-tome wants to merge 7 commits intomainfrom
ac/pm-22450/collection-revision-date-is-not-updated
Open

[PM-22450] Bump Collection.RevisionDate on edits and access changes#7380
r-tome wants to merge 7 commits intomainfrom
ac/pm-22450/collection-revision-date-is-not-updated

Conversation

@r-tome
Copy link
Copy Markdown
Contributor

@r-tome r-tome commented Apr 2, 2026

🎟️ Tracking

https://bitwarden.atlassian.net/browse/PM-22450

📔 Objective

Collection.RevisionDate was 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 via UpdateCollectionCommand, user/group assignment changes, and bulk access operations -- in both stored procedures and EF repositories.

…d update corresponding tests. Adjust tests to verify correct RevisionDate assignment during collection updates.
@r-tome r-tome added needs-qa ai-review-vnext Request a Claude code review using the vNext workflow labels Apr 2, 2026
@r-tome r-tome marked this pull request as ready for review April 2, 2026 15:43
@r-tome r-tome requested a review from a team as a code owner April 2, 2026 15:43
@r-tome r-tome requested a review from eliykat April 2, 2026 15:43
@codecov
Copy link
Copy Markdown

codecov bot commented Apr 2, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 62.74%. Comparing base (0918bfd) to head (48d9e7c).
⚠️ Report is 9 commits behind head on main.

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.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 2, 2026

Logo
Checkmarx One – Scan Summary & Details3b101038-8d89-4f91-b75d-a602f321a6ef


New Issues (119) Checkmarx found the following issues in this Pull Request
# Severity Issue Source File / Package Checkmarx Insight
1 CRITICAL Stored_XSS /src/SharedWeb/Health/HealthCheckServiceExtensions.cs: 61
detailsThe method embeds untrusted data in generated output with WriteAsync, at line 60 of /src/SharedWeb/Health/HealthCheckServiceExtensions.cs. This ...
Attack Vector
2 CRITICAL Stored_XSS /util/Server/Startup.cs: 57
detailsThe method embeds untrusted data in generated output with WriteAsync, at line 59 of /util/Server/Startup.cs. This untrusted data is embedded int...
Attack Vector
3 MEDIUM CSRF /src/Api/Billing/Controllers/VNext/AccountBillingVNextController.cs: 55
detailsMethod at line 55 of /src/Api/Billing/Controllers/VNext/AccountBillingVNextController.cs gets a parameter from a user request from user. This pa...
Attack Vector
4 MEDIUM CSRF /src/Api/KeyManagement/Controllers/AccountsKeyManagementController.cs: 145
detailsMethod at line 145 of /src/Api/KeyManagement/Controllers/AccountsKeyManagementController.cs gets a parameter from a user request from request. T...
Attack Vector
5 MEDIUM CSRF /src/Api/KeyManagement/Controllers/AccountsKeyManagementController.cs: 145
detailsMethod at line 145 of /src/Api/KeyManagement/Controllers/AccountsKeyManagementController.cs gets a parameter from a user request from request. T...
Attack Vector
6 MEDIUM CSRF /src/Api/KeyManagement/Controllers/AccountsKeyManagementController.cs: 97
detailsMethod at line 97 of /src/Api/KeyManagement/Controllers/AccountsKeyManagementController.cs gets a parameter from a user request from model. This...
Attack Vector
7 MEDIUM CSRF /src/Api/KeyManagement/Controllers/AccountsKeyManagementController.cs: 97
detailsMethod at line 97 of /src/Api/KeyManagement/Controllers/AccountsKeyManagementController.cs gets a parameter from a user request from model. This...
Attack Vector
8 MEDIUM CSRF /src/Api/AdminConsole/Controllers/OrganizationUsersController.cs: 534
detailsMethod at line 534 of /src/Api/AdminConsole/Controllers/OrganizationUsersController.cs gets a parameter from a user request from model. This par...
Attack Vector
9 MEDIUM CSRF /src/Api/KeyManagement/Controllers/AccountsKeyManagementController.cs: 229
detailsMethod at line 229 of /src/Api/KeyManagement/Controllers/AccountsKeyManagementController.cs gets a parameter from a user request from model. Thi...
Attack Vector
10 MEDIUM CSRF /src/Api/Vault/Controllers/CiphersController.cs: 1558
detailsMethod at line 1558 of /src/Api/Vault/Controllers/CiphersController.cs gets a parameter from a user request from id. This parameter value flows ...
Attack Vector
11 MEDIUM CSRF /src/Api/Tools/Controllers/SendsController.cs: 73
detailsMethod at line 73 of /src/Api/Tools/Controllers/SendsController.cs gets a parameter from a user request from id. This parameter value flows thro...
Attack Vector
12 MEDIUM CSRF /src/Api/Billing/Controllers/VNext/AccountBillingVNextController.cs: 145
detailsMethod at line 145 of /src/Api/Billing/Controllers/VNext/AccountBillingVNextController.cs gets a parameter from a user request from user. This p...
Attack Vector
13 MEDIUM CSRF /src/Api/Auth/Controllers/AccountsController.cs: 217
detailsMethod at line 217 of /src/Api/Auth/Controllers/AccountsController.cs gets a parameter from a user request from model. This parameter value flow...
Attack Vector
14 MEDIUM CSRF /src/Api/Public/Controllers/CollectionsController.cs: 91
detailsMethod at line 91 of /src/Api/Public/Controllers/CollectionsController.cs gets a parameter from a user request from model. This parameter value ...
Attack Vector
15 MEDIUM CSRF /src/Api/Public/Controllers/CollectionsController.cs: 91
detailsMethod at line 91 of /src/Api/Public/Controllers/CollectionsController.cs gets a parameter from a user request from model. This parameter value ...
Attack Vector
16 MEDIUM CSRF /src/Api/Controllers/CollectionsController.cs: 176
detailsMethod at line 176 of /src/Api/Controllers/CollectionsController.cs gets a parameter from a user request from model. This parameter value flows ...
Attack Vector
17 MEDIUM CSRF /src/Api/Controllers/CollectionsController.cs: 176
detailsMethod at line 176 of /src/Api/Controllers/CollectionsController.cs gets a parameter from a user request from model. This parameter value flows ...
Attack Vector
18 MEDIUM CSRF /src/Api/Controllers/CollectionsController.cs: 176
detailsMethod at line 176 of /src/Api/Controllers/CollectionsController.cs gets a parameter from a user request from model. This parameter value flows ...
Attack Vector
19 MEDIUM CSRF /src/Api/Controllers/CollectionsController.cs: 176
detailsMethod at line 176 of /src/Api/Controllers/CollectionsController.cs gets a parameter from a user request from model. This parameter value flows ...
Attack Vector
20 MEDIUM CSRF /src/Api/KeyManagement/Controllers/AccountsKeyManagementController.cs: 173
detailsMethod at line 173 of /src/Api/KeyManagement/Controllers/AccountsKeyManagementController.cs gets a parameter from a user request from model. Thi...
Attack Vector
21 MEDIUM CSRF /src/Api/Auth/Controllers/AccountsController.cs: 452
detailsMethod at line 452 of /src/Api/Auth/Controllers/AccountsController.cs gets a parameter from a user request from model. This parameter value flow...
Attack Vector
22 MEDIUM CSRF /src/Api/Dirt/Controllers/OrganizationReportsController.cs: 189
detailsMethod at line 189 of /src/Api/Dirt/Controllers/OrganizationReportsController.cs gets a parameter from a user request from request. This paramet...
Attack Vector
23 MEDIUM CSRF /src/Api/Billing/Controllers/VNext/AccountBillingVNextController.cs: 104
detailsMethod at line 104 of /src/Api/Billing/Controllers/VNext/AccountBillingVNextController.cs gets a parameter from a user request from user. This p...
Attack Vector
24 MEDIUM CSRF /src/Api/Billing/Controllers/VNext/OrganizationBillingVNextController.cs: 107
detailsMethod at line 107 of /src/Api/Billing/Controllers/VNext/OrganizationBillingVNextController.cs gets a parameter from a user request from organiza...
Attack Vector
25 MEDIUM CSRF /src/Api/Vault/Controllers/CiphersController.cs: 1417
detailsMethod at line 1417 of /src/Api/Vault/Controllers/CiphersController.cs gets a parameter from a user request from id. This parameter value flows ...
Attack Vector
26 MEDIUM CSRF /src/Api/Dirt/Controllers/OrganizationReportsController.cs: 286
detailsMethod at line 286 of /src/Api/Dirt/Controllers/OrganizationReportsController.cs gets a parameter from a user request from request. This paramet...
Attack Vector
27 MEDIUM CSRF /src/Api/Dirt/Controllers/OrganizationReportsController.cs: 233
detailsMethod at line 233 of /src/Api/Dirt/Controllers/OrganizationReportsController.cs gets a parameter from a user request from request. This paramet...
Attack Vector
28 MEDIUM CSRF /src/Api/Dirt/Controllers/OrganizationReportsController.cs: 189
detailsMethod at line 189 of /src/Api/Dirt/Controllers/OrganizationReportsController.cs gets a parameter from a user request from request. This paramet...
Attack Vector
29 MEDIUM CSRF /src/Api/Vault/Controllers/CiphersController.cs: 1417
detailsMethod at line 1417 of /src/Api/Vault/Controllers/CiphersController.cs gets a parameter from a user request from id. This parameter value flows ...
Attack Vector
30 MEDIUM CSRF /src/Api/Vault/Controllers/CiphersController.cs: 1417
detailsMethod at line 1417 of /src/Api/Vault/Controllers/CiphersController.cs gets a parameter from a user request from id. This parameter value flows ...
Attack Vector
31 MEDIUM CSRF /src/Api/AdminConsole/Controllers/GroupsController.cs: 289
detailsMethod at line 289 of /src/Api/AdminConsole/Controllers/GroupsController.cs gets a parameter from a user request from orgUserId. This parameter ...
Attack Vector
32 MEDIUM CSRF /src/Api/Vault/Controllers/CiphersController.cs: 1385
detailsMethod at line 1385 of /src/Api/Vault/Controllers/CiphersController.cs gets a parameter from a user request from id. This parameter value flows ...
Attack Vector
33 MEDIUM CSRF /src/Api/Vault/Controllers/CiphersController.cs: 1446
detailsMethod at line 1446 of /src/Api/Vault/Controllers/CiphersController.cs gets a parameter from a user request from id. This parameter value flows ...
Attack Vector
34 MEDIUM CSRF /src/Api/Vault/Controllers/CiphersController.cs: 1148
detailsMethod at line 1148 of /src/Api/Vault/Controllers/CiphersController.cs gets a parameter from a user request from id. This parameter value flows ...
Attack Vector
35 MEDIUM CSRF /src/Api/Vault/Controllers/CiphersController.cs: 1032
detailsMethod at line 1032 of /src/Api/Vault/Controllers/CiphersController.cs gets a parameter from a user request from id. This parameter value flows ...
Attack Vector
36 MEDIUM CSRF /src/Api/Vault/Controllers/CiphersController.cs: 1281
detailsMethod at line 1281 of /src/Api/Vault/Controllers/CiphersController.cs gets a parameter from a user request from organizationId. This parameter ...
Attack Vector
37 MEDIUM CSRF /src/Api/AdminConsole/Controllers/OrganizationUsersController.cs: 394
detailsMethod at line 394 of /src/Api/AdminConsole/Controllers/OrganizationUsersController.cs gets a parameter from a user request from model. This par...
Attack Vector
38 MEDIUM CSRF /src/Api/AdminConsole/Controllers/OrganizationUsersController.cs: 385
detailsMethod at line 385 of /src/Api/AdminConsole/Controllers/OrganizationUsersController.cs gets a parameter from a user request from model. This par...
Attack Vector
39 MEDIUM CSRF /src/Api/AdminConsole/Controllers/OrganizationUsersController.cs: 385
detailsMethod at line 385 of /src/Api/AdminConsole/Controllers/OrganizationUsersController.cs gets a parameter from a user request from id. This parame...
Attack Vector
40 MEDIUM CSRF /src/Api/Billing/Controllers/VNext/OrganizationBillingVNextController.cs: 95
detailsMethod at line 95 of /src/Api/Billing/Controllers/VNext/OrganizationBillingVNextController.cs gets a parameter from a user request from organizat...
Attack Vector
41 MEDIUM CSRF /src/Api/Billing/Controllers/VNext/ProviderBillingVNextController.cs: 82
detailsMethod at line 82 of /src/Api/Billing/Controllers/VNext/ProviderBillingVNextController.cs gets a parameter from a user request from provider. Th...
Attack Vector
42 MEDIUM CSRF /src/Api/Billing/Controllers/VNext/AccountBillingVNextController.cs: 93
detailsMethod at line 93 of /src/Api/Billing/Controllers/VNext/AccountBillingVNextController.cs gets a parameter from a user request from user. This pa...
Attack Vector
43 MEDIUM CSRF /src/Api/Billing/Controllers/VNext/OrganizationBillingVNextController.cs: 49
detailsMethod at line 49 of /src/Api/Billing/Controllers/VNext/OrganizationBillingVNextController.cs gets a parameter from a user request from organizat...
Attack Vector
44 MEDIUM CSRF /src/Api/Billing/Controllers/VNext/ProviderBillingVNextController.cs: 40
detailsMethod at line 40 of /src/Api/Billing/Controllers/VNext/ProviderBillingVNextController.cs gets a parameter from a user request from provider. Th...
Attack Vector
45 MEDIUM CSRF /src/Api/Vault/Controllers/CiphersController.cs: 1226
detailsMethod at line 1226 of /src/Api/Vault/Controllers/CiphersController.cs gets a parameter from a user request from model. This parameter value flo...
Attack Vector
46 MEDIUM CSRF /src/Api/KeyManagement/Controllers/AccountsKeyManagementController.cs: 173
detailsMethod at line 173 of /src/Api/KeyManagement/Controllers/AccountsKeyManagementController.cs gets a parameter from a user request from model. Thi...
Attack Vector
47 MEDIUM CSRF /src/Api/Vault/Controllers/SecurityTaskController.cs: 66
detailsMethod at line 66 of /src/Api/Vault/Controllers/SecurityTaskController.cs gets a parameter from a user request from taskId. This parameter value...
Attack Vector
48 MEDIUM CSRF /src/Api/Auth/Controllers/AccountsController.cs: 721
detailsMethod at line 721 of /src/Api/Auth/Controllers/AccountsController.cs gets a parameter from a user request from request. This parameter value fl...
Attack Vector
49 MEDIUM CSRF /src/Api/Auth/Controllers/AccountsController.cs: 192
detailsMethod at line 192 of /src/Api/Auth/Controllers/AccountsController.cs gets a parameter from a user request from model. This parameter value flow...
Attack Vector
50 MEDIUM CSRF /src/Api/Auth/Controllers/AccountsController.cs: 641
detailsMethod at line 641 of /src/Api/Auth/Controllers/AccountsController.cs gets a parameter from a user request from model. This parameter value flow...
Attack Vector
51 MEDIUM CSRF /src/Api/Auth/Controllers/AccountsController.cs: 664
detailsMethod at line 664 of /src/Api/Auth/Controllers/AccountsController.cs gets a parameter from a user request from model. This parameter value flow...
Attack Vector
52 MEDIUM CSRF /src/Api/Auth/Controllers/EmergencyAccessController.cs: 173
detailsMethod at line 173 of /src/Api/Auth/Controllers/EmergencyAccessController.cs gets a parameter from a user request from model. This parameter val...
Attack Vector
53 MEDIUM CSRF /src/Api/Auth/Controllers/AccountsController.cs: 385
detailsMethod at line 385 of /src/Api/Auth/Controllers/AccountsController.cs gets a parameter from a user request from model. This parameter value flow...
Attack Vector
54 MEDIUM CSRF /src/Api/Auth/Controllers/AccountsController.cs: 412
detailsMethod at line 412 of /src/Api/Auth/Controllers/AccountsController.cs gets a parameter from a user request from model. This parameter value flow...
Attack Vector
55 MEDIUM CSRF /src/Api/Auth/Controllers/AccountsController.cs: 126
detailsMethod at line 126 of /src/Api/Auth/Controllers/AccountsController.cs gets a parameter from a user request from model. This parameter value flow...
Attack Vector
56 MEDIUM CSRF /src/Api/Vault/Controllers/CiphersController.cs: 825
detailsMethod at line 825 of /src/Api/Vault/Controllers/CiphersController.cs gets a parameter from a user request from model. This parameter value flow...
Attack Vector
57 MEDIUM CSRF /src/Api/Vault/Controllers/CiphersController.cs: 825
detailsMethod at line 825 of /src/Api/Vault/Controllers/CiphersController.cs gets a parameter from a user request from model. This parameter value flow...
Attack Vector
58 MEDIUM CSRF /src/Api/Vault/Controllers/CiphersController.cs: 825
detailsMethod at line 825 of /src/Api/Vault/Controllers/CiphersController.cs gets a parameter from a user request from id. This parameter value flows t...
Attack Vector
59 MEDIUM CSRF /src/Api/Vault/Controllers/CiphersController.cs: 825
detailsMethod at line 825 of /src/Api/Vault/Controllers/CiphersController.cs gets a parameter from a user request from id. This parameter value flows t...
Attack Vector
60 MEDIUM CSRF /src/Api/NotificationCenter/Controllers/NotificationsController.cs: 61
detailsMethod at line 61 of /src/Api/NotificationCenter/Controllers/NotificationsController.cs gets a parameter from a user request from id. This param...
Attack Vector
61 MEDIUM CSRF /src/Api/NotificationCenter/Controllers/NotificationsController.cs: 67
detailsMethod at line 67 of /src/Api/NotificationCenter/Controllers/NotificationsController.cs gets a parameter from a user request from id. This param...
Attack Vector
62 MEDIUM CSRF /src/Api/Vault/Controllers/CiphersController.cs: 1446
detailsMethod at line 1446 of /src/Api/Vault/Controllers/CiphersController.cs gets a parameter from a user request from id. This parameter value flows ...
Attack Vector
63 MEDIUM CSRF /src/Api/Vault/Controllers/CiphersController.cs: 763
detailsMethod at line 763 of /src/Api/Vault/Controllers/CiphersController.cs gets a parameter from a user request from id. This parameter value flows t...
Attack Vector
64 MEDIUM CSRF /src/Api/Vault/Controllers/CiphersController.cs: 790
detailsMethod at line 790 of /src/Api/Vault/Controllers/CiphersController.cs gets a parameter from a user request from id. This parameter value flows t...
Attack Vector
65 MEDIUM CSRF /src/Api/Vault/Controllers/CiphersController.cs: 763
detailsMethod at line 763 of /src/Api/Vault/Controllers/CiphersController.cs gets a parameter from a user request from model. This parameter value flow...
Attack Vector
66 MEDIUM CSRF /src/Api/Vault/Controllers/CiphersController.cs: 790
detailsMethod at line 790 of /src/Api/Vault/Controllers/CiphersController.cs gets a parameter from a user request from model. This parameter value flow...
Attack Vector
67 MEDIUM CSRF /src/Api/Vault/Controllers/CiphersController.cs: 790
detailsMethod at line 790 of /src/Api/Vault/Controllers/CiphersController.cs gets a parameter from a user request from id. This parameter value flows t...
Attack Vector
68 MEDIUM CSRF /src/Api/Vault/Controllers/CiphersController.cs: 790
detailsMethod at line 790 of /src/Api/Vault/Controllers/CiphersController.cs gets a parameter from a user request from model. This parameter value flow...
Attack Vector
69 MEDIUM CSRF /src/Api/Vault/Controllers/CiphersController.cs: 763
detailsMethod at line 763 of /src/Api/Vault/Controllers/CiphersController.cs gets a parameter from a user request from model. This parameter value flow...
Attack Vector
70 MEDIUM CSRF /src/Api/Vault/Controllers/CiphersController.cs: 763
detailsMethod at line 763 of /src/Api/Vault/Controllers/CiphersController.cs gets a parameter from a user request from id. This parameter value flows t...
Attack Vector
71 MEDIUM CSRF /src/Api/AdminConsole/Controllers/GroupsController.cs: 138
detailsMethod at line 138 of /src/Api/AdminConsole/Controllers/GroupsController.cs gets a parameter from a user request from model. This parameter valu...
Attack Vector
72 MEDIUM CSRF /src/Api/AdminConsole/Controllers/GroupsController.cs: 166
detailsMethod at line 166 of /src/Api/AdminConsole/Controllers/GroupsController.cs gets a parameter from a user request from model. This parameter valu...
Attack Vector
73 MEDIUM CSRF /src/Api/AdminConsole/Controllers/GroupsController.cs: 166
detailsMethod at line 166 of /src/Api/AdminConsole/Controllers/GroupsController.cs gets a parameter from a user request from model. This parameter valu...
Attack Vector
74 MEDIUM CSRF /src/Api/AdminConsole/Controllers/OrganizationUsersController.cs: 414
detailsMethod at line 414 of /src/Api/AdminConsole/Controllers/OrganizationUsersController.cs gets a parameter from a user request from model. This par...
Attack Vector
75 MEDIUM CSRF /src/Api/AdminConsole/Controllers/OrganizationUsersController.cs: 414
detailsMethod at line 414 of /src/Api/AdminConsole/Controllers/OrganizationUsersController.cs gets a parameter from a user request from model. This par...
Attack Vector
76 MEDIUM CSRF /src/Api/Auth/Controllers/AccountsController.cs: 558
detailsMethod at line 558 of /src/Api/Auth/Controllers/AccountsController.cs gets a parameter from a user request from model. This parameter value flow...
Attack Vector
77 MEDIUM CSRF /src/Api/Auth/Controllers/AccountsController.cs: 582
detailsMethod at line 582 of /src/Api/Auth/Controllers/AccountsController.cs gets a parameter from a user request from organizationId. This parameter v...
Attack Vector

More results are available on the CxOne platform

eliykat
eliykat previously approved these changes Apr 3, 2026
Copy link
Copy Markdown
Member

@eliykat eliykat left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ticket says we need to bump the revision date in these scenarios:

  1. Whenever a collection has its name updated (including when it’s nested)
  2. Whenever a collection has its user/group assignment updated
  3. Whenever a user has their access to a collection updated
  4. 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.)

r-tome added 6 commits April 3, 2026 15:31
…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.
@r-tome r-tome requested a review from a team as a code owner April 3, 2026 15:03
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 3, 2026

Bitwarden Claude Code Review

Overall Assessment: APPROVE

This PR fixes Collection.RevisionDate not updating when collection access is modified. The changes consistently apply revision date bumps across all six code paths: bulk collection access, organization user create/update (single and bulk), and group create/update. The implementation covers all three data layers (application commands with TimeProvider, EF repositories, Dapper repositories, and SQL stored procedures) with matching integration and unit tests. The @RevisionDate = NULL default parameter in Collection_CreateOrUpdateAccessForMany maintains backward compatibility.

Code Review Details

No findings.

@r-tome r-tome changed the title [PM-22450] Fix Collection.RevisionDate not updating when a collection is edited [PM-22450] Bump Collection.RevisionDate on edits and access changes Apr 3, 2026
@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud bot commented Apr 3, 2026

@r-tome
Copy link
Copy Markdown
Contributor Author

r-tome commented Apr 3, 2026

The ticket says we need to bump the revision date in these scenarios:

  1. Whenever a collection has its name updated (including when it’s nested)
  2. Whenever a collection has its user/group assignment updated
  3. Whenever a user has their access to a collection updated
  4. 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.)

Great callout! I went even further and also updated when user is invited with collection access.

@r-tome r-tome requested a review from eliykat April 3, 2026 19:39
Copy link
Copy Markdown
Member

@eliykat eliykat left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking good.

Comment on lines +21 to +26
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)
)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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()
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why no injected date here?

FROM [dbo].[Collection] C
WHERE C.[Id] IN (
SELECT OUC.[CollectionId]
FROM OPENJSON(@collectionData)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we want to avoid repeatedly parsing this json.

@@ -1,4 +1,4 @@
CREATE PROCEDURE [dbo].[OrganizationUser_UpdateWithCollections]
CREATE PROCEDURE [dbo].[OrganizationUser_UpdateWithCollections]
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment on lines +42 to +45
foreach (var c in availableCollections.Where(a => filteredCollections.Any(fc => fc.Id == a.Id)))
{
c.RevisionDate = grp.RevisionDate;
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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)))
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here for the available/filtered logic.

var affectedCollections = await dbContext.Collections
.Where(c => affectedCollectionIds.Contains(c.Id))
.ToListAsync();
var now = DateTime.UtcNow;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DateTime.UtcNow() usage

Comment on lines +972 to +973
var affectedCollections = await dbContext.Collections
.Where(c => affectedCollectionIds.Contains(c.Id))
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here re: OrgId filtering

Comment on lines +639 to +640
Assert.True(actualCollection.RevisionDate > originalRevisionDate);
Assert.Equal(revisionDate, actualCollection.RevisionDate, TimeSpan.FromSeconds(1));
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here, should be able to assert a precise revision date. (and throughout all other tests)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ai-review-vnext Request a Claude code review using the vNext workflow needs-qa

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants