feat(sms): CLI list --type/--phones + notification sms group + channel-aware recipients (S6)

This commit is contained in:
Joseph Doherty
2026-06-19 10:40:09 -04:00
parent cdfd0ffbd2
commit 73df322a66
7 changed files with 638 additions and 37 deletions
@@ -1686,9 +1686,9 @@ public class ManagementActor : ReceiveActor
{
var repo = sp.GetRequiredService<INotificationRepository>();
var list = new NotificationList(cmd.Name) { Type = cmd.Type };
foreach (var email in cmd.RecipientEmails)
foreach (var recipient in BuildRecipients(cmd.Type, cmd.RecipientEmails, cmd.RecipientPhones))
{
list.Recipients.Add(new NotificationRecipient(email, email));
list.Recipients.Add(recipient);
}
await repo.AddNotificationListAsync(list);
await repo.SaveChangesAsync();
@@ -1710,12 +1710,10 @@ public class ManagementActor : ReceiveActor
await repo.DeleteRecipientAsync(r.Id);
}
foreach (var email in cmd.RecipientEmails)
foreach (var recipient in BuildRecipients(cmd.Type, cmd.RecipientEmails, cmd.RecipientPhones))
{
await repo.AddRecipientAsync(new NotificationRecipient(email, email)
{
NotificationListId = cmd.NotificationListId
});
recipient.NotificationListId = cmd.NotificationListId;
await repo.AddRecipientAsync(recipient);
}
await repo.UpdateNotificationListAsync(list);
@@ -1733,6 +1731,33 @@ public class ManagementActor : ReceiveActor
return true;
}
/// <summary>
/// SMS Notifications (S6): build the recipient set for a notification list according
/// to its delivery channel. Email lists map each <paramref name="recipientEmails"/>
/// entry to an <see cref="NotificationRecipient.ForEmail"/> recipient; SMS lists map
/// each <paramref name="recipientPhones"/> entry to an <see cref="NotificationRecipient.ForSms"/>
/// recipient. The off-channel source list is ignored so an Email list never stores a
/// phone in EmailAddress (and vice versa).
/// </summary>
private static IEnumerable<NotificationRecipient> BuildRecipients(
NotificationType type, IReadOnlyList<string> recipientEmails, IReadOnlyList<string>? recipientPhones)
{
if (type == NotificationType.Sms)
{
foreach (var phone in recipientPhones ?? Array.Empty<string>())
{
yield return NotificationRecipient.ForSms(phone, phone);
}
}
else
{
foreach (var email in recipientEmails)
{
yield return NotificationRecipient.ForEmail(email, email);
}
}
}
/// <summary>
/// MgmtSvc-020: project an SmtpConfiguration to a credential-free shape so the
/// stored Credentials (SMTP password / OAuth2 client secret) never leaves this