Restructure solution layout by module
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
This commit is contained in:
4
src/Notify/__Libraries/StellaOps.Notify.Engine/AGENTS.md
Normal file
4
src/Notify/__Libraries/StellaOps.Notify.Engine/AGENTS.md
Normal file
@@ -0,0 +1,4 @@
|
||||
# StellaOps.Notify.Engine — Agent Charter
|
||||
|
||||
## Mission
|
||||
Deliver rule evaluation, digest, and rendering logic per `docs/ARCHITECTURE_NOTIFY.md`.
|
||||
@@ -0,0 +1,51 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using StellaOps.Notify.Models;
|
||||
|
||||
namespace StellaOps.Notify.Engine;
|
||||
|
||||
/// <summary>
|
||||
/// Contract implemented by channel plug-ins to provide health diagnostics.
|
||||
/// </summary>
|
||||
public interface INotifyChannelHealthProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// Channel type supported by the provider.
|
||||
/// </summary>
|
||||
NotifyChannelType ChannelType { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Executes a health check for the supplied channel.
|
||||
/// </summary>
|
||||
Task<ChannelHealthResult> CheckAsync(ChannelHealthContext context, CancellationToken cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Immutable context describing a channel health request.
|
||||
/// </summary>
|
||||
public sealed record ChannelHealthContext(
|
||||
string TenantId,
|
||||
NotifyChannel Channel,
|
||||
string Target,
|
||||
DateTimeOffset Timestamp,
|
||||
string TraceId);
|
||||
|
||||
/// <summary>
|
||||
/// Result returned by channel plug-ins when reporting health diagnostics.
|
||||
/// </summary>
|
||||
public sealed record ChannelHealthResult(
|
||||
ChannelHealthStatus Status,
|
||||
string? Message,
|
||||
IReadOnlyDictionary<string, string> Metadata);
|
||||
|
||||
/// <summary>
|
||||
/// Supported channel health states.
|
||||
/// </summary>
|
||||
public enum ChannelHealthStatus
|
||||
{
|
||||
Healthy,
|
||||
Degraded,
|
||||
Unhealthy
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using StellaOps.Notify.Models;
|
||||
|
||||
namespace StellaOps.Notify.Engine;
|
||||
|
||||
/// <summary>
|
||||
/// Contract implemented by Notify channel plug-ins to generate channel-specific test preview payloads.
|
||||
/// </summary>
|
||||
public interface INotifyChannelTestProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// Channel type supported by the provider.
|
||||
/// </summary>
|
||||
NotifyChannelType ChannelType { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Builds a channel-specific preview for a test-send request.
|
||||
/// </summary>
|
||||
Task<ChannelTestPreviewResult> BuildPreviewAsync(ChannelTestPreviewContext context, CancellationToken cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sanitised request payload passed to channel plug-ins when building a preview.
|
||||
/// </summary>
|
||||
public sealed record ChannelTestPreviewRequest(
|
||||
string? TargetOverride,
|
||||
string? TemplateId,
|
||||
string? Title,
|
||||
string? Summary,
|
||||
string? Body,
|
||||
string? TextBody,
|
||||
string? Locale,
|
||||
IReadOnlyDictionary<string, string> Metadata,
|
||||
IReadOnlyList<string> Attachments);
|
||||
|
||||
/// <summary>
|
||||
/// Immutable context describing the channel and request for a test preview.
|
||||
/// </summary>
|
||||
public sealed record ChannelTestPreviewContext(
|
||||
string TenantId,
|
||||
NotifyChannel Channel,
|
||||
string Target,
|
||||
ChannelTestPreviewRequest Request,
|
||||
DateTimeOffset Timestamp,
|
||||
string TraceId);
|
||||
|
||||
/// <summary>
|
||||
/// Result returned by channel plug-ins for test preview generation.
|
||||
/// </summary>
|
||||
public sealed record ChannelTestPreviewResult(
|
||||
NotifyDeliveryRendered Preview,
|
||||
IReadOnlyDictionary<string, string>? Metadata);
|
||||
|
||||
/// <summary>
|
||||
/// Exception thrown by plug-ins when preview input is invalid.
|
||||
/// </summary>
|
||||
public sealed class ChannelTestPreviewException : Exception
|
||||
{
|
||||
public ChannelTestPreviewException(string message)
|
||||
: base(message)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Shared helpers for channel preview generation.
|
||||
/// </summary>
|
||||
public static class ChannelTestPreviewUtilities
|
||||
{
|
||||
/// <summary>
|
||||
/// Computes a lowercase hex SHA-256 body hash for preview payloads.
|
||||
/// </summary>
|
||||
public static string ComputeBodyHash(string body)
|
||||
{
|
||||
var bytes = Encoding.UTF8.GetBytes(body);
|
||||
var hash = SHA256.HashData(bytes);
|
||||
return Convert.ToHexString(hash).ToLowerInvariant();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using StellaOps.Notify.Models;
|
||||
|
||||
namespace StellaOps.Notify.Engine;
|
||||
|
||||
/// <summary>
|
||||
/// Evaluates Notify rules against platform events.
|
||||
/// </summary>
|
||||
public interface INotifyRuleEvaluator
|
||||
{
|
||||
/// <summary>
|
||||
/// Evaluates a single rule against an event and returns the match outcome.
|
||||
/// </summary>
|
||||
NotifyRuleEvaluationOutcome Evaluate(
|
||||
NotifyRule rule,
|
||||
NotifyEvent @event,
|
||||
DateTimeOffset? evaluationTimestamp = null);
|
||||
|
||||
/// <summary>
|
||||
/// Evaluates a collection of rules against an event.
|
||||
/// </summary>
|
||||
ImmutableArray<NotifyRuleEvaluationOutcome> Evaluate(
|
||||
IEnumerable<NotifyRule> rules,
|
||||
NotifyEvent @event,
|
||||
DateTimeOffset? evaluationTimestamp = null);
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
using System;
|
||||
using System.Collections.Immutable;
|
||||
using StellaOps.Notify.Models;
|
||||
|
||||
namespace StellaOps.Notify.Engine;
|
||||
|
||||
/// <summary>
|
||||
/// Outcome produced when evaluating a notify rule against an event.
|
||||
/// </summary>
|
||||
public sealed record NotifyRuleEvaluationOutcome
|
||||
{
|
||||
private NotifyRuleEvaluationOutcome(
|
||||
NotifyRule rule,
|
||||
bool isMatch,
|
||||
ImmutableArray<NotifyRuleAction> actions,
|
||||
DateTimeOffset? matchedAt,
|
||||
string? reason)
|
||||
{
|
||||
Rule = rule ?? throw new ArgumentNullException(nameof(rule));
|
||||
IsMatch = isMatch;
|
||||
Actions = actions;
|
||||
MatchedAt = matchedAt;
|
||||
Reason = reason;
|
||||
}
|
||||
|
||||
public NotifyRule Rule { get; }
|
||||
|
||||
public bool IsMatch { get; }
|
||||
|
||||
public ImmutableArray<NotifyRuleAction> Actions { get; }
|
||||
|
||||
public DateTimeOffset? MatchedAt { get; }
|
||||
|
||||
public string? Reason { get; }
|
||||
|
||||
public static NotifyRuleEvaluationOutcome NotMatched(NotifyRule rule, string reason)
|
||||
=> new(rule, false, ImmutableArray<NotifyRuleAction>.Empty, null, reason);
|
||||
|
||||
public static NotifyRuleEvaluationOutcome Matched(
|
||||
NotifyRule rule,
|
||||
ImmutableArray<NotifyRuleAction> actions,
|
||||
DateTimeOffset matchedAt)
|
||||
=> new(rule, true, actions, matchedAt, null);
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\StellaOps.Notify.Models\StellaOps.Notify.Models.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
2
src/Notify/__Libraries/StellaOps.Notify.Engine/TASKS.md
Normal file
2
src/Notify/__Libraries/StellaOps.Notify.Engine/TASKS.md
Normal file
@@ -0,0 +1,2 @@
|
||||
# Notify Engine Task Board (Sprint 15)
|
||||
> Archived 2025-10-26 — runtime responsibilities moved to `src/Notifier/StellaOps.Notifier` (Sprints 38–40).
|
||||
Reference in New Issue
Block a user