-
Notifications
You must be signed in to change notification settings - Fork 1.6k
[PM-31929] Add deletion days restriction to Send Controls policy #7506
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
base: tools/pm-31884/send-access-controls-policy
Are you sure you want to change the base?
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 |
|---|---|---|
|
|
@@ -109,6 +109,10 @@ private async Task UpdateSendsByPolicyAsync(Policy postUpsertedPolicyState, Send | |
| { | ||
| await sendRepository.UpdateManyDisabledAsync(disabled, true); | ||
| } | ||
| if (sendControlsPolicyData.DeletionDays != null) | ||
| { | ||
| await sendRepository.UpdateManyDeletionDatesByIdsAsync(sendIdsChunk, sendControlsPolicyData.DeletionDays.GetValueOrDefault(0)); | ||
| } | ||
|
Comment on lines
+112
to
+115
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. Details and fixThe existing enable/disable branch above intentionally checks Suggested fix: if (postUpsertedPolicyState.Enabled && sendControlsPolicyData.DeletionDays != null)
{
await sendRepository.UpdateManyDeletionDatesByIdsAsync(
sendIdsChunk,
sendControlsPolicyData.DeletionDays.Value);
}Consider also whether only changes to |
||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| CREATE PROCEDURE [dbo].[Send_UpdateDeletionDatesByIds] | ||
| @Ids AS [dbo].[GuidIdArray] READONLY, | ||
| @DeletionHours INT | ||
| AS | ||
| BEGIN | ||
| SET NOCOUNT ON | ||
|
|
||
| -- Set field | ||
| UPDATE | ||
| [dbo].[Send] | ||
| SET | ||
| [DeletionDate] = DATEADD(HOUR, @DeletionHours, [CreationDate]), | ||
| [RevisionDate] = GETUTCDATE() | ||
| WHERE | ||
| [Id] IN (SELECT * FROM @Ids) | ||
|
Comment on lines
+9
to
+15
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. β QUESTION: Should user-set deletion dates that are earlier than DetailsThis proc unconditionally overwrites If UPDATE [dbo].[Send]
SET
[DeletionDate] = DATEADD(DAY, @DeletionDays, [CreationDate]),
[RevisionDate] = GETUTCDATE()
WHERE
[Id] IN (SELECT * FROM @Ids)
AND [DeletionDate] > DATEADD(DAY, @DeletionDays, [CreationDate])(mirror the same guard in the EF implementation). If it is instead intended to force all Sends to exactly |
||
|
|
||
| -- Bump account revision dates | ||
| EXEC [dbo].[User_BumpManyAccountRevisionDates] | ||
|
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. This does not work as expected and oddly, does not generate an error, despite being invalid SQL syntax. Instead you need to do something like this: -- Near the top of stored proc
DECLARE @UserIds [dbo].[GuidIdArray]
--rest of stored procedure
INSERT INTO @UserIds
SELECT DISTINCT
UserId
FROM
[dbo].[Send]
WHERE
[Id] IN (SELECT * FROM @Ids)
AND [UserId] IS NOT NULL
EXEC [dbo].[User_BumpManyAccountRevisionDates] @UserIds |
||
| ( | ||
| SELECT DISTINCT | ||
| UserId | ||
| FROM | ||
| [dbo].[Send] | ||
| WHERE | ||
| [Id] IN (SELECT * FROM @Ids) | ||
| ) | ||
| END | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| CREATE OR ALTER PROCEDURE [dbo].[Send_UpdateDeletionDatesByIds] | ||
| @Ids AS [dbo].[GuidIdArray] READONLY, | ||
| @DeletionHours INT | ||
| AS | ||
| BEGIN | ||
| SET NOCOUNT ON | ||
|
|
||
| -- Set field | ||
| UPDATE | ||
| [dbo].[Send] | ||
| SET | ||
| [DeletionDate] = DATEADD(HOUR, @DeletionHours, [CreationDate]), | ||
| [RevisionDate] = GETUTCDATE() | ||
| WHERE | ||
| [Id] IN (SELECT * FROM @Ids) | ||
|
|
||
| -- Bump account revision dates | ||
| EXEC [dbo].[User_BumpManyAccountRevisionDates] | ||
| ( | ||
| SELECT DISTINCT | ||
| UserId | ||
| FROM | ||
| [dbo].[Send] | ||
| WHERE | ||
| [Id] IN (SELECT * FROM @Ids) | ||
| ) | ||
| END |
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.
β CRITICAL: Units mismatch β
DeletionDaysis passed directly asdeletionHours.Details and fix
The policy field is
SendControlsPolicyData.DeletionDays(int?), but the repository method is declared asUpdateManyDeletionDatesByIdsAsync(IEnumerable<Guid> ids, int deletionHours)and the stored procedure / EF implementation both doDATEADD(HOUR, @DeletionHours, [CreationDate])/CreationDate.AddHours(deletionHours).Tracing the call chain: an admin who sets
DeletionDays = 7ends up with sends whoseDeletionDate = CreationDate + 7 hours, i.e., ~7 hours instead of 7 days. This is off by a factor of 24.The test case even asserts the broken behavior directly:
DeletionDays = 48is asserted to be passed as48to a method that interprets it as hours.Either convert at the call site:
Or rename the policy field/column to match the unit actually stored (e.g.,
DeletionHours), and update the DB column name, migration file (2026-04-20_01_SendUpdateDeletionDaysByIds.sql), SendControlsPolicyRequirement, and all callers / UI consumers accordingly.Recommended: change the SQL/EF implementations to use
DATEADD(DAY, @DeletionDays, ...)/.AddDays(...)and rename the parameter to@DeletionDays/deletionDays. That keeps the policy unit semantics consistent with the field name and with how admins will likely reason about Send retention.