docs re-org, audit fixes, build fixes

This commit is contained in:
StellaOps Bot
2026-01-05 09:35:33 +02:00
parent eca4e964d3
commit dfab8a29c3
173 changed files with 1276 additions and 560 deletions

View File

@@ -100,6 +100,7 @@ public static class GovernanceEndpoints
private static Task<IResult> GetSealedModeStatusAsync(
HttpContext httpContext,
[FromServices] TimeProvider timeProvider,
[FromQuery] string? tenantId)
{
var tenant = tenantId ?? GetTenantId(httpContext) ?? "default";
@@ -118,7 +119,7 @@ public static class GovernanceEndpoints
.Select(MapOverrideToResponse)
.ToList(),
VerificationStatus = "verified",
LastVerifiedAt = DateTimeOffset.UtcNow.ToString("O")
LastVerifiedAt = timeProvider.GetUtcNow().ToString("O")
};
return Task.FromResult(Results.Ok(response));
@@ -140,11 +141,12 @@ public static class GovernanceEndpoints
private static Task<IResult> ToggleSealedModeAsync(
HttpContext httpContext,
[FromServices] TimeProvider timeProvider,
SealedModeToggleRequest request)
{
var tenant = GetTenantId(httpContext) ?? "default";
var actor = GetActorId(httpContext) ?? "system";
var now = DateTimeOffset.UtcNow;
var now = timeProvider.GetUtcNow();
var state = SealedModeStates.GetOrAdd(tenant, _ => new SealedModeState());
@@ -173,7 +175,7 @@ public static class GovernanceEndpoints
// Audit
RecordAudit(tenant, actor, "sealed_mode_toggled", "sealed-mode", "system_config",
$"{(request.Enable ? "Enabled" : "Disabled")} sealed mode: {request.Reason}");
$"{(request.Enable ? "Enabled" : "Disabled")} sealed mode: {request.Reason}", timeProvider);
var response = new SealedModeStatusResponse
{
@@ -193,11 +195,12 @@ public static class GovernanceEndpoints
private static Task<IResult> CreateSealedModeOverrideAsync(
HttpContext httpContext,
[FromServices] TimeProvider timeProvider,
SealedModeOverrideRequest request)
{
var tenant = GetTenantId(httpContext) ?? "default";
var actor = GetActorId(httpContext) ?? "system";
var now = DateTimeOffset.UtcNow;
var now = timeProvider.GetUtcNow();
var overrideId = $"override-{Guid.NewGuid():N}";
var entity = new SealedModeOverrideEntity
@@ -217,13 +220,14 @@ public static class GovernanceEndpoints
Overrides[overrideId] = entity;
RecordAudit(tenant, actor, "sealed_mode_override_created", overrideId, "sealed_mode_override",
$"Created override for {request.Target}: {request.Reason}");
$"Created override for {request.Target}: {request.Reason}", timeProvider);
return Task.FromResult(Results.Ok(MapOverrideToResponse(entity)));
}
private static Task<IResult> RevokeSealedModeOverrideAsync(
HttpContext httpContext,
[FromServices] TimeProvider timeProvider,
string overrideId,
RevokeOverrideRequest request)
{
@@ -243,7 +247,7 @@ public static class GovernanceEndpoints
Overrides[overrideId] = entity;
RecordAudit(tenant, actor, "sealed_mode_override_revoked", overrideId, "sealed_mode_override",
$"Revoked override: {request.Reason}");
$"Revoked override: {request.Reason}", timeProvider);
return Task.FromResult(Results.NoContent());
}
@@ -289,11 +293,12 @@ public static class GovernanceEndpoints
private static Task<IResult> CreateRiskProfileAsync(
HttpContext httpContext,
[FromServices] TimeProvider timeProvider,
CreateRiskProfileRequest request)
{
var tenant = GetTenantId(httpContext) ?? "default";
var actor = GetActorId(httpContext) ?? "system";
var now = DateTimeOffset.UtcNow;
var now = timeProvider.GetUtcNow();
var profileId = $"profile-{Guid.NewGuid():N}";
var entity = new RiskProfileEntity
@@ -317,19 +322,20 @@ public static class GovernanceEndpoints
RiskProfiles[profileId] = entity;
RecordAudit(tenant, actor, "risk_profile_created", profileId, "risk_profile",
$"Created risk profile: {request.Name}");
$"Created risk profile: {request.Name}", timeProvider);
return Task.FromResult(Results.Created($"/api/v1/governance/risk-profiles/{profileId}", MapProfileToResponse(entity)));
}
private static Task<IResult> UpdateRiskProfileAsync(
HttpContext httpContext,
[FromServices] TimeProvider timeProvider,
string profileId,
UpdateRiskProfileRequest request)
{
var tenant = GetTenantId(httpContext) ?? "default";
var actor = GetActorId(httpContext) ?? "system";
var now = DateTimeOffset.UtcNow;
var now = timeProvider.GetUtcNow();
if (!RiskProfiles.TryGetValue(profileId, out var existing))
{
@@ -354,13 +360,14 @@ public static class GovernanceEndpoints
RiskProfiles[profileId] = entity;
RecordAudit(tenant, actor, "risk_profile_updated", profileId, "risk_profile",
$"Updated risk profile: {entity.Name}");
$"Updated risk profile: {entity.Name}", timeProvider);
return Task.FromResult(Results.Ok(MapProfileToResponse(entity)));
}
private static Task<IResult> DeleteRiskProfileAsync(
HttpContext httpContext,
[FromServices] TimeProvider timeProvider,
string profileId)
{
var tenant = GetTenantId(httpContext) ?? "default";
@@ -376,18 +383,19 @@ public static class GovernanceEndpoints
}
RecordAudit(tenant, actor, "risk_profile_deleted", profileId, "risk_profile",
$"Deleted risk profile: {removed.Name}");
$"Deleted risk profile: {removed.Name}", timeProvider);
return Task.FromResult(Results.NoContent());
}
private static Task<IResult> ActivateRiskProfileAsync(
HttpContext httpContext,
[FromServices] TimeProvider timeProvider,
string profileId)
{
var tenant = GetTenantId(httpContext) ?? "default";
var actor = GetActorId(httpContext) ?? "system";
var now = DateTimeOffset.UtcNow;
var now = timeProvider.GetUtcNow();
if (!RiskProfiles.TryGetValue(profileId, out var existing))
{
@@ -408,19 +416,20 @@ public static class GovernanceEndpoints
RiskProfiles[profileId] = entity;
RecordAudit(tenant, actor, "risk_profile_activated", profileId, "risk_profile",
$"Activated risk profile: {entity.Name}");
$"Activated risk profile: {entity.Name}", timeProvider);
return Task.FromResult(Results.Ok(MapProfileToResponse(entity)));
}
private static Task<IResult> DeprecateRiskProfileAsync(
HttpContext httpContext,
[FromServices] TimeProvider timeProvider,
string profileId,
DeprecateProfileRequest request)
{
var tenant = GetTenantId(httpContext) ?? "default";
var actor = GetActorId(httpContext) ?? "system";
var now = DateTimeOffset.UtcNow;
var now = timeProvider.GetUtcNow();
if (!RiskProfiles.TryGetValue(profileId, out var existing))
{
@@ -442,7 +451,7 @@ public static class GovernanceEndpoints
RiskProfiles[profileId] = entity;
RecordAudit(tenant, actor, "risk_profile_deprecated", profileId, "risk_profile",
$"Deprecated risk profile: {entity.Name} - {request.Reason}");
$"Deprecated risk profile: {entity.Name} - {request.Reason}", timeProvider);
return Task.FromResult(Results.Ok(MapProfileToResponse(entity)));
}
@@ -582,7 +591,7 @@ public static class GovernanceEndpoints
?? httpContext.Request.Headers["X-StellaOps-Actor"].FirstOrDefault();
}
private static void RecordAudit(string tenantId, string actor, string eventType, string targetId, string targetType, string summary)
private static void RecordAudit(string tenantId, string actor, string eventType, string targetId, string targetType, string summary, TimeProvider timeProvider)
{
var id = $"audit-{Guid.NewGuid():N}";
AuditEntries[id] = new GovernanceAuditEntry
@@ -590,7 +599,7 @@ public static class GovernanceEndpoints
Id = id,
TenantId = tenantId,
Type = eventType,
Timestamp = DateTimeOffset.UtcNow.ToString("O"),
Timestamp = timeProvider.GetUtcNow().ToString("O"),
Actor = actor,
ActorType = "user",
TargetResource = targetId,