-
-
Notifications
You must be signed in to change notification settings - Fork 88
RG-T133 Fixes #484
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
RG-T133 Fixes #484
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -53,6 +53,9 @@ DELETE FROM [dbo].[LogAttachments] WHERE LogId IN (SELECT LogId FROM [dbo].[Logs | |
| DELETE FROM [dbo].[LogUnits] WHERE LogId IN (SELECT LogId FROM [dbo].[Logs] WHERE DepartmentId = @DepartmentId) | ||
| DELETE FROM [dbo].[LogUsers] WHERE LogId IN (SELECT LogId FROM [dbo].[Logs] WHERE DepartmentId = @DepartmentId) | ||
|
|
||
| -- PushUris has no DepartmentId column; delete by membership while DepartmentMembers rows still exist | ||
| DELETE FROM [dbo].[PushUris] WHERE UserId IN (SELECT UserId FROM [dbo].[DepartmentMembers] WHERE DepartmentId = @DepartmentId) | ||
|
Comment on lines
+56
to
+57
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Cross-department data loss in Repositories/Resgrid.Repositories.DataRepository/DeleteRepository.cs: the new department-level -- Only remove PushUris for users whose account is being fully removed with this department
DELETE FROM [dbo].[PushUris]
WHERE UserId IN (
SELECT dm.UserId
FROM [dbo].[DepartmentMembers] dm
WHERE dm.DepartmentId = @DepartmentId
AND (SELECT COUNT(*) FROM [dbo].[DepartmentMembers] dm2 WHERE dm2.UserId = dm.UserId) = 1
)Prompt for LLMTalk to Kody by mentioning @kody Was this suggestion helpful? React with 👍 or 👎 to help Kody learn from this interaction. |
||
|
|
||
|
Comment on lines
+56
to
+58
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win Preserve push registrations for users in other departments.
Delete Also applies to: 246-246 🤖 Prompt for AI AgentsSource: MCP tools |
||
| OPEN db_cursor | ||
| FETCH NEXT FROM db_cursor INTO @UserId | ||
|
|
||
|
|
@@ -183,8 +186,8 @@ DELETE FROM [dbo].[Pois] WHERE PoiTypeId IN (SELECT PoiTypeId FROM [dbo].[POITyp | |
| DELETE FROM [dbo].[POITypes] WHERE DepartmentId = @DepartmentId | ||
|
|
||
| -- Resource orders (ResourceOrders row deleted further down) | ||
| DELETE FROM [dbo].[ResourceOrderFillUnits] WHERE ResourceOrderFillId IN (SELECT ResourceOrderFillId FROM [dbo].[ResourceOrderFills] WHERE DepartmentId = @DepartmentId OR ResourceOrderId IN (SELECT ResourceOrderId FROM [dbo].[ResourceOrders] WHERE DepartmentId = @DepartmentId)) | ||
| DELETE FROM [dbo].[ResourceOrderFills] WHERE DepartmentId = @DepartmentId OR ResourceOrderId IN (SELECT ResourceOrderId FROM [dbo].[ResourceOrders] WHERE DepartmentId = @DepartmentId) | ||
| DELETE FROM [dbo].[ResourceOrderFillUnits] WHERE ResourceOrderFillId IN (SELECT ResourceOrderFillId FROM [dbo].[ResourceOrderFills] WHERE DepartmentId = @DepartmentId OR ResourceOrderItemId IN (SELECT ResourceOrderItemId FROM [dbo].[ResourceOrderItems] WHERE ResourceOrderId IN (SELECT ResourceOrderId FROM [dbo].[ResourceOrders] WHERE DepartmentId = @DepartmentId))) | ||
| DELETE FROM [dbo].[ResourceOrderFills] WHERE DepartmentId = @DepartmentId OR ResourceOrderItemId IN (SELECT ResourceOrderItemId FROM [dbo].[ResourceOrderItems] WHERE ResourceOrderId IN (SELECT ResourceOrderId FROM [dbo].[ResourceOrders] WHERE DepartmentId = @DepartmentId)) | ||
| DELETE FROM [dbo].[ResourceOrderItems] WHERE ResourceOrderId IN (SELECT ResourceOrderId FROM [dbo].[ResourceOrders] WHERE DepartmentId = @DepartmentId) | ||
| DELETE FROM [dbo].[ResourceOrderSettings] WHERE DepartmentId = @DepartmentId | ||
|
|
||
|
|
@@ -240,7 +243,6 @@ DELETE FROM [dbo].[UdfFields] WHERE UdfDefinitionId IN (SELECT UdfDefinitionId F | |
| DELETE FROM [dbo].[UserStates] WHERE DepartmentId = @DepartmentId | ||
| DELETE FROM [dbo].[PersonnelCertifications] WHERE DepartmentId = @DepartmentId | ||
| DELETE FROM [dbo].[PersonnelRoleUsers] WHERE DepartmentId = @DepartmentId | ||
| DELETE FROM [dbo].[PushUris] WHERE DepartmentId = @DepartmentId | ||
|
|
||
| DELETE FROM [dbo].[Invites] WHERE DepartmentId = @DepartmentId | ||
| DELETE FROM [dbo].[Payments] WHERE DepartmentId = @DepartmentId | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,116 @@ | ||
| using System; | ||
| using System.Threading.Tasks; | ||
| using FluentAssertions; | ||
| using Moq; | ||
| using NUnit.Framework; | ||
| using Resgrid.Model; | ||
| using Resgrid.Model.Providers; | ||
| using Resgrid.Model.Services; | ||
| using Resgrid.Services; | ||
|
|
||
| namespace Resgrid.Tests.Services | ||
| { | ||
| [TestFixture] | ||
| public class PushServiceUserRegistrationTests | ||
| { | ||
| private const string UserId = "user-1"; | ||
| private const int DepartmentId = 7; | ||
| private const string Code = "DEPT"; | ||
| private const string DeviceId = "device-token"; | ||
| private const string Email = "user@example.com"; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. PII exposure in Kody rule violation: Mask PII and secrets in logs private const string EmailHash = "user_example_com_hash";Prompt for LLMTalk to Kody by mentioning @kody Was this suggestion helpful? React with 👍 or 👎 to help Kody learn from this interaction. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. PII-like test data in Kody rule violation: Redact PII in logs and metrics by default private const string Email = "redacted@example.test";Prompt for LLMTalk to Kody by mentioning @kody Was this suggestion helpful? React with 👍 or 👎 to help Kody learn from this interaction. |
||
| private const string FirstName = "First"; | ||
| private const string LastName = "Last"; | ||
|
|
||
| private Mock<INovuProvider> _novuProvider; | ||
| private Mock<IUserProfileService> _userProfileService; | ||
| private PushService _pushService; | ||
|
|
||
| [SetUp] | ||
| public void SetUp() | ||
| { | ||
| _novuProvider = new Mock<INovuProvider>(); | ||
| _userProfileService = new Mock<IUserProfileService>(); | ||
| _userProfileService.Setup(x => x.GetProfileByUserIdAsync(UserId, It.IsAny<bool>())).ReturnsAsync(new UserProfile | ||
| { | ||
| UserId = UserId, | ||
| FirstName = FirstName, | ||
| LastName = LastName, | ||
| MembershipEmail = Email | ||
| }); | ||
|
|
||
| _pushService = new PushService( | ||
| Mock.Of<IPushLogsService>(), | ||
| Mock.Of<INotificationProvider>(), | ||
| _userProfileService.Object, | ||
| Mock.Of<IUnitNotificationProvider>(), | ||
| _novuProvider.Object, | ||
| Mock.Of<IDepartmentSettingsService>(), | ||
| Mock.Of<IUnitsService>()); | ||
| } | ||
|
|
||
| [Test] | ||
| public async Task Register_responder_should_create_subscriber_before_credential_write() | ||
| { | ||
| _novuProvider.Setup(x => x.UpdateUserSubscriberFcm(UserId, Code, DeviceId)).ReturnsAsync(true); | ||
|
|
||
| var result = await _pushService.Register(CreatePushUri(source: null)); | ||
|
|
||
| result.Should().BeTrue(); | ||
| _novuProvider.Verify(x => x.CreateUserSubscriber(UserId, Code, DepartmentId, Email, FirstName, LastName), Times.Once); | ||
| _novuProvider.Verify(x => x.CreateICUserSubscriber(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<int>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>()), Times.Never); | ||
| _novuProvider.Verify(x => x.UpdateUserSubscriberFcm(UserId, Code, DeviceId), Times.Once); | ||
| } | ||
|
|
||
| [Test] | ||
| public async Task Register_ic_should_create_ic_subscriber_before_credential_write() | ||
| { | ||
| _novuProvider.Setup(x => x.UpdateICUserSubscriberFcm(UserId, Code, DeviceId)).ReturnsAsync(true); | ||
|
|
||
| var result = await _pushService.Register(CreatePushUri(source: "IC")); | ||
|
|
||
| result.Should().BeTrue(); | ||
| _novuProvider.Verify(x => x.CreateICUserSubscriber(UserId, Code, DepartmentId, Email, FirstName, LastName), Times.Once); | ||
| _novuProvider.Verify(x => x.CreateUserSubscriber(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<int>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>()), Times.Never); | ||
| _novuProvider.Verify(x => x.UpdateICUserSubscriberFcm(UserId, Code, DeviceId), Times.Once); | ||
| } | ||
|
|
||
| [Test] | ||
| public async Task Register_should_still_write_credentials_when_subscriber_create_fails() | ||
| { | ||
| _novuProvider.Setup(x => x.CreateUserSubscriber(UserId, Code, DepartmentId, Email, FirstName, LastName)) | ||
| .ReturnsAsync(false); | ||
| _novuProvider.Setup(x => x.UpdateUserSubscriberFcm(UserId, Code, DeviceId)).ReturnsAsync(true); | ||
|
|
||
| var result = await _pushService.Register(CreatePushUri(source: null)); | ||
|
|
||
| result.Should().BeTrue(); | ||
| _novuProvider.Verify(x => x.UpdateUserSubscriberFcm(UserId, Code, DeviceId), Times.Once); | ||
| } | ||
|
|
||
| [Test] | ||
| public async Task Register_should_still_write_credentials_when_subscriber_create_throws() | ||
| { | ||
| _novuProvider.Setup(x => x.CreateUserSubscriber(UserId, Code, DepartmentId, Email, FirstName, LastName)) | ||
| .ThrowsAsync(new InvalidOperationException("Novu unavailable")); | ||
| _novuProvider.Setup(x => x.UpdateUserSubscriberFcm(UserId, Code, DeviceId)).ReturnsAsync(true); | ||
|
|
||
| var result = await _pushService.Register(CreatePushUri(source: null)); | ||
|
|
||
| result.Should().BeTrue(); | ||
| _novuProvider.Verify(x => x.UpdateUserSubscriberFcm(UserId, Code, DeviceId), Times.Once); | ||
| } | ||
|
|
||
| private static PushUri CreatePushUri(string source) | ||
| { | ||
| return new PushUri | ||
| { | ||
| UserId = UserId, | ||
| DepartmentId = DepartmentId, | ||
| PlatformType = (int)Platforms.Android, | ||
| PushLocation = Code, | ||
| DeviceId = DeviceId, | ||
| Source = source | ||
| }; | ||
| } | ||
| } | ||
| } | ||
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.
Insufficient error telemetry in
Core/Resgrid.Services/PushService.cs: the tolerated failure path incatch (Exception ex)loses the structured context needed to verify and diagnoseEnsureUserSubscriberfailures. Log the exception with fields for the operation name and relevant identifiers, includingUserId,DepartmentId, and app type.Kody rule violation: Include error context in structured logs
Prompt for LLM
Talk to Kody by mentioning @kody
Was this suggestion helpful? React with 👍 or 👎 to help Kody learn from this interaction.