Add channel test providers for Email, Slack, Teams, and Webhook

- Implemented EmailChannelTestProvider to generate email preview payloads.
- Implemented SlackChannelTestProvider to create Slack message previews.
- Implemented TeamsChannelTestProvider for generating Teams Adaptive Card previews.
- Implemented WebhookChannelTestProvider to create webhook payloads.
- Added INotifyChannelTestProvider interface for channel-specific preview generation.
- Created ChannelTestPreviewContracts for request and response models.
- Developed NotifyChannelTestService to handle test send requests and generate previews.
- Added rate limit policies for test sends and delivery history.
- Implemented unit tests for service registration and binding.
- Updated project files to include necessary dependencies and configurations.
This commit is contained in:
master
2025-10-19 23:29:34 +03:00
parent a811f7ac47
commit a07f46231b
239 changed files with 17245 additions and 3155 deletions

View File

@@ -4,4 +4,10 @@
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\StellaOps.DependencyInjection\StellaOps.DependencyInjection.csproj" />
<ProjectReference Include="..\StellaOps.Notify.Engine\StellaOps.Notify.Engine.csproj" />
<ProjectReference Include="..\StellaOps.Notify.Models\StellaOps.Notify.Models.csproj" />
</ItemGroup>
</Project>

View File

@@ -3,5 +3,5 @@
| ID | Status | Owner(s) | Depends on | Description | Exit Criteria |
|----|--------|----------|------------|-------------|---------------|
| NOTIFY-CONN-WEBHOOK-15-801 | TODO | Notify Connectors Guild | NOTIFY-ENGINE-15-303 | Implement webhook connector: JSON payload, signature (HMAC/Ed25519), retries/backoff, status code handling. | Integration tests with webhook stub validate signatures, retries, error handling; payload schema documented. |
| NOTIFY-CONN-WEBHOOK-15-802 | TODO | Notify Connectors Guild | NOTIFY-CONN-WEBHOOK-15-801 | Health/test-send support with signature validation hints and secret management. | Test-send returns success with sample payload; docs include verification guide; secrets never logged. |
| NOTIFY-CONN-WEBHOOK-15-802 | DOING (2025-10-19) | Notify Connectors Guild | NOTIFY-CONN-WEBHOOK-15-801 | Health/test-send support with signature validation hints and secret management. | Test-send returns success with sample payload; docs include verification guide; secrets never logged. |
| NOTIFY-CONN-WEBHOOK-15-803 | TODO | Notify Connectors Guild | NOTIFY-CONN-WEBHOOK-15-802 | Package Webhook connector as restart-time plug-in (manifest + host registration). | Plugin manifest added; host loads connector from `plugins/notify/webhook/`; restart validation passes. |

View File

@@ -0,0 +1,58 @@
using System;
using System.Collections.Generic;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using StellaOps.DependencyInjection;
using StellaOps.Notify.Engine;
using StellaOps.Notify.Models;
namespace StellaOps.Notify.Connectors.Webhook;
[ServiceBinding(typeof(INotifyChannelTestProvider), ServiceLifetime.Singleton)]
public sealed class WebhookChannelTestProvider : INotifyChannelTestProvider
{
private static readonly JsonSerializerOptions JsonOptions = new(JsonSerializerDefaults.Web);
public NotifyChannelType ChannelType => NotifyChannelType.Webhook;
public Task<ChannelTestPreviewResult> BuildPreviewAsync(ChannelTestPreviewContext context, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
var title = context.Request.Title ?? "Stella Ops Notify Preview";
var summary = context.Request.Summary ?? $"Preview generated at {context.Timestamp:O}.";
var payload = new
{
title,
summary,
traceId = context.TraceId,
timestamp = context.Timestamp,
body = context.Request.Body,
metadata = context.Request.Metadata
};
var body = JsonSerializer.Serialize(payload, JsonOptions);
var preview = NotifyDeliveryRendered.Create(
NotifyChannelType.Webhook,
NotifyDeliveryFormat.Webhook,
context.Target,
title,
body,
summary,
context.Request.TextBody ?? summary,
context.Request.Locale,
ChannelTestPreviewUtilities.ComputeBodyHash(body),
context.Request.Attachments);
var metadata = new Dictionary<string, string>(StringComparer.Ordinal)
{
["webhook.endpoint"] = context.Target
};
return Task.FromResult(new ChannelTestPreviewResult(preview, metadata));
}
}