fix bug with deleting groups anonymizing campaigns and bad recipient count

Signed-off-by: Ronni Skansing <rskansing@gmail.com>
This commit is contained in:
Ronni Skansing
2026-06-11 22:34:41 +02:00
parent 884c2819ad
commit 6d025d2dc7
3 changed files with 12 additions and 56 deletions
+5 -2
View File
@@ -273,8 +273,11 @@ func (r *CampaignRecipient) GetByCampaignRecipientID(
return ToCampaignRecipient(&dbCampaignRecipient)
}
// GetUnsendRecipients gets all campaign recipients that are not sent
// and have been attempted or been cancelled
// GetUnsendRecipients gets campaign recipients that were never attempted and are
// not already cancelled (cancelled_at IS NULL AND last_attempt_at IS NULL). Used
// at campaign close to cancel only sends that never started; recipients that were
// attempted (sent, failed, or still in flight) are left untouched so their
// existing state is not overwritten.
// if limit is larger than 0 it will limit the number of results
// if campaignID is not nil, it will filter by that campaign
func (r *CampaignRecipient) GetUnsendRecipients(
+4 -51
View File
@@ -518,37 +518,14 @@ func (r *RecipientGroup) RemoveRecipients(
if existingGroup.IsDynamic.IsSpecified() && !existingGroup.IsDynamic.IsNull() && existingGroup.IsDynamic.MustGet() {
return validate.WrapErrorWithField(errors.New("cannot remove recipients from a dynamic group"), "group")
}
// anonymize recipients in any recipient-campaign data
// cancel any pending sends for these recipients in active campaigns; the
// recipients are kept and their campaign history is left intact
for _, recpID := range recipientIDs {
// if the recipient is in any active campaign, cancel the recipient sending
err = r.CampaignRecipientRepository.CancelInActiveCampaigns(ctx, recpID)
if err != nil {
r.Logger.Errorw("failed to cancel campaign recipient", "error", err)
return err
}
anonymizedID := uuid.New()
err = r.RecipientService.CampaignRecipientRepository.Anonymize(
ctx,
nil, // nil campaignID means anonymize across all campaigns
recpID,
&anonymizedID,
)
if err != nil {
r.Logger.Errorw(
"failed to remove recipient - failed to anonymized recipiet campaign data",
"error", err,
)
return err
}
err = r.CampaignRepository.AnonymizeCampaignEventsByRecipientID(
ctx,
recpID,
&anonymizedID,
)
if err != nil {
r.Logger.Errorw("failed to anonymize campaign event", "error", err)
return err
}
}
// remove recipient from group
err = r.RecipientGroupRepository.RemoveRecipients(
@@ -616,39 +593,15 @@ func (r *RecipientGroup) DeleteByID(
}
if len(recipients) > 0 {
// anonymize recipients in any recipient-campaign data
// cancel any pending sends for these recipients in active campaigns; the
// recipients are kept and their campaign history is left intact
for _, recipient := range recipients {
anonymizedID := uuid.New()
recpID := recipient.ID.MustGet()
// if the recipient is in any active campaign, cancel the recipient sending
err = r.CampaignRecipientRepository.CancelInActiveCampaigns(ctx, &recpID)
if err != nil {
r.Logger.Errorw("failed to cancel campaign recipient", "error", err)
return err
}
err = r.RecipientService.CampaignRecipientRepository.Anonymize(
ctx,
nil, // nil campaignID means anonymize across all campaigns
&recpID,
&anonymizedID,
)
if err != nil {
r.Logger.Errorw(
"failed to remove recipient - failed to anonymized recipiet campaign data",
"error", err,
)
return err
}
err = r.CampaignRepository.AnonymizeCampaignEventsByRecipientID(
ctx,
&recpID,
&anonymizedID,
)
if err != nil {
r.Logger.Errorw("failed to anonymize campaign event", "error", err)
return err
}
}
}
// remove group from campaign groups
@@ -506,10 +506,10 @@
<DeleteAlert
list={[
'All recipients in this group will become orphaned',
'Campaign data for recipients in this group will be anonymized',
'Recipients not in any other group will become orphaned',
'Active campaign sends for recipients in this group will be cancelled',
'This group will be removed from any campaigns it is assigned to'
'This group will be removed from any campaigns it is assigned to',
'Recipients are kept and their campaign history is left intact'
]}
name={deleteValues.name}
onClick={() => onClickDelete(deleteValues.id)}