stabilize tests

This commit is contained in:
master
2026-02-01 21:37:40 +02:00
parent 55744f6a39
commit 5d5e80b2e4
6435 changed files with 33984 additions and 13802 deletions

View File

@@ -15,5 +15,5 @@ Deliver and operate the Notify module across WebService, Worker, and storage lay
- Update sprint rows in `docs/implplan/SPRINT_*.md` with TODO → DOING → DONE/BLOCKED as work progresses; log blockers in **Decisions & Risks**.
- Offline/deterministic posture: stable ordering, UTC timestamps, idempotent migrations; use NuGet cache `.nuget/packages/`.
- Storage: keep schema/tests aligned to `notify` schema; when running tests locally ensure Docker/WSL integration for Testcontainers.
- Testing: prefer integration suites under `src/Notify/__Tests/StellaOps.Notify.Storage.Postgres.Tests`; add coverage for new repositories or state transitions; keep results under `out/test-results/` when capturing evidence.
- Testing: prefer integration suites under `src/Notify/__Tests/StellaOps.Notify.Persistence.Tests`; add coverage for new repositories or state transitions; keep results under `out/test-results/` when capturing evidence.
- Cross-module edits require explicit sprint note; otherwise stay within `src/Notify/**` and shared libraries listed in module docs.

View File

@@ -1,6 +1,7 @@
using StellaOps.Notify.Engine;
using System;
using System.Collections.Generic;
using StellaOps.Notify.Engine;
namespace StellaOps.Notify.WebService.Contracts;

View File

@@ -1,6 +1,7 @@
using StellaOps.Notify.Models;
using System;
using System.Collections.Generic;
using StellaOps.Notify.Models;
namespace StellaOps.Notify.WebService.Contracts;

View File

@@ -1,7 +1,8 @@
using Microsoft.Extensions.Configuration;
using System.IO;
using System.Text;
using System.Text.Json;
using Microsoft.Extensions.Configuration;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.NamingConventions;

View File

@@ -1,7 +1,8 @@
using System;
using System.IO;
using StellaOps.Notify.WebService.Options;
using StellaOps.Plugin.Hosting;
using System;
using System.IO;
namespace StellaOps.Notify.WebService.Hosting;

View File

@@ -1,7 +1,8 @@
using System;
using System.Threading;
using Microsoft.Extensions.Logging;
using StellaOps.Plugin.Hosting;
using System;
using System.Threading;
namespace StellaOps.Notify.WebService.Plugins;

View File

@@ -1,45 +1,46 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Globalization;
using System.Security.Claims;
using System.Text;
using System.Text.Json;
using System.Text.Json.Nodes;
using System.Threading;
using System.Threading.RateLimiting;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.RateLimiting;
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Microsoft.Extensions.Primitives;
using Microsoft.IdentityModel.Tokens;
using Serilog;
using Serilog.Events;
using StellaOps.Auth.ServerIntegration;
using StellaOps.Configuration;
using System.Collections.Immutable;
using StellaOps.Notify.Models;
using StellaOps.Notify.Persistence.Extensions;
using StellaOps.Notify.Persistence.Postgres;
using StellaOps.Notify.Persistence.Postgres.Models;
using StellaOps.Notify.Persistence.Postgres.Repositories;
using StellaOps.Notify.WebService.Contracts;
using StellaOps.Notify.WebService.Diagnostics;
using StellaOps.Notify.WebService.Extensions;
using StellaOps.Notify.WebService.Hosting;
using StellaOps.Notify.WebService.Internal;
using StellaOps.Notify.WebService.Options;
using StellaOps.Notify.WebService.Plugins;
using StellaOps.Notify.WebService.Security;
using StellaOps.Notify.WebService.Services;
using StellaOps.Notify.WebService.Internal;
using StellaOps.Plugin.DependencyInjection;
using StellaOps.Notify.WebService.Contracts;
using StellaOps.Router.AspNet;
using System;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Text.Json;
using System.Text.Json.Nodes;
using System.Threading;
using System.Threading.RateLimiting;
var builder = WebApplication.CreateBuilder(args);
@@ -250,8 +251,6 @@ static void ConfigureAuthentication(WebApplicationBuilder builder, NotifyWebServ
static void ConfigureRateLimiting(WebApplicationBuilder builder, NotifyWebServiceOptions options)
{
ArgumentNullException.ThrowIfNull(options);
var tenantHeader = options.Api.TenantHeader;
var limits = options.Api.RateLimits;
builder.Services.AddRateLimiter(rateLimiterOptions =>
{
@@ -262,19 +261,22 @@ static void ConfigureRateLimiting(WebApplicationBuilder builder, NotifyWebServic
return ValueTask.CompletedTask;
};
ConfigurePolicy(rateLimiterOptions, NotifyRateLimitPolicies.DeliveryHistory, limits.DeliveryHistory, tenantHeader, "deliveries");
ConfigurePolicy(rateLimiterOptions, NotifyRateLimitPolicies.TestSend, limits.TestSend, tenantHeader, "channel-test");
ConfigurePolicy(rateLimiterOptions, NotifyRateLimitPolicies.DeliveryHistory, o => o.Api.RateLimits.DeliveryHistory, "deliveries");
ConfigurePolicy(rateLimiterOptions, NotifyRateLimitPolicies.TestSend, o => o.Api.RateLimits.TestSend, "channel-test");
});
static void ConfigurePolicy(
RateLimiterOptions rateLimiterOptions,
string policyName,
NotifyWebServiceOptions.RateLimitPolicyOptions policy,
string tenantHeader,
Func<NotifyWebServiceOptions, NotifyWebServiceOptions.RateLimitPolicyOptions> policySelector,
string prefix)
{
rateLimiterOptions.AddPolicy(policyName, httpContext =>
{
var opts = httpContext.RequestServices.GetRequiredService<IOptions<NotifyWebServiceOptions>>().Value;
var policy = policySelector(opts);
var tenantHeader = opts.Api.TenantHeader;
if (policy is null || !policy.Enabled)
{
return RateLimitPartition.GetNoLimiter("notify-disabled");
@@ -439,7 +441,16 @@ static void ConfigureEndpoints(WebApplication app)
return Results.BadRequest(new { error = "Request body is required." });
}
var ruleModel = service.UpgradeRule(body);
NotifyRule ruleModel;
try
{
ruleModel = service.UpgradeRule(body);
}
catch (Exception ex) when (ex is JsonException or InvalidOperationException or KeyNotFoundException or ArgumentException or FormatException)
{
return Results.BadRequest(new { error = $"Invalid rule payload: {ex.Message}" });
}
if (!string.Equals(ruleModel.TenantId, tenant, StringComparison.Ordinal))
{
return Results.BadRequest(new { error = "Tenant mismatch between header and payload." });
@@ -477,8 +488,8 @@ static void ConfigureEndpoints(WebApplication app)
return Results.BadRequest(new { error = "ruleId must be a GUID." });
}
await repository.DeleteAsync(tenant, ruleGuid, cancellationToken).ConfigureAwait(false);
return Results.NoContent();
var deleted = await repository.DeleteAsync(tenant, ruleGuid, cancellationToken).ConfigureAwait(false);
return deleted ? Results.NoContent() : Results.NotFound();
})
.RequireAuthorization(NotifyPolicies.Operator);
@@ -523,7 +534,16 @@ static void ConfigureEndpoints(WebApplication app)
return Results.BadRequest(new { error = "Request body is required." });
}
var channelModel = service.UpgradeChannel(body);
NotifyChannel channelModel;
try
{
channelModel = service.UpgradeChannel(body);
}
catch (Exception ex) when (ex is System.Text.Json.JsonException or InvalidOperationException or KeyNotFoundException or ArgumentException or FormatException or NotSupportedException)
{
return Results.BadRequest(new { error = $"Invalid channel payload: {ex.Message}" });
}
if (!string.Equals(channelModel.TenantId, tenant, StringComparison.Ordinal))
{
return Results.BadRequest(new { error = "Tenant mismatch between header and payload." });
@@ -549,6 +569,55 @@ static void ConfigureEndpoints(WebApplication app)
})
.RequireAuthorization(NotifyPolicies.Operator);
apiGroup.MapPost("/channels/{channelId}/test", async (
string channelId,
ChannelTestSendRequest? request,
IChannelRepository repository,
INotifyChannelTestService testService,
HttpContext context,
CancellationToken cancellationToken) =>
{
if (!TryResolveTenant(context, tenantHeader, out var tenant, out var error))
{
return error!;
}
if (request is null)
{
return Results.BadRequest(new { error = "Request body is required." });
}
if (!TryParseGuid(channelId, out var channelGuid))
{
return Results.BadRequest(new { error = "channelId must be a GUID." });
}
var channelEntity = await repository.GetByIdAsync(tenant, channelGuid, cancellationToken)
.ConfigureAwait(false);
if (channelEntity is null)
{
return Results.NotFound();
}
var channel = ToNotifyChannel(channelEntity);
try
{
var response = await testService.SendAsync(
tenant,
channel,
request,
context.TraceIdentifier,
cancellationToken).ConfigureAwait(false);
return Results.Accepted(value: response);
}
catch (ChannelTestSendValidationException ex)
{
return Results.BadRequest(new { error = ex.Message });
}
})
.RequireAuthorization(NotifyPolicies.Operator)
.RequireRateLimiting(NotifyRateLimitPolicies.TestSend);
apiGroup.MapDelete("/channels/{channelId}", async (string channelId, IChannelRepository repository, HttpContext context, CancellationToken cancellationToken) =>
{
if (!TryResolveTenant(context, tenantHeader, out var tenant, out var error))

View File

@@ -1,9 +1,10 @@
using System;
using System.Security.Claims;
using System.Text.Encodings.Web;
using Microsoft.AspNetCore.Authentication;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System;
using System.Security.Claims;
using System.Text.Encodings.Web;
namespace StellaOps.Notify.WebService.Security;

View File

@@ -1,11 +1,12 @@
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using StellaOps.Notify.Engine;
using StellaOps.Notify.Models;
using StellaOps.Notify.WebService.Contracts;
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace StellaOps.Notify.WebService.Services;

View File

@@ -1,10 +1,11 @@
using System;
using System.Collections.Generic;
using System.Threading;
using Microsoft.Extensions.Logging;
using StellaOps.Notify.Engine;
using StellaOps.Notify.Models;
using StellaOps.Notify.WebService.Contracts;
using System;
using System.Collections.Generic;
using System.Threading;
namespace StellaOps.Notify.WebService.Services;

View File

@@ -1,6 +1,7 @@
using StellaOps.Notify.Models;
using System;
using System.Text.Json.Nodes;
using StellaOps.Notify.Models;
namespace StellaOps.Notify.WebService.Services;

View File

@@ -8,3 +8,4 @@ Source of truth: `docs-archived/implplan/2025-12-29-csproj-audit/SPRINT_20251229
| AUDIT-0416-M | DONE | Revalidated 2026-01-07; maintainability audit for StellaOps.Notify.WebService. |
| AUDIT-0416-T | DONE | Revalidated 2026-01-07; test coverage audit for StellaOps.Notify.WebService. |
| AUDIT-0416-A | TODO | Revalidated 2026-01-07 (open findings). |
| REMED-06 | DONE | SOLID review notes captured for SPRINT_20260130_002. |

View File

@@ -1,6 +1,7 @@
using StellaOps.Notify.Queue;
using System.Threading;
using System.Threading.Tasks;
using StellaOps.Notify.Queue;
namespace StellaOps.Notify.Worker.Handlers;

View File

@@ -1,7 +1,8 @@
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using StellaOps.Notify.Queue;
using System.Threading;
using System.Threading.Tasks;
namespace StellaOps.Notify.Worker.Handlers;

View File

@@ -1,12 +1,13 @@
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using StellaOps.Notify.Queue;
using StellaOps.Notify.Worker.Handlers;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using StellaOps.Notify.Queue;
using StellaOps.Notify.Worker.Handlers;
namespace StellaOps.Notify.Worker.Processing;

View File

@@ -1,9 +1,10 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System;
using System.Threading;
using System.Threading.Tasks;
namespace StellaOps.Notify.Worker.Processing;

View File

@@ -8,3 +8,4 @@ Source of truth: `docs-archived/implplan/2025-12-29-csproj-audit/SPRINT_20251229
| AUDIT-0418-M | DONE | Revalidated 2026-01-07; maintainability audit for StellaOps.Notify.Worker. |
| AUDIT-0418-T | DONE | Revalidated 2026-01-07; test coverage audit for StellaOps.Notify.Worker. |
| AUDIT-0418-A | TODO | Revalidated 2026-01-07 (open findings). |
| REMED-06 | DONE | SOLID review notes captured for SPRINT_20260130_002. |

View File

@@ -1,11 +1,12 @@
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using StellaOps.DependencyInjection;
using StellaOps.Notify.Engine;
using StellaOps.Notify.Models;
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace StellaOps.Notify.Connectors.Email;

View File

@@ -1,11 +1,12 @@
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using StellaOps.DependencyInjection;
using StellaOps.Notify.Engine;
using StellaOps.Notify.Models;
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace StellaOps.Notify.Connectors.Email;

View File

@@ -1,8 +1,9 @@
using System;
using System.Collections.Generic;
using StellaOps.Notify.Connectors.Shared;
using StellaOps.Notify.Engine;
using StellaOps.Notify.Models;
using System;
using System.Collections.Generic;
namespace StellaOps.Notify.Connectors.Email;

View File

@@ -1,5 +1,6 @@
using System.Runtime.CompilerServices;
using StellaOps.Plugin.Versioning;
using System.Runtime.CompilerServices;
[assembly: InternalsVisibleTo("StellaOps.Notify.Connectors.Email.Tests")]
[assembly: StellaPluginVersion("1.0.0", MinimumHostVersion = "1.0.0", MaximumHostVersion = "1.99.99")]

View File

@@ -8,3 +8,4 @@ Source of truth: `docs-archived/implplan/2025-12-29-csproj-audit/SPRINT_20251229
| AUDIT-0397-M | DONE | Revalidated 2026-01-07; maintainability audit for StellaOps.Notify.Connectors.Email. |
| AUDIT-0397-T | DONE | Revalidated 2026-01-07; test coverage audit for StellaOps.Notify.Connectors.Email. |
| AUDIT-0397-A | TODO | Revalidated 2026-01-07 (open findings). |
| REMED-06 | DONE | SOLID review notes captured for SPRINT_20260130_002. |

View File

@@ -1,5 +1,6 @@
using System.Runtime.CompilerServices;
using StellaOps.Plugin.Versioning;
using System.Runtime.CompilerServices;
[assembly: InternalsVisibleTo("StellaOps.Notify.Connectors.Shared.Tests")]
[assembly: StellaPluginVersion("1.0.0", MinimumHostVersion = "1.0.0", MaximumHostVersion = "1.99.99")]

View File

@@ -8,3 +8,4 @@ Source of truth: `docs-archived/implplan/2025-12-29-csproj-audit/SPRINT_20251229
| AUDIT-0399-M | DONE | Revalidated 2026-01-07; maintainability audit for StellaOps.Notify.Connectors.Shared. |
| AUDIT-0399-T | DONE | Revalidated 2026-01-07; test coverage audit for StellaOps.Notify.Connectors.Shared. |
| AUDIT-0399-A | TODO | Revalidated 2026-01-07 (open findings). |
| REMED-06 | DONE | SOLID review notes captured for SPRINT_20260130_002. |

View File

@@ -1,5 +1,6 @@
using System.Runtime.CompilerServices;
using StellaOps.Plugin.Versioning;
using System.Runtime.CompilerServices;
[assembly: InternalsVisibleTo("StellaOps.Notify.Connectors.Slack.Tests")]
[assembly: StellaPluginVersion("1.0.0", MinimumHostVersion = "1.0.0", MaximumHostVersion = "1.99.99")]

View File

@@ -1,11 +1,12 @@
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using StellaOps.DependencyInjection;
using StellaOps.Notify.Engine;
using StellaOps.Notify.Models;
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace StellaOps.Notify.Connectors.Slack;

View File

@@ -1,12 +1,13 @@
using Microsoft.Extensions.DependencyInjection;
using StellaOps.DependencyInjection;
using StellaOps.Notify.Engine;
using StellaOps.Notify.Models;
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.Slack;

View File

@@ -1,8 +1,9 @@
using System;
using System.Collections.Generic;
using StellaOps.Notify.Connectors.Shared;
using StellaOps.Notify.Engine;
using StellaOps.Notify.Models;
using System;
using System.Collections.Generic;
namespace StellaOps.Notify.Connectors.Slack;

View File

@@ -8,3 +8,4 @@ Source of truth: `docs-archived/implplan/2025-12-29-csproj-audit/SPRINT_20251229
| AUDIT-0400-M | DONE | Revalidated 2026-01-07; maintainability audit for StellaOps.Notify.Connectors.Slack. |
| AUDIT-0400-T | DONE | Revalidated 2026-01-07; test coverage audit for StellaOps.Notify.Connectors.Slack. |
| AUDIT-0400-A | TODO | Revalidated 2026-01-07 (open findings). |
| REMED-06 | DONE | SOLID review notes captured for SPRINT_20260130_002. |

View File

@@ -1,5 +1,6 @@
using System.Runtime.CompilerServices;
using StellaOps.Plugin.Versioning;
using System.Runtime.CompilerServices;
[assembly: InternalsVisibleTo("StellaOps.Notify.Connectors.Teams.Tests")]
[assembly: StellaPluginVersion("1.0.0", MinimumHostVersion = "1.0.0", MaximumHostVersion = "1.99.99")]

View File

@@ -8,3 +8,4 @@ Source of truth: `docs-archived/implplan/2025-12-29-csproj-audit/SPRINT_20251229
| AUDIT-0402-M | DONE | Revalidated 2026-01-07; maintainability audit for StellaOps.Notify.Connectors.Teams. |
| AUDIT-0402-T | DONE | Revalidated 2026-01-07; test coverage audit for StellaOps.Notify.Connectors.Teams. |
| AUDIT-0402-A | TODO | Revalidated 2026-01-07 (open findings). |
| REMED-06 | DONE | SOLID review notes captured for SPRINT_20260130_002. |

View File

@@ -1,11 +1,12 @@
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using StellaOps.DependencyInjection;
using StellaOps.Notify.Engine;
using StellaOps.Notify.Models;
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace StellaOps.Notify.Connectors.Teams;

View File

@@ -1,11 +1,12 @@
using System;
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;
using System;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
namespace StellaOps.Notify.Connectors.Teams;

View File

@@ -1,8 +1,9 @@
using System;
using System.Collections.Generic;
using StellaOps.Notify.Connectors.Shared;
using StellaOps.Notify.Engine;
using StellaOps.Notify.Models;
using System;
using System.Collections.Generic;
namespace StellaOps.Notify.Connectors.Teams;

View File

@@ -1,5 +1,6 @@
using System.Runtime.CompilerServices;
using StellaOps.Plugin.Versioning;
using System.Runtime.CompilerServices;
[assembly: InternalsVisibleTo("StellaOps.Notify.Connectors.Webhook.Tests")]
[assembly: StellaPluginVersion("1.0.0", MinimumHostVersion = "1.0.0", MaximumHostVersion = "1.99.99")]

View File

@@ -8,3 +8,4 @@ Source of truth: `docs-archived/implplan/2025-12-29-csproj-audit/SPRINT_20251229
| AUDIT-0404-M | DONE | Revalidated 2026-01-07; maintainability audit for StellaOps.Notify.Connectors.Webhook. |
| AUDIT-0404-T | DONE | Revalidated 2026-01-07; test coverage audit for StellaOps.Notify.Connectors.Webhook. |
| AUDIT-0404-A | TODO | Revalidated 2026-01-07 (open findings). |
| REMED-06 | DONE | SOLID review notes captured for SPRINT_20260130_002. |

View File

@@ -1,11 +1,12 @@
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using StellaOps.DependencyInjection;
using StellaOps.Notify.Engine;
using StellaOps.Notify.Models;
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace StellaOps.Notify.Connectors.Webhook;

View File

@@ -1,12 +1,13 @@
using Microsoft.Extensions.DependencyInjection;
using StellaOps.DependencyInjection;
using StellaOps.Notify.Engine;
using StellaOps.Notify.Models;
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;

View File

@@ -1,7 +1,8 @@
using System.Collections.Generic;
using StellaOps.Notify.Connectors.Shared;
using StellaOps.Notify.Engine;
using StellaOps.Notify.Models;
using System.Collections.Generic;
namespace StellaOps.Notify.Connectors.Webhook;

View File

@@ -1,8 +1,9 @@
using StellaOps.Notify.Models;
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using StellaOps.Notify.Models;
namespace StellaOps.Notify.Engine;

View File

@@ -1,10 +1,11 @@
using StellaOps.Notify.Models;
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;

View File

@@ -1,7 +1,8 @@
using StellaOps.Notify.Models;
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using StellaOps.Notify.Models;
namespace StellaOps.Notify.Engine;

View File

@@ -1,6 +1,7 @@
using StellaOps.Notify.Models;
using System;
using System.Collections.Immutable;
using StellaOps.Notify.Models;
namespace StellaOps.Notify.Engine;

View File

@@ -8,3 +8,4 @@ Source of truth: `docs-archived/implplan/2025-12-29-csproj-audit/SPRINT_20251229
| AUDIT-0407-M | DONE | Revalidated 2026-01-07; maintainability audit for StellaOps.Notify.Engine. |
| AUDIT-0407-T | DONE | Revalidated 2026-01-07; test coverage audit for StellaOps.Notify.Engine. |
| AUDIT-0407-A | TODO | Revalidated 2026-01-07 (open findings). |
| REMED-06 | DONE | SOLID review notes captured for SPRINT_20260130_002. |

View File

@@ -5,8 +5,9 @@
// Description: Default templates for risk budget warning and exceeded alerts
// -----------------------------------------------------------------------------
using System.Collections.Immutable;
using StellaOps.Notify.Models;
using System.Collections.Immutable;
namespace StellaOps.Notify.Engine.Templates;

View File

@@ -6,8 +6,9 @@
// Description: Default templates for secret finding alert notifications
// -----------------------------------------------------------------------------
using System.Collections.Immutable;
using StellaOps.Notify.Models;
using System.Collections.Immutable;
namespace StellaOps.Notify.Engine.Templates;

View File

@@ -1,9 +1,10 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json.Nodes;
using System.Text.Encodings.Web;
using System.Text.Json;
using System.Text.Json.Nodes;
using System.Text.Json.Serialization;
using System.Text.Json.Serialization.Metadata;

View File

@@ -8,3 +8,4 @@ Source of truth: `docs-archived/implplan/2025-12-29-csproj-audit/SPRINT_20251229
| AUDIT-0409-M | DONE | Revalidated 2026-01-07; maintainability audit for StellaOps.Notify.Models. |
| AUDIT-0409-T | DONE | Revalidated 2026-01-07; test coverage audit for StellaOps.Notify.Models. |
| AUDIT-0409-A | TODO | Revalidated 2026-01-07 (open findings). |
| REMED-06 | DONE | SOLID review notes captured for SPRINT_20260130_002. |

View File

@@ -1,5 +1,6 @@
using System.Collections.Concurrent;
using StellaOps.Notify.Persistence.InMemory.Documents;
using System.Collections.Concurrent;
namespace StellaOps.Notify.Persistence.InMemory.Repositories;

View File

@@ -1,8 +1,9 @@
using System.Text;
using Microsoft.Extensions.Logging;
using Npgsql;
using StellaOps.Infrastructure.Postgres.Repositories;
using StellaOps.Notify.Persistence.Postgres.Models;
using System.Text;
namespace StellaOps.Notify.Persistence.Postgres.Repositories;

View File

@@ -8,3 +8,4 @@ Source of truth: `docs-archived/implplan/2025-12-29-csproj-audit/SPRINT_20251229
| AUDIT-0411-M | DONE | Revalidated 2026-01-07; maintainability audit for StellaOps.Notify.Persistence. |
| AUDIT-0411-T | DONE | Revalidated 2026-01-07; test coverage audit for StellaOps.Notify.Persistence. |
| AUDIT-0411-A | TODO | Revalidated 2026-01-07 (open findings). |
| REMED-06 | DONE | SOLID review notes captured for SPRINT_20260130_002. |

View File

@@ -1,8 +1,9 @@
using NATS.Client.JetStream;
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using NATS.Client.JetStream;
namespace StellaOps.Notify.Queue.Nats;

View File

@@ -1,3 +1,9 @@
using Microsoft.Extensions.Logging;
using NATS.Client.Core;
using NATS.Client.JetStream;
using NATS.Client.JetStream.Models;
using StellaOps.Notify.Models;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
@@ -7,11 +13,6 @@ using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using NATS.Client.Core;
using NATS.Client.JetStream;
using NATS.Client.JetStream.Models;
using StellaOps.Notify.Models;
namespace StellaOps.Notify.Queue.Nats;

View File

@@ -1,8 +1,9 @@
using NATS.Client.JetStream;
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using NATS.Client.JetStream;
namespace StellaOps.Notify.Queue.Nats;

View File

@@ -1,3 +1,9 @@
using Microsoft.Extensions.Logging;
using NATS.Client.Core;
using NATS.Client.JetStream;
using NATS.Client.JetStream.Models;
using StellaOps.Notify.Models;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
@@ -7,11 +13,6 @@ using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using NATS.Client.Core;
using NATS.Client.JetStream;
using NATS.Client.JetStream.Models;
using StellaOps.Notify.Models;
namespace StellaOps.Notify.Queue.Nats;

View File

@@ -1,10 +1,11 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Diagnostics.HealthChecks;
using Microsoft.Extensions.Logging;
using StellaOps.Notify.Queue.Nats;
using StellaOps.Notify.Queue.Redis;
using System;
using System.Threading;
using System.Threading.Tasks;
namespace StellaOps.Notify.Queue;

View File

@@ -1,9 +1,10 @@
using StellaOps.Notify.Models;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Threading;
using System.Threading.Tasks;
using StellaOps.Notify.Models;
namespace StellaOps.Notify.Queue;

View File

@@ -1,10 +1,11 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Diagnostics.HealthChecks;
using Microsoft.Extensions.Logging;
using StellaOps.Notify.Queue.Nats;
using StellaOps.Notify.Queue.Redis;
using System;
using System.Threading;
using System.Threading.Tasks;
namespace StellaOps.Notify.Queue;

View File

@@ -1,4 +1,4 @@
using System;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
@@ -6,6 +6,7 @@ using Microsoft.Extensions.Diagnostics.HealthChecks;
using Microsoft.Extensions.Logging;
using StellaOps.Notify.Queue.Nats;
using StellaOps.Notify.Queue.Redis;
using System;
namespace StellaOps.Notify.Queue;

View File

@@ -1,3 +1,7 @@
using Microsoft.Extensions.Logging;
using StackExchange.Redis;
using StellaOps.Notify.Models;
using System;
using System.Buffers;
using System.Collections.Concurrent;
@@ -7,9 +11,6 @@ using System.Globalization;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using StackExchange.Redis;
using StellaOps.Notify.Models;
namespace StellaOps.Notify.Queue.Redis;

View File

@@ -1,3 +1,7 @@
using Microsoft.Extensions.Logging;
using StackExchange.Redis;
using StellaOps.Notify.Models;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
@@ -6,9 +10,6 @@ using System.Globalization;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using StackExchange.Redis;
using StellaOps.Notify.Models;
namespace StellaOps.Notify.Queue.Redis;

View File

@@ -8,3 +8,4 @@ Source of truth: `docs-archived/implplan/2025-12-29-csproj-audit/SPRINT_20251229
| AUDIT-0413-M | DONE | Revalidated 2026-01-07; maintainability audit for StellaOps.Notify.Queue. |
| AUDIT-0413-T | DONE | Revalidated 2026-01-07; test coverage audit for StellaOps.Notify.Queue. |
| AUDIT-0413-A | TODO | Revalidated 2026-01-07 (open findings). |
| REMED-06 | DONE | SOLID review notes captured for SPRINT_20260130_002. |

View File

@@ -1,5 +1,6 @@
using System.Collections.Concurrent;
using StellaOps.Notify.Storage.InMemory.Documents;
using System.Collections.Concurrent;
namespace StellaOps.Notify.Storage.InMemory.Repositories;

View File

@@ -1,7 +1,8 @@
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using StellaOps.Notify.Storage.InMemory.Repositories;
using StellaOps.Notify.Persistence;
using StellaOps.Notify.Storage.InMemory.Repositories;
namespace StellaOps.Notify.Storage.InMemory;

View File

@@ -8,3 +8,4 @@ Source of truth: `docs-archived/implplan/2025-12-29-csproj-audit/SPRINT_20251229
| AUDIT-0415-M | DONE | Revalidated 2026-01-07; maintainability audit for StellaOps.Notify.Storage.InMemory. |
| AUDIT-0415-T | DONE | Revalidated 2026-01-07; test coverage audit for StellaOps.Notify.Storage.InMemory. |
| AUDIT-0415-A | TODO | Revalidated 2026-01-07 (open findings). |
| REMED-06 | DONE | SOLID review notes captured for SPRINT_20260130_002. |

View File

@@ -8,3 +8,4 @@ Source of truth: `docs-archived/implplan/2025-12-29-csproj-audit/SPRINT_20251229
| AUDIT-0398-M | DONE | Revalidated 2026-01-07; maintainability audit for StellaOps.Notify.Connectors.Email.Tests. |
| AUDIT-0398-T | DONE | Revalidated 2026-01-07; test coverage audit for StellaOps.Notify.Connectors.Email.Tests. |
| AUDIT-0398-A | DONE | Waived (test project; revalidated 2026-01-07). |
| REMED-06 | DONE | SOLID review notes captured for SPRINT_20260130_002. |

View File

@@ -0,0 +1,8 @@
# StellaOps.Notify.Connectors.Shared.Tests Task Board
This board mirrors active sprint tasks for this module.
Source of truth: `docs/implplan/SPRINT_20260130_002_Tools_csproj_remediation_solid_review.md`.
| Task ID | Status | Notes |
| --- | --- | --- |
| REMED-05 | TODO | Remediation checklist: docs/implplan/audits/csproj-standards/remediation/checklists/src/Notify/__Tests/StellaOps.Notify.Connectors.Shared.Tests/StellaOps.Notify.Connectors.Shared.Tests.md. |
| REMED-06 | DONE | SOLID review notes captured for SPRINT_20260130_002. |

View File

@@ -8,3 +8,4 @@ Source of truth: `docs-archived/implplan/2025-12-29-csproj-audit/SPRINT_20251229
| AUDIT-0401-M | DONE | Revalidated 2026-01-07; maintainability audit for StellaOps.Notify.Connectors.Slack.Tests. |
| AUDIT-0401-T | DONE | Revalidated 2026-01-07; test coverage audit for StellaOps.Notify.Connectors.Slack.Tests. |
| AUDIT-0401-A | DONE | Waived (test project; revalidated 2026-01-07). |
| REMED-06 | DONE | SOLID review notes captured for SPRINT_20260130_002. |

View File

@@ -8,3 +8,4 @@ Source of truth: `docs-archived/implplan/2025-12-29-csproj-audit/SPRINT_20251229
| AUDIT-0403-M | DONE | Revalidated 2026-01-07; maintainability audit for StellaOps.Notify.Connectors.Teams.Tests. |
| AUDIT-0403-T | DONE | Revalidated 2026-01-07; test coverage audit for StellaOps.Notify.Connectors.Teams.Tests. |
| AUDIT-0403-A | DONE | Waived (test project; revalidated 2026-01-07). |
| REMED-06 | DONE | SOLID review notes captured for SPRINT_20260130_002. |

View File

@@ -8,3 +8,4 @@ Source of truth: `docs-archived/implplan/2025-12-29-csproj-audit/SPRINT_20251229
| AUDIT-0405-M | DONE | Revalidated 2026-01-07; maintainability audit for StellaOps.Notify.Connectors.Webhook.Tests. |
| AUDIT-0405-T | DONE | Revalidated 2026-01-07; test coverage audit for StellaOps.Notify.Connectors.Webhook.Tests. |
| AUDIT-0405-A | DONE | Waived (test project; revalidated 2026-01-07). |
| REMED-06 | DONE | SOLID review notes captured for SPRINT_20260130_002. |

View File

@@ -8,3 +8,4 @@ Source of truth: `docs-archived/implplan/2025-12-29-csproj-audit/SPRINT_20251229
| AUDIT-0406-M | DONE | Revalidated 2026-01-07; maintainability audit for StellaOps.Notify.Core.Tests. |
| AUDIT-0406-T | DONE | Revalidated 2026-01-07; test coverage audit for StellaOps.Notify.Core.Tests. |
| AUDIT-0406-A | DONE | Waived (test project; revalidated 2026-01-07). |
| REMED-06 | DONE | SOLID review notes captured for SPRINT_20260130_002. |

View File

@@ -8,3 +8,4 @@ Source of truth: `docs-archived/implplan/2025-12-29-csproj-audit/SPRINT_20251229
| AUDIT-0408-M | DONE | Revalidated 2026-01-07; maintainability audit for StellaOps.Notify.Engine.Tests. |
| AUDIT-0408-T | DONE | Revalidated 2026-01-07; test coverage audit for StellaOps.Notify.Engine.Tests. |
| AUDIT-0408-A | DONE | Waived (test project; revalidated 2026-01-07). |
| REMED-06 | DONE | SOLID review notes captured for SPRINT_20260130_002. |

View File

@@ -8,3 +8,4 @@ Source of truth: `docs-archived/implplan/2025-12-29-csproj-audit/SPRINT_20251229
| AUDIT-0410-M | DONE | Revalidated 2026-01-07; maintainability audit for StellaOps.Notify.Models.Tests. |
| AUDIT-0410-T | DONE | Revalidated 2026-01-07; test coverage audit for StellaOps.Notify.Models.Tests. |
| AUDIT-0410-A | DONE | Waived (test project; revalidated 2026-01-07). |
| REMED-06 | DONE | SOLID review notes captured for SPRINT_20260130_002. |

View File

@@ -8,3 +8,4 @@ Source of truth: `docs-archived/implplan/2025-12-29-csproj-audit/SPRINT_20251229
| AUDIT-0412-M | DONE | Revalidated 2026-01-07; maintainability audit for StellaOps.Notify.Persistence.Tests. |
| AUDIT-0412-T | DONE | Revalidated 2026-01-07; test coverage audit for StellaOps.Notify.Persistence.Tests. |
| AUDIT-0412-A | DONE | Waived (test project; revalidated 2026-01-07). |
| REMED-06 | DONE | SOLID review notes captured for SPRINT_20260130_002. |

View File

@@ -8,3 +8,4 @@ Source of truth: `docs-archived/implplan/2025-12-29-csproj-audit/SPRINT_20251229
| AUDIT-0414-M | DONE | Revalidated 2026-01-07; maintainability audit for StellaOps.Notify.Queue.Tests. |
| AUDIT-0414-T | DONE | Revalidated 2026-01-07; test coverage audit for StellaOps.Notify.Queue.Tests. |
| AUDIT-0414-A | DONE | Waived (test project; revalidated 2026-01-07). |
| REMED-06 | DONE | SOLID review notes captured for SPRINT_20260130_002. |

View File

@@ -0,0 +1,8 @@
# StellaOps.Notify.Storage.InMemory.Tests Task Board
This board mirrors active sprint tasks for this module.
Source of truth: `docs/implplan/SPRINT_20260130_002_Tools_csproj_remediation_solid_review.md`.
| Task ID | Status | Notes |
| --- | --- | --- |
| REMED-05 | TODO | Remediation checklist: docs/implplan/audits/csproj-standards/remediation/checklists/src/Notify/__Tests/StellaOps.Notify.Storage.InMemory.Tests/StellaOps.Notify.Storage.InMemory.Tests.md. |
| REMED-06 | DONE | SOLID review notes captured for SPRINT_20260130_002. |

View File

@@ -203,7 +203,7 @@ public sealed class CrudEndpointsTests : IClassFixture<WebApplicationFactory<Pro
}
[Trait("Category", TestCategories.Unit)]
[Fact(Skip = "Channel test-send endpoint not yet implemented")]
[Fact]
public async Task ChannelTestSendReturnsPreview()
{
var client = _factory.CreateClient();
@@ -250,7 +250,7 @@ public sealed class CrudEndpointsTests : IClassFixture<WebApplicationFactory<Pro
}
[Trait("Category", TestCategories.Unit)]
[Fact(Skip = "Channel test-send endpoint not yet implemented")]
[Fact]
public async Task ChannelTestSendHonoursRateLimit()
{
using var limitedFactory = _factory.WithWebHostBuilder(builder =>
@@ -295,7 +295,7 @@ public sealed class CrudEndpointsTests : IClassFixture<WebApplicationFactory<Pro
}
[Trait("Category", TestCategories.Unit)]
[Fact(Skip = "Channel test-send endpoint not yet implemented")]
[Fact]
public async Task ChannelTestSendUsesRegisteredProvider()
{
var providerName = typeof(FakeSlackTestProvider).FullName!;

View File

@@ -8,3 +8,4 @@ Source of truth: `docs-archived/implplan/2025-12-29-csproj-audit/SPRINT_20251229
| AUDIT-0417-M | DONE | Revalidated 2026-01-07; maintainability audit for StellaOps.Notify.WebService.Tests. |
| AUDIT-0417-T | DONE | Revalidated 2026-01-07; test coverage audit for StellaOps.Notify.WebService.Tests. |
| AUDIT-0417-A | DONE | Waived (test project; revalidated 2026-01-07). |
| REMED-06 | DONE | SOLID review notes captured for SPRINT_20260130_002. |

View File

@@ -301,7 +301,7 @@ public class NotifyWebServiceAuthTests : IClassFixture<WebApplicationFactory<Pro
// Act - internal normalize endpoint
var response = await client.PostAsync(
"/api/v1/notify/_internal/rules/normalize",
"/internal/notify/rules/normalize",
new StringContent(payload.ToJsonString(), Encoding.UTF8, "application/json"),
CancellationToken.None);
@@ -365,7 +365,7 @@ public class NotifyWebServiceAuthTests : IClassFixture<WebApplicationFactory<Pro
var rule2Id = Guid.NewGuid().ToString();
await client2.PostAsync(
"/api/v1/notify/rules",
new StringContent(CreateRulePayload(rule2Id).ToJsonString(), Encoding.UTF8, "application/json"));
new StringContent(CreateRulePayload(rule2Id, OtherTenantId).ToJsonString(), Encoding.UTF8, "application/json"));
// Act - tenant 1 lists rules
var response1 = await client1.GetAsync("/api/v1/notify/rules", CancellationToken.None);
@@ -535,13 +535,13 @@ public class NotifyWebServiceAuthTests : IClassFixture<WebApplicationFactory<Pro
tenantId: tenantId, expires: expiresAt, notBefore: notBefore);
}
private static JsonObject CreateRulePayload(string ruleId)
private static JsonObject CreateRulePayload(string ruleId, string? tenantId = null)
{
return new JsonObject
{
["schemaVersion"] = "notify.rule@1",
["ruleId"] = ruleId,
["tenantId"] = TestTenantId,
["tenantId"] = tenantId ?? TestTenantId,
["name"] = $"Test Rule {ruleId}",
["description"] = "Auth test rule",
["enabled"] = true,

View File

@@ -348,7 +348,7 @@ public class NotifyWebServiceContractTests : IClassFixture<WebApplicationFactory
// Act
var response = await client.PostAsync(
"/api/v1/notify/_internal/rules/normalize",
"/internal/notify/rules/normalize",
new StringContent(payload.ToJsonString(), Encoding.UTF8, "application/json"),
CancellationToken.None);
@@ -418,7 +418,7 @@ public class NotifyWebServiceContractTests : IClassFixture<WebApplicationFactory
json?["channelId"].Should().NotBeNull();
json?["tenantId"].Should().NotBeNull();
json?["channelType"].Should().NotBeNull();
json?["type"].Should().NotBeNull();
json?["name"].Should().NotBeNull();
}
@@ -479,6 +479,7 @@ public class NotifyWebServiceContractTests : IClassFixture<WebApplicationFactory
["enabled"] = true,
["config"] = new JsonObject
{
["secretRef"] = "vault://notify/channels/test",
["target"] = "test@example.com"
}
};

View File

@@ -486,6 +486,7 @@ public class NotifyWebServiceOTelTests : IClassFixture<WebApplicationFactory<Pro
["enabled"] = true,
["config"] = new JsonObject
{
["secretRef"] = "vault://notify/channels/test",
["target"] = "test@example.com"
}
};

View File

@@ -8,3 +8,4 @@ Source of truth: `docs-archived/implplan/2025-12-29-csproj-audit/SPRINT_20251229
| AUDIT-0419-M | DONE | Revalidated 2026-01-07; maintainability audit for StellaOps.Notify.Worker.Tests. |
| AUDIT-0419-T | DONE | Revalidated 2026-01-07; test coverage audit for StellaOps.Notify.Worker.Tests. |
| AUDIT-0419-A | DONE | Waived (test project; revalidated 2026-01-07). |
| REMED-06 | DONE | SOLID review notes captured for SPRINT_20260130_002. |