Concelier: - Register Topology.Read, Topology.Manage, Topology.Admin authorization policies mapped to OrchRead/OrchOperate/PlatformContextRead/IntegrationWrite scopes. Previously these policies were referenced by endpoints but never registered, causing System.InvalidOperationException on every topology API call. Gateway routes: - Simplified targets/environments routes (removed specific sub-path routes, use catch-all patterns instead) - Changed environments base route to JobEngine (where CRUD lives) - Changed to ReverseProxy type for all topology routes KNOWN ISSUE (not yet fixed): - ReverseProxy routes don't forward the gateway's identity envelope to Concelier. The regions/targets/bindings endpoints return 401 because hasPrincipal=False — the gateway authenticates the user but doesn't pass the identity to the backend via ReverseProxy. Microservice routes use Valkey transport which includes envelope headers. Topology endpoints need either: (a) Valkey transport registration in Concelier, or (b) Concelier configured to accept raw bearer tokens on ReverseProxy paths. This is an architecture-level fix. Journey findings collected so far: - Integration wizard (Harbor + GitHub App): works end-to-end - Advisory Check All: fixed (parallel individual checks) - Mirror domain creation: works, generate-immediately fails silently - Topology wizard Step 1 (Region): blocked by auth passthrough issue - Topology wizard Step 2 (Environment): POST to JobEngine needs verify - User ID resolution: raw hashes shown everywhere Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
43 lines
1.5 KiB
C#
43 lines
1.5 KiB
C#
using Npgsql;
|
|
using StellaOps.JobEngine.Infrastructure.Postgres;
|
|
|
|
namespace StellaOps.JobEngine.Tests.DeadLetter;
|
|
|
|
public sealed class PostgresDeadLetterRepositoryTests
|
|
{
|
|
[Theory]
|
|
[InlineData(PostgresErrorCodes.UndefinedFunction)]
|
|
[InlineData(PostgresErrorCodes.AmbiguousColumn)]
|
|
public void ShouldUseActionableSummaryFallback_ReturnsTrue_ForRecoverableLegacySqlStates(string sqlState)
|
|
{
|
|
Assert.True(PostgresDeadLetterRepository.ShouldUseActionableSummaryFallback(sqlState));
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData(PostgresErrorCodes.UndefinedTable)]
|
|
[InlineData("XX000")]
|
|
[InlineData(null)]
|
|
public void ShouldUseActionableSummaryFallback_ReturnsFalse_ForNonFallbackSqlStates(string? sqlState)
|
|
{
|
|
Assert.False(PostgresDeadLetterRepository.ShouldUseActionableSummaryFallback(sqlState));
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData(PostgresErrorCodes.UndefinedTable)]
|
|
[InlineData("25P02")] // in_failed_sql_transaction
|
|
public void IsMissingTableOrAbortedTransaction_ReturnsTrue_ForExpectedSqlStates(string sqlState)
|
|
{
|
|
Assert.True(PostgresDeadLetterRepository.IsMissingTableOrAbortedTransaction(sqlState));
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData(PostgresErrorCodes.UndefinedFunction)]
|
|
[InlineData(PostgresErrorCodes.AmbiguousColumn)]
|
|
[InlineData("XX000")]
|
|
[InlineData(null)]
|
|
public void IsMissingTableOrAbortedTransaction_ReturnsFalse_ForOtherSqlStates(string? sqlState)
|
|
{
|
|
Assert.False(PostgresDeadLetterRepository.IsMissingTableOrAbortedTransaction(sqlState));
|
|
}
|
|
}
|