feat(push): add service-owned firebase channels and delivery

Add push contracts, provider delivery and channel diagnostics. Link email channels to services and document migration and validation.

Ref: IT-1074
This commit is contained in:
2026-10-24 12:31:35 +03:00
parent b30dba93e8
commit 1631786ce2
105 changed files with 3838 additions and 147 deletions
@@ -12,7 +12,7 @@ public sealed class SendEmailDeliveryValidatorTests
string? error = SendEmailDeliveryValidator.GetValidationError(
CreateMessage(),
CreateContext(),
SendEmailConsumer.SupportedMessageType);
SupportedMessageType.SendEmailV1);
Assert.Null(error);
}
@@ -25,7 +25,7 @@ public sealed class SendEmailDeliveryValidatorTests
string? error = SendEmailDeliveryValidator.GetValidationError(
CreateMessage(),
context,
SendEmailConsumer.SupportedMessageType);
SupportedMessageType.SendEmailV1);
Assert.Equal("AMQP MessageId is required.", error);
}
@@ -41,18 +41,33 @@ public sealed class SendEmailDeliveryValidatorTests
string? error = SendEmailDeliveryValidator.GetValidationError(
CreateMessage(),
context,
SendEmailConsumer.SupportedMessageType);
SupportedMessageType.SendEmailV1);
Assert.Equal("Unsupported AMQP message type 'Notification.SendEmail.v2'.", error);
}
[Theory]
[InlineData("Notification.SendPush.v1")]
[InlineData("notification.sendemail.v1")]
[InlineData("SendEmailV1")]
[InlineData("0")]
[InlineData("")]
[InlineData(null)]
public void OtherOrMissingWireType_IsRejected(string? wireType)
{
string? error = SendEmailDeliveryValidator.GetValidationError(CreateMessage(),
CreateContext() with { MessageType = wireType }, SupportedMessageType.SendEmailV1);
Assert.Equal($"Unsupported AMQP message type '{wireType ?? "<missing>"}'.", error);
}
private static RabbitMqMessageContext CreateContext() => new()
{
QueueName = SendEmailConsumer.IncomingQueue,
Exchange = string.Empty,
RoutingKey = SendEmailConsumer.IncomingQueue,
MessageId = Guid.NewGuid().ToString("D"),
MessageType = SendEmailConsumer.SupportedMessageType,
MessageType = "Notification.SendEmail.v1",
CorrelationId = "correlation-id",
ContentType = "application/json"
};