fix(sms): repair S1 build breaks — null-filter EmailAddress projections + SiteNotificationRepository SMS stubs
S1 made NotificationRecipient.EmailAddress nullable + added SmsConfiguration and four INotificationRepository SMS methods, breaking compilation beyond the intentionally-deferred central NotificationRepository. Fix 1 (CS8620/CS8604 nullable EmailAddress projections, email-only paths): - NotificationOutbox EmailNotificationDeliveryAdapter: filter non-null emails - DeploymentManager ArtifactDeploymentService: filter non-null emails - Transport EntitySerializer: filter non-null emails into NotificationRecipientDto Fix 2 (CS0535): stub the four SMS-config methods on SiteRuntime SiteNotificationRepository (central-only — NotSupportedException, matching the existing 'Managed via artifact deployment from Central' write-path pattern). Doc nits: reword NotificationRecipient private ctor and SmsConfiguration.AuthToken comments. The central ConfigurationDatabase.NotificationRepository compile break is left as-is (S2 implements those four methods).
This commit is contained in:
@@ -71,8 +71,9 @@ public class NotificationRecipient
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parameterless constructor used by EF Core materialization and the SMS factory, where the
|
||||
/// contact field is assigned via property setters rather than constructor parameters.
|
||||
/// Private parameterless constructor that backs the <see cref="ForSms"/> factory path,
|
||||
/// where the contact field is assigned via property setters rather than constructor
|
||||
/// parameters — without exposing a half-initialized public constructor to callers.
|
||||
/// </summary>
|
||||
private NotificationRecipient()
|
||||
{
|
||||
|
||||
@@ -6,7 +6,10 @@ public class SmsConfiguration
|
||||
public int Id { get; set; }
|
||||
/// <summary>Gets or sets the Twilio Account SID.</summary>
|
||||
public string AccountSid { get; set; }
|
||||
/// <summary>Gets or sets the Twilio Auth Token (secret), or null when not applicable.</summary>
|
||||
/// <summary>
|
||||
/// Gets or sets the Twilio Auth Token (secret). Stored encrypted; null only transiently
|
||||
/// during configuration, never a valid production value.
|
||||
/// </summary>
|
||||
public string? AuthToken { get; set; }
|
||||
/// <summary>Gets or sets the sender phone number (E.164) placed in the From field.</summary>
|
||||
public string FromNumber { get; set; }
|
||||
|
||||
@@ -179,7 +179,7 @@ public class ArtifactDeploymentService
|
||||
|
||||
// Map notification lists
|
||||
var notificationListArtifacts = notificationLists.Select(nl =>
|
||||
new NotificationListArtifact(nl.Name, nl.Recipients.Select(r => r.EmailAddress).ToList())).ToList();
|
||||
new NotificationListArtifact(nl.Name, nl.Recipients.Where(r => r.EmailAddress is not null).Select(r => r.EmailAddress!).ToList())).ToList();
|
||||
|
||||
// Map SMTP configurations — use Host as the artifact name (matches SQLite PK on site)
|
||||
var smtpArtifacts = smtpConfigurations.Select(smtp =>
|
||||
|
||||
+4
-1
@@ -106,7 +106,10 @@ public sealed class EmailNotificationDeliveryAdapter : INotificationDeliveryAdap
|
||||
return DeliveryOutcome.Permanent(addressError);
|
||||
}
|
||||
|
||||
var recipientAddresses = recipients.Select(r => r.EmailAddress).ToList();
|
||||
var recipientAddresses = recipients
|
||||
.Where(r => r.EmailAddress is not null)
|
||||
.Select(r => r.EmailAddress!)
|
||||
.ToList();
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
@@ -193,6 +193,24 @@ public class SiteNotificationRepository : INotificationRepository
|
||||
public Task DeleteSmtpConfigurationAsync(int id, CancellationToken cancellationToken = default)
|
||||
=> throw new NotSupportedException("Managed via artifact deployment from Central");
|
||||
|
||||
// ── SmsConfiguration (central-only — never deployed to or served from the site) ──
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task<SmsConfiguration?> GetSmsConfigurationAsync(CancellationToken cancellationToken = default)
|
||||
=> throw new NotSupportedException("Managed via artifact deployment from Central");
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task<IReadOnlyList<SmsConfiguration>> GetAllSmsConfigurationsAsync(CancellationToken cancellationToken = default)
|
||||
=> throw new NotSupportedException("Managed via artifact deployment from Central");
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task AddSmsConfigurationAsync(SmsConfiguration smsConfiguration, CancellationToken cancellationToken = default)
|
||||
=> throw new NotSupportedException("Managed via artifact deployment from Central");
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task UpdateSmsConfigurationAsync(SmsConfiguration smsConfiguration, CancellationToken cancellationToken = default)
|
||||
=> throw new NotSupportedException("Managed via artifact deployment from Central");
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task<int> SaveChangesAsync(CancellationToken cancellationToken = default)
|
||||
=> throw new NotSupportedException("Managed via artifact deployment from Central");
|
||||
|
||||
@@ -138,9 +138,11 @@ public sealed class EntitySerializer
|
||||
NotificationLists: aggregate.NotificationLists.Select(nl => new NotificationListDto(
|
||||
Name: nl.Name,
|
||||
Type: nl.Type,
|
||||
Recipients: nl.Recipients.Select(r => new NotificationRecipientDto(
|
||||
Name: r.Name,
|
||||
EmailAddress: r.EmailAddress)).ToList())).ToList(),
|
||||
Recipients: nl.Recipients
|
||||
.Where(r => r.EmailAddress is not null)
|
||||
.Select(r => new NotificationRecipientDto(
|
||||
Name: r.Name,
|
||||
EmailAddress: r.EmailAddress!)).ToList())).ToList(),
|
||||
SmtpConfigs: aggregate.SmtpConfigurations.Select(smtp =>
|
||||
{
|
||||
SecretsBlock? secrets = null;
|
||||
|
||||
Reference in New Issue
Block a user