diff --git a/test/Infrastructure.IntegrationTest/AdminConsole/Repositories/CollectionRepository/DefaultCollectionSemaphoreTests.cs b/test/Infrastructure.IntegrationTest/AdminConsole/Repositories/CollectionRepository/DefaultCollectionSemaphoreTests.cs
new file mode 100644
index 0000000000..38dd28b367
--- /dev/null
+++ b/test/Infrastructure.IntegrationTest/AdminConsole/Repositories/CollectionRepository/DefaultCollectionSemaphoreTests.cs
@@ -0,0 +1,78 @@
+using Bit.Core.AdminConsole.Entities;
+using Bit.Core.Billing.Enums;
+using Bit.Core.Entities;
+using Bit.Core.Enums;
+using Bit.Core.Repositories;
+using Bit.Infrastructure.EntityFramework.Repositories;
+using Microsoft.EntityFrameworkCore;
+using Xunit;
+
+namespace Bit.Infrastructure.IntegrationTest.AdminConsole.Repositories.CollectionRepository;
+
+///
+/// Tests for DefaultCollectionSemaphore table behavior including cascade deletions
+///
+public class DefaultCollectionSemaphoreTests
+{
+ [Theory, DatabaseData]
+ public async Task DeleteOrganizationUser_CascadeDeletesSemaphore(
+ IUserRepository userRepository,
+ IOrganizationRepository organizationRepository,
+ ICollectionRepository collectionRepository,
+ IOrganizationUserRepository organizationUserRepository)
+ {
+ // Arrange
+ var user = await userRepository.CreateTestUserAsync();
+ var organization = await organizationRepository.CreateTestOrganizationAsync();
+ var orgUser = await organizationUserRepository.CreateTestOrganizationUserAsync(organization, user);
+
+ await collectionRepository.UpsertDefaultCollectionsAsync(
+ organization.Id,
+ [orgUser.Id],
+ "My Items");
+
+ // Verify semaphore exists
+ var semaphoreBefore = await collectionRepository.GetDefaultCollectionSemaphoresAsync(organization.Id);
+ Assert.Single(semaphoreBefore, s => s == orgUser.Id);
+
+ // Act - Delete organization user
+ await organizationUserRepository.DeleteAsync(orgUser);
+
+ // Assert - Semaphore should be cascade deleted
+ var semaphoreAfter = await collectionRepository.GetDefaultCollectionSemaphoresAsync(organization.Id);
+ Assert.Empty(semaphoreAfter);
+ }
+
+ ///
+ /// Test that deleting an Organization cascades through OrganizationUser to DefaultCollectionSemaphore
+ /// Note: Cascade path is Organization -> OrganizationUser -> DefaultCollectionSemaphore (not direct)
+ ///
+ [Theory, DatabaseData]
+ public async Task DeleteOrganization_CascadeDeletesSemaphore_ThroughOrganizationUser(
+ IUserRepository userRepository,
+ IOrganizationRepository organizationRepository,
+ ICollectionRepository collectionRepository,
+ IOrganizationUserRepository organizationUserRepository)
+ {
+ // Arrange
+ var user = await userRepository.CreateTestUserAsync();
+ var organization = await organizationRepository.CreateTestOrganizationAsync();
+ var orgUser = await organizationUserRepository.CreateTestOrganizationUserAsync(organization, user);
+
+ await collectionRepository.UpsertDefaultCollectionsAsync(
+ organization.Id,
+ [orgUser.Id],
+ "My Items");
+
+ // Verify semaphore exists
+ var semaphoreBefore = await collectionRepository.GetDefaultCollectionSemaphoresAsync(organization.Id);
+ Assert.Single(semaphoreBefore, s => s == orgUser.Id);
+
+ // Act - Delete organization (which cascades to OrganizationUser, which cascades to semaphore)
+ await organizationRepository.DeleteAsync(organization);
+
+ // Assert - Semaphore should be cascade deleted via OrganizationUser
+ var semaphoreAfter = await collectionRepository.GetDefaultCollectionSemaphoresAsync(organization.Id);
+ Assert.Empty(semaphoreAfter);
+ }
+}