[PM-32477]PremiumStatusChanged Push Notification#7198
[PM-32477]PremiumStatusChanged Push Notification#7198cyprain-okeke wants to merge 8 commits intomainfrom
Conversation
|
New Issues (2)Checkmarx found the following issues in this Pull Request
|
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #7198 +/- ##
=======================================
Coverage 57.43% 57.43%
=======================================
Files 2032 2032
Lines 89377 89460 +83
Branches 7944 7948 +4
=======================================
+ Hits 51331 51382 +51
- Misses 36203 36234 +31
- Partials 1843 1844 +1 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
|
||
| await userService.EnablePremiumAsync(userId.Value, subscription.GetCurrentPeriodEnd()); | ||
| var user = await userRepository.GetByIdAsync(userId.Value); | ||
| await pushNotificationAdapter.NotifyPremiumStatusChangedAsync(user!); |
There was a problem hiding this comment.
❌ 2 things we should clean up here:
userService.EnablePremiumAsyncmakes no guarantees theUserexists. It just skips the operation if the user is null, which means line 120 could result in an NRE. Not only that, but if theUserthat comes back from the DB isnull, theEnablewould be followed by us sending the notification anyway, which is incorrect.- This will never be hit for users on the new price because of the missed Price adaptation on line 113 - we should fix that.
| ExcludeCurrentContext = false, | ||
| }); | ||
|
|
||
| Task PushPremiumStatusChangedAsync(Entities.User user) |
There was a problem hiding this comment.
❌ We're no longer adding methods like this to the shared IPushNotificationService. Please follow the established pattern in the the Billing application's PushNotificationAdapter so that we own the code.
| ExcludeCurrentContext = false, | ||
| }); | ||
|
|
||
| public Task NotifyPremiumStatusChangedAsync(User user) => |
There was a problem hiding this comment.
❌ Related to this comment, this should follow the pattern of the methods above.
| { | ||
| await _userService.DisablePremiumAsync(userId.Value, subscription.GetCurrentPeriodEnd()); | ||
| var user = await _userRepository.GetByIdAsync(userId.Value); | ||
| await _pushNotificationAdapter.NotifyPremiumStatusChangedAsync(user!); |
| { | ||
| await _userService.DisablePremiumAsync(userId.Value, currentPeriodEnd); | ||
| var user = await _userRepository.GetByIdAsync(userId.Value); | ||
| await _pushNotificationAdapter.NotifyPremiumStatusChangedAsync(user!); |
| { | ||
| await _userService.EnablePremiumAsync(userId.Value, currentPeriodEnd); | ||
| var user = await _userRepository.GetByIdAsync(userId.Value); | ||
| await _pushNotificationAdapter.NotifyPremiumStatusChangedAsync(user!); |
|
|
||
| await userService.SaveUserAsync(user); | ||
| await pushNotificationService.PushSyncVaultAsync(user.Id); | ||
| await pushNotificationService.PushPremiumStatusChangedAsync(user); |
There was a problem hiding this comment.
❓ Wouldn't this be redundant? I assume a full sync would re-pull Premium status, right?
|
|
||
| await userService.SaveUserAsync(user); | ||
| await pushNotificationService.PushSyncVaultAsync(user.Id); | ||
| await pushNotificationService.PushPremiumStatusChangedAsync(user); |
src/Core/Models/PushNotification.cs
Outdated
| { | ||
| public Guid UserId { get; set; } | ||
| public bool Premium { get; set; } | ||
| public DateTime? PremiumExpirationDate { get; set; } |
There was a problem hiding this comment.
❓ Is there a client-side use-case for including the expiration date?
| public Guid TargetOrganizationUserId { get; set; } | ||
| } | ||
|
|
||
| public class PremiumStatusPushNotification |
There was a problem hiding this comment.
❌ Please review the comments on lines 7 and 8 of this file regarding the location this file should live in.
djsmith85
left a comment
There was a problem hiding this comment.
It seems like after the comments from @amorask-bitwarden are addressed, a review from platform might not be necessary anymore. In case they do, please re-request a review.
|





🎟️ Tracking
https://bitwarden.atlassian.net/browse/PM-32477
📔 Objective
Summary
Implement premium-status push notifications across billing flows so clients stay in sync whenever a user’s premium state changes.
Details
New adapter API for premium changes
Stripe payment and subscription handlers
SubscriptionDeletedHandler
SubscriptionUpdatedHandler
Premium subscription commands
CreatePremiumCloudHostedSubscriptionCommand
CreatePremiumSelfHostedSubscriptionCommand
After writing the license and saving the user, call PushPremiumStatusChangedAsync(user) to broadcast the new premium status for self-hosted subscriptions.
UpgradePremiumToOrganizationCommand
Tests
Update billing service tests to:
Update premium command tests to:
📸 Screenshots