fix: clean up worktree refs + remaining schema extraction + route fixes
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -24,7 +24,7 @@ public static class AuditEndpoints
|
|||||||
.RequireTenant();
|
.RequireTenant();
|
||||||
|
|
||||||
// List and get operations
|
// List and get operations
|
||||||
group.MapGet(string.Empty, ListAuditEntries)
|
group.MapGet(string.Empty, ListAuditEntriesHandler)
|
||||||
.WithName("ReleaseOrchestrator_ListAuditEntries")
|
.WithName("ReleaseOrchestrator_ListAuditEntries")
|
||||||
.WithDescription(_t("orchestrator.audit.list_description"));
|
.WithDescription(_t("orchestrator.audit.list_description"));
|
||||||
|
|
||||||
@@ -56,7 +56,7 @@ public static class AuditEndpoints
|
|||||||
return group;
|
return group;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async Task<IResult> ListAuditEntries(
|
internal static async Task<IResult> ListAuditEntriesHandler(
|
||||||
HttpContext context,
|
HttpContext context,
|
||||||
[FromServices] TenantResolver tenantResolver,
|
[FromServices] TenantResolver tenantResolver,
|
||||||
[FromServices] IAuditRepository repository,
|
[FromServices] IAuditRepository repository,
|
||||||
|
|||||||
@@ -1,9 +1,4 @@
|
|||||||
using Microsoft.AspNetCore.Mvc;
|
|
||||||
using StellaOps.Auth.ServerIntegration.Tenancy;
|
using StellaOps.Auth.ServerIntegration.Tenancy;
|
||||||
using StellaOps.JobEngine.Core.Domain;
|
|
||||||
using StellaOps.JobEngine.Infrastructure.Repositories;
|
|
||||||
using StellaOps.ReleaseOrchestrator.WebApi.Contracts;
|
|
||||||
using StellaOps.ReleaseOrchestrator.WebApi.Services;
|
|
||||||
|
|
||||||
namespace StellaOps.ReleaseOrchestrator.WebApi.Endpoints;
|
namespace StellaOps.ReleaseOrchestrator.WebApi.Endpoints;
|
||||||
|
|
||||||
@@ -42,7 +37,7 @@ public static class JobEngineLegacyEndpoints
|
|||||||
.RequireAuthorization(ReleaseOrchestratorPolicies.Read)
|
.RequireAuthorization(ReleaseOrchestratorPolicies.Read)
|
||||||
.RequireTenant();
|
.RequireTenant();
|
||||||
|
|
||||||
group.MapGet("events", AuditEndpoints.ListAuditEventsLegacy);
|
group.MapGet("events", AuditEndpoints.ListAuditEntriesHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
|
|||||||
@@ -0,0 +1,44 @@
|
|||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
|
using Npgsql;
|
||||||
|
using StellaOps.Infrastructure.Postgres.Connections;
|
||||||
|
using StellaOps.Infrastructure.Postgres.Options;
|
||||||
|
|
||||||
|
namespace StellaOps.ReleaseOrchestrator.Persistence.Postgres;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// PostgreSQL data source for the ReleaseOrchestrator module.
|
||||||
|
/// </summary>
|
||||||
|
public sealed class ReleaseOrchestratorDataSource : DataSourceBase
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Default schema name for release-orchestrator tables.
|
||||||
|
/// </summary>
|
||||||
|
public const string DefaultSchemaName = "release_orchestrator";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new ReleaseOrchestrator data source.
|
||||||
|
/// </summary>
|
||||||
|
public ReleaseOrchestratorDataSource(IOptions<PostgresOptions> options, ILogger<ReleaseOrchestratorDataSource> logger)
|
||||||
|
: base(CreateOptions(options.Value), logger)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override string ModuleName => "ReleaseOrchestrator";
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void ConfigureDataSourceBuilder(NpgsqlDataSourceBuilder builder)
|
||||||
|
{
|
||||||
|
base.ConfigureDataSourceBuilder(builder);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static PostgresOptions CreateOptions(PostgresOptions baseOptions)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(baseOptions.SchemaName))
|
||||||
|
{
|
||||||
|
baseOptions.SchemaName = DefaultSchemaName;
|
||||||
|
}
|
||||||
|
return baseOptions;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,127 @@
|
|||||||
|
using StellaOps.ReleaseOrchestrator.Persistence.Domain;
|
||||||
|
|
||||||
|
namespace StellaOps.ReleaseOrchestrator.Persistence.Repositories;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Repository for audit log entries.
|
||||||
|
/// </summary>
|
||||||
|
public interface IAuditRepository
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Appends a new audit entry to the log.
|
||||||
|
/// </summary>
|
||||||
|
Task<AuditEntry> AppendAsync(
|
||||||
|
string tenantId,
|
||||||
|
AuditEventType eventType,
|
||||||
|
string resourceType,
|
||||||
|
Guid resourceId,
|
||||||
|
string actorId,
|
||||||
|
ActorType actorType,
|
||||||
|
string description,
|
||||||
|
string? oldState = null,
|
||||||
|
string? newState = null,
|
||||||
|
string? actorIp = null,
|
||||||
|
string? userAgent = null,
|
||||||
|
string? httpMethod = null,
|
||||||
|
string? requestPath = null,
|
||||||
|
string? correlationId = null,
|
||||||
|
string? metadata = null,
|
||||||
|
CancellationToken cancellationToken = default);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets an audit entry by ID.
|
||||||
|
/// </summary>
|
||||||
|
Task<AuditEntry?> GetByIdAsync(
|
||||||
|
string tenantId,
|
||||||
|
Guid entryId,
|
||||||
|
CancellationToken cancellationToken = default);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Lists audit entries with optional filters.
|
||||||
|
/// </summary>
|
||||||
|
Task<IReadOnlyList<AuditEntry>> ListAsync(
|
||||||
|
string tenantId,
|
||||||
|
AuditEventType? eventType = null,
|
||||||
|
string? resourceType = null,
|
||||||
|
Guid? resourceId = null,
|
||||||
|
string? actorId = null,
|
||||||
|
DateTimeOffset? startTime = null,
|
||||||
|
DateTimeOffset? endTime = null,
|
||||||
|
int limit = 100,
|
||||||
|
int offset = 0,
|
||||||
|
CancellationToken cancellationToken = default);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets audit entries by sequence range.
|
||||||
|
/// </summary>
|
||||||
|
Task<IReadOnlyList<AuditEntry>> GetBySequenceRangeAsync(
|
||||||
|
string tenantId,
|
||||||
|
long startSequence,
|
||||||
|
long endSequence,
|
||||||
|
CancellationToken cancellationToken = default);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the latest audit entry for a tenant.
|
||||||
|
/// </summary>
|
||||||
|
Task<AuditEntry?> GetLatestAsync(
|
||||||
|
string tenantId,
|
||||||
|
CancellationToken cancellationToken = default);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets audit entries for a specific resource.
|
||||||
|
/// </summary>
|
||||||
|
Task<IReadOnlyList<AuditEntry>> GetByResourceAsync(
|
||||||
|
string tenantId,
|
||||||
|
string resourceType,
|
||||||
|
Guid resourceId,
|
||||||
|
int limit = 100,
|
||||||
|
CancellationToken cancellationToken = default);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the count of audit entries.
|
||||||
|
/// </summary>
|
||||||
|
Task<long> GetCountAsync(
|
||||||
|
string tenantId,
|
||||||
|
AuditEventType? eventType = null,
|
||||||
|
DateTimeOffset? startTime = null,
|
||||||
|
DateTimeOffset? endTime = null,
|
||||||
|
CancellationToken cancellationToken = default);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Verifies the chain integrity for a range of entries.
|
||||||
|
/// </summary>
|
||||||
|
Task<ChainVerificationResult> VerifyChainAsync(
|
||||||
|
string tenantId,
|
||||||
|
long? startSequence = null,
|
||||||
|
long? endSequence = null,
|
||||||
|
CancellationToken cancellationToken = default);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets audit summary statistics.
|
||||||
|
/// </summary>
|
||||||
|
Task<AuditSummary> GetSummaryAsync(
|
||||||
|
string tenantId,
|
||||||
|
DateTimeOffset? since = null,
|
||||||
|
CancellationToken cancellationToken = default);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Result of chain verification.
|
||||||
|
/// </summary>
|
||||||
|
public sealed record ChainVerificationResult(
|
||||||
|
bool IsValid,
|
||||||
|
Guid? InvalidEntryId,
|
||||||
|
long? InvalidSequence,
|
||||||
|
string? ErrorMessage);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Audit summary statistics.
|
||||||
|
/// </summary>
|
||||||
|
public sealed record AuditSummary(
|
||||||
|
long TotalEntries,
|
||||||
|
long EntriesSince,
|
||||||
|
long EventTypes,
|
||||||
|
long UniqueActors,
|
||||||
|
long UniqueResources,
|
||||||
|
DateTimeOffset? EarliestEntry,
|
||||||
|
DateTimeOffset? LatestEntry);
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
using StellaOps.ReleaseOrchestrator.Persistence.Domain;
|
||||||
|
|
||||||
|
namespace StellaOps.ReleaseOrchestrator.Persistence.Services;
|
||||||
|
|
||||||
|
public interface IFirstSignalService
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the first signal for a run, checking cache first.
|
||||||
|
/// </summary>
|
||||||
|
Task<FirstSignalResult> GetFirstSignalAsync(
|
||||||
|
Guid runId,
|
||||||
|
string tenantId,
|
||||||
|
string? ifNoneMatch = null,
|
||||||
|
CancellationToken cancellationToken = default);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Updates the first signal snapshot for a run and invalidates any cached copies.
|
||||||
|
/// </summary>
|
||||||
|
Task UpdateSnapshotAsync(
|
||||||
|
Guid runId,
|
||||||
|
string tenantId,
|
||||||
|
FirstSignal signal,
|
||||||
|
CancellationToken cancellationToken = default);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Invalidates cached first signal for a run.
|
||||||
|
/// </summary>
|
||||||
|
Task InvalidateCacheAsync(
|
||||||
|
Guid runId,
|
||||||
|
string tenantId,
|
||||||
|
CancellationToken cancellationToken = default);
|
||||||
|
}
|
||||||
|
|
||||||
|
public sealed record FirstSignalResult
|
||||||
|
{
|
||||||
|
public required FirstSignalResultStatus Status { get; init; }
|
||||||
|
public FirstSignal? Signal { get; init; }
|
||||||
|
public string? ETag { get; init; }
|
||||||
|
public bool CacheHit { get; init; }
|
||||||
|
public string? Source { get; init; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum FirstSignalResultStatus
|
||||||
|
{
|
||||||
|
Found,
|
||||||
|
NotModified,
|
||||||
|
NotFound,
|
||||||
|
NotAvailable,
|
||||||
|
Error
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user