Rewrite UI API clients from /api/v2/releases to /api/v1/release-orchestrator

Completes Sprint 323 TASK-001 using Option C (direct URL rewrite):
- release-management.client.ts: readBaseUrl and legacyBaseUrl now use
  /api/v1/release-orchestrator/releases, eliminating the v2 proxy dependency
- All 15+ component files updated: activity, approvals, runs, versions,
  bundle-organizer, sidebar queries, topology pages
- Spec files updated to match new URL patterns
- Added /releases/activity and /releases/versions backend route aliases
  in ReleaseEndpoints.cs with ListActivity and ListVersions handlers
- Fixed orphaned audit-log-dashboard.component import → audit-log-table
- Both Angular build and JobEngine build pass clean

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
master
2026-04-01 00:16:32 +03:00
parent f96c6cb9ed
commit a4c4690fef
22 changed files with 257 additions and 138 deletions

View File

@@ -160,6 +160,20 @@ public static class ReleaseEndpoints
{
targets.WithName("Release_AvailableEnvironments");
}
var activity = group.MapGet("/activity", ListActivity)
.WithDescription("Return a paginated feed of release activities across all releases, optionally filtered by environment, outcome, and time window.");
if (includeRouteNames)
{
activity.WithName("Release_Activity");
}
var versions = group.MapGet("/versions", ListVersions)
.WithDescription("Return a filtered list of release versions, optionally filtered by gate status.");
if (includeRouteNames)
{
versions.WithName("Release_Versions");
}
}
// ---- Handlers ----
@@ -636,6 +650,53 @@ public static class ReleaseEndpoints
public Dictionary<string, string>? ConfigOverrides { get; init; }
}
private static IResult ListActivity(
[FromQuery] string? environment,
[FromQuery] string? outcome,
[FromQuery] int? limit,
[FromQuery] string? releaseId)
{
var events = SeedData.Events.Values.SelectMany(e => e).AsEnumerable();
if (!string.IsNullOrWhiteSpace(environment))
events = events.Where(e => string.Equals(e.Environment, environment, StringComparison.OrdinalIgnoreCase));
if (!string.IsNullOrWhiteSpace(outcome))
events = events.Where(e => string.Equals(e.Type, outcome, StringComparison.OrdinalIgnoreCase));
if (!string.IsNullOrWhiteSpace(releaseId))
events = events.Where(e => string.Equals(e.ReleaseId, releaseId, StringComparison.OrdinalIgnoreCase));
var sorted = events.OrderByDescending(e => e.Timestamp).ToList();
var items = limit > 0 ? sorted.Take(limit.Value).ToList() : sorted;
return Results.Ok(new { items, total = sorted.Count });
}
private static IResult ListVersions(
[FromQuery] string? gateStatus,
[FromQuery] int? limit)
{
var releases = SeedData.Releases.AsEnumerable();
if (!string.IsNullOrWhiteSpace(gateStatus))
{
// Map gate status to release status for filtering
releases = gateStatus.ToLowerInvariant() switch
{
"block" => releases.Where(r => r.Status is "failed" or "rolled_back"),
"pass" => releases.Where(r => r.Status is "ready" or "deployed"),
"warn" => releases.Where(r => r.Status is "deploying"),
_ => releases,
};
}
var sorted = releases.OrderByDescending(r => r.CreatedAt).ToList();
var items = limit > 0 ? sorted.Take(limit.Value).ToList() : sorted;
return Results.Ok(new { items, total = sorted.Count });
}
// ---- Seed Data ----
internal static class SeedData