using StellaOps.Policy.Registry.Contracts;
namespace StellaOps.Policy.Registry.Services;
///
/// Service for managing policy pack promotions across environments.
/// Implements REGISTRY-API-27-008: Promotion bindings per tenant/environment.
///
public interface IPromotionService
{
///
/// Creates a promotion binding for a policy pack to an environment.
///
Task CreateBindingAsync(
Guid tenantId,
CreatePromotionBindingRequest request,
CancellationToken cancellationToken = default);
///
/// Promotes a policy pack to a target environment.
///
Task PromoteAsync(
Guid tenantId,
Guid packId,
PromoteRequest request,
CancellationToken cancellationToken = default);
///
/// Gets the current binding for a pack/environment combination.
///
Task GetBindingAsync(
Guid tenantId,
Guid packId,
string environment,
CancellationToken cancellationToken = default);
///
/// Lists all bindings for a tenant.
///
Task ListBindingsAsync(
Guid tenantId,
string? environment = null,
Guid? packId = null,
int pageSize = 20,
string? pageToken = null,
CancellationToken cancellationToken = default);
///
/// Gets the active policy pack for an environment.
///
Task GetActiveForEnvironmentAsync(
Guid tenantId,
string environment,
CancellationToken cancellationToken = default);
///
/// Rolls back to a previous promotion for an environment.
///
Task RollbackAsync(
Guid tenantId,
string environment,
RollbackRequest request,
CancellationToken cancellationToken = default);
///
/// Gets the promotion history for an environment.
///
Task> GetHistoryAsync(
Guid tenantId,
string environment,
int limit = 50,
CancellationToken cancellationToken = default);
///
/// Validates a promotion is allowed before executing.
///
Task ValidatePromotionAsync(
Guid tenantId,
Guid packId,
string targetEnvironment,
CancellationToken cancellationToken = default);
}
///
/// Request to create a promotion binding.
///
public sealed record CreatePromotionBindingRequest
{
public required Guid PackId { get; init; }
public required string Environment { get; init; }
public PromotionBindingMode Mode { get; init; } = PromotionBindingMode.Manual;
public PromotionBindingRules? Rules { get; init; }
public IReadOnlyDictionary? Metadata { get; init; }
public string? CreatedBy { get; init; }
}
///
/// Request to promote a policy pack.
///
public sealed record PromoteRequest
{
public required string TargetEnvironment { get; init; }
public string? ApprovalId { get; init; }
public string? PromotedBy { get; init; }
public string? Comment { get; init; }
public bool Force { get; init; }
}
///
/// Request to rollback a promotion.
///
public sealed record RollbackRequest
{
public string? TargetBindingId { get; init; }
public int? StepsBack { get; init; }
public string? RolledBackBy { get; init; }
public string? Reason { get; init; }
}
///
/// Promotion binding mode.
///
public enum PromotionBindingMode
{
Manual,
AutomaticOnApproval,
Scheduled,
Canary
}
///
/// Rules for automatic promotion.
///
public sealed record PromotionBindingRules
{
public IReadOnlyList? RequiredApprovers { get; init; }
public int? MinimumApprovals { get; init; }
public bool RequireSuccessfulSimulation { get; init; }
public int? MinimumSimulationInputs { get; init; }
public TimeSpan? MinimumSoakPeriod { get; init; }
public IReadOnlyList? AllowedSourceEnvironments { get; init; }
}
///
/// Promotion binding.
///
public sealed record PromotionBinding
{
public required string BindingId { get; init; }
public required Guid TenantId { get; init; }
public required Guid PackId { get; init; }
public required string PackVersion { get; init; }
public required string Environment { get; init; }
public required PromotionBindingMode Mode { get; init; }
public required PromotionBindingStatus Status { get; init; }
public PromotionBindingRules? Rules { get; init; }
public required DateTimeOffset CreatedAt { get; init; }
public DateTimeOffset? ActivatedAt { get; init; }
public DateTimeOffset? DeactivatedAt { get; init; }
public string? CreatedBy { get; init; }
public string? ActivatedBy { get; init; }
public IReadOnlyDictionary? Metadata { get; init; }
}
///
/// Promotion binding status.
///
public enum PromotionBindingStatus
{
Pending,
Active,
Superseded,
RolledBack,
Disabled
}
///
/// Result of a promotion operation.
///
public sealed record PromotionResult
{
public required bool Success { get; init; }
public PromotionBinding? Binding { get; init; }
public string? PreviousBindingId { get; init; }
public string? Error { get; init; }
public IReadOnlyList? Warnings { get; init; }
}
///
/// List of promotion bindings.
///
public sealed record PromotionBindingList
{
public required IReadOnlyList Items { get; init; }
public string? NextPageToken { get; init; }
public int TotalCount { get; init; }
}
///
/// Active policy pack for an environment.
///
public sealed record ActiveEnvironmentPolicy
{
public required string Environment { get; init; }
public required Guid PackId { get; init; }
public required string PackVersion { get; init; }
public required string PackDigest { get; init; }
public required string BindingId { get; init; }
public required DateTimeOffset ActivatedAt { get; init; }
public string? ActivatedBy { get; init; }
}
///
/// Result of a rollback operation.
///
public sealed record RollbackResult
{
public required bool Success { get; init; }
public PromotionBinding? RestoredBinding { get; init; }
public string? RolledBackBindingId { get; init; }
public string? Error { get; init; }
}
///
/// Promotion history entry.
///
public sealed record PromotionHistoryEntry
{
public required string BindingId { get; init; }
public required Guid PackId { get; init; }
public required string PackVersion { get; init; }
public required PromotionHistoryAction Action { get; init; }
public required DateTimeOffset Timestamp { get; init; }
public string? PerformedBy { get; init; }
public string? Comment { get; init; }
public string? PreviousBindingId { get; init; }
}
///
/// Promotion history action types.
///
public enum PromotionHistoryAction
{
Promoted,
RolledBack,
Disabled,
Superseded
}
///
/// Result of promotion validation.
///
public sealed record PromotionValidationResult
{
public required bool IsValid { get; init; }
public IReadOnlyList? Errors { get; init; }
public IReadOnlyList? Warnings { get; init; }
}
///
/// Promotion validation error.
///
public sealed record PromotionValidationError
{
public required string Code { get; init; }
public required string Message { get; init; }
}
///
/// Promotion validation warning.
///
public sealed record PromotionValidationWarning
{
public required string Code { get; init; }
public required string Message { get; init; }
}