Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
Concelier Attestation Tests / attestation-tests (push) Has been cancelled
Policy Lint & Smoke / policy-lint (push) Has been cancelled
613 lines
15 KiB
C#
613 lines
15 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Text.Json.Serialization;
|
|
|
|
namespace StellaOps.Cli.Services.Models;
|
|
|
|
// CLI-PARITY-41-002: Notify command models for CLI
|
|
|
|
/// <summary>
|
|
/// Notify channel types.
|
|
/// </summary>
|
|
[JsonConverter(typeof(JsonStringEnumConverter))]
|
|
internal enum NotifyChannelType
|
|
{
|
|
Slack,
|
|
Teams,
|
|
Email,
|
|
Webhook,
|
|
Custom,
|
|
PagerDuty,
|
|
OpsGenie,
|
|
Cli,
|
|
InAppInbox,
|
|
InApp
|
|
}
|
|
|
|
/// <summary>
|
|
/// Notify delivery status.
|
|
/// </summary>
|
|
[JsonConverter(typeof(JsonStringEnumConverter))]
|
|
internal enum NotifyDeliveryStatus
|
|
{
|
|
Pending,
|
|
Sent,
|
|
Failed,
|
|
Throttled,
|
|
Digested,
|
|
Dropped
|
|
}
|
|
|
|
/// <summary>
|
|
/// Notify channel list request.
|
|
/// </summary>
|
|
internal sealed class NotifyChannelListRequest
|
|
{
|
|
[JsonPropertyName("tenant")]
|
|
public string? Tenant { get; init; }
|
|
|
|
[JsonPropertyName("type")]
|
|
public string? Type { get; init; }
|
|
|
|
[JsonPropertyName("enabled")]
|
|
public bool? Enabled { get; init; }
|
|
|
|
[JsonPropertyName("limit")]
|
|
public int? Limit { get; init; }
|
|
|
|
[JsonPropertyName("offset")]
|
|
public int? Offset { get; init; }
|
|
|
|
[JsonPropertyName("cursor")]
|
|
public string? Cursor { get; init; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Notify channel list response.
|
|
/// </summary>
|
|
internal sealed class NotifyChannelListResponse
|
|
{
|
|
[JsonPropertyName("items")]
|
|
public IReadOnlyList<NotifyChannelSummary> Items { get; init; } = [];
|
|
|
|
[JsonPropertyName("total")]
|
|
public int Total { get; init; }
|
|
|
|
[JsonPropertyName("hasMore")]
|
|
public bool HasMore { get; init; }
|
|
|
|
[JsonPropertyName("nextCursor")]
|
|
public string? NextCursor { get; init; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Notify channel summary for list view.
|
|
/// </summary>
|
|
internal sealed class NotifyChannelSummary
|
|
{
|
|
[JsonPropertyName("channelId")]
|
|
public string ChannelId { get; init; } = string.Empty;
|
|
|
|
[JsonPropertyName("name")]
|
|
public string Name { get; init; } = string.Empty;
|
|
|
|
[JsonPropertyName("displayName")]
|
|
public string? DisplayName { get; init; }
|
|
|
|
[JsonPropertyName("type")]
|
|
public string Type { get; init; } = string.Empty;
|
|
|
|
[JsonPropertyName("enabled")]
|
|
public bool Enabled { get; init; }
|
|
|
|
[JsonPropertyName("createdAt")]
|
|
public DateTimeOffset CreatedAt { get; init; }
|
|
|
|
[JsonPropertyName("updatedAt")]
|
|
public DateTimeOffset UpdatedAt { get; init; }
|
|
|
|
[JsonPropertyName("deliveryCount")]
|
|
public int DeliveryCount { get; init; }
|
|
|
|
[JsonPropertyName("failureRate")]
|
|
public double? FailureRate { get; init; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Detailed notify channel response.
|
|
/// </summary>
|
|
internal sealed class NotifyChannelDetail
|
|
{
|
|
[JsonPropertyName("channelId")]
|
|
public string ChannelId { get; init; } = string.Empty;
|
|
|
|
[JsonPropertyName("tenantId")]
|
|
public string TenantId { get; init; } = string.Empty;
|
|
|
|
[JsonPropertyName("name")]
|
|
public string Name { get; init; } = string.Empty;
|
|
|
|
[JsonPropertyName("displayName")]
|
|
public string? DisplayName { get; init; }
|
|
|
|
[JsonPropertyName("description")]
|
|
public string? Description { get; init; }
|
|
|
|
[JsonPropertyName("type")]
|
|
public string Type { get; init; } = string.Empty;
|
|
|
|
[JsonPropertyName("enabled")]
|
|
public bool Enabled { get; init; }
|
|
|
|
[JsonPropertyName("config")]
|
|
public NotifyChannelConfigInfo? Config { get; init; }
|
|
|
|
[JsonPropertyName("labels")]
|
|
public IReadOnlyDictionary<string, string>? Labels { get; init; }
|
|
|
|
[JsonPropertyName("metadata")]
|
|
public IReadOnlyDictionary<string, string>? Metadata { get; init; }
|
|
|
|
[JsonPropertyName("createdBy")]
|
|
public string? CreatedBy { get; init; }
|
|
|
|
[JsonPropertyName("createdAt")]
|
|
public DateTimeOffset CreatedAt { get; init; }
|
|
|
|
[JsonPropertyName("updatedBy")]
|
|
public string? UpdatedBy { get; init; }
|
|
|
|
[JsonPropertyName("updatedAt")]
|
|
public DateTimeOffset UpdatedAt { get; init; }
|
|
|
|
[JsonPropertyName("stats")]
|
|
public NotifyChannelStats? Stats { get; init; }
|
|
|
|
[JsonPropertyName("health")]
|
|
public NotifyChannelHealth? Health { get; init; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Notify channel configuration info (redacted secrets).
|
|
/// </summary>
|
|
internal sealed class NotifyChannelConfigInfo
|
|
{
|
|
[JsonPropertyName("secretRef")]
|
|
public string SecretRef { get; init; } = string.Empty;
|
|
|
|
[JsonPropertyName("target")]
|
|
public string? Target { get; init; }
|
|
|
|
[JsonPropertyName("endpoint")]
|
|
public string? Endpoint { get; init; }
|
|
|
|
[JsonPropertyName("properties")]
|
|
public IReadOnlyDictionary<string, string>? Properties { get; init; }
|
|
|
|
[JsonPropertyName("limits")]
|
|
public NotifyChannelLimitsInfo? Limits { get; init; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Notify channel limits.
|
|
/// </summary>
|
|
internal sealed class NotifyChannelLimitsInfo
|
|
{
|
|
[JsonPropertyName("concurrency")]
|
|
public int? Concurrency { get; init; }
|
|
|
|
[JsonPropertyName("requestsPerMinute")]
|
|
public int? RequestsPerMinute { get; init; }
|
|
|
|
[JsonPropertyName("timeoutSeconds")]
|
|
public int? TimeoutSeconds { get; init; }
|
|
|
|
[JsonPropertyName("maxBatchSize")]
|
|
public int? MaxBatchSize { get; init; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Notify channel statistics.
|
|
/// </summary>
|
|
internal sealed class NotifyChannelStats
|
|
{
|
|
[JsonPropertyName("totalDeliveries")]
|
|
public long TotalDeliveries { get; init; }
|
|
|
|
[JsonPropertyName("successfulDeliveries")]
|
|
public long SuccessfulDeliveries { get; init; }
|
|
|
|
[JsonPropertyName("failedDeliveries")]
|
|
public long FailedDeliveries { get; init; }
|
|
|
|
[JsonPropertyName("throttledDeliveries")]
|
|
public long ThrottledDeliveries { get; init; }
|
|
|
|
[JsonPropertyName("lastDeliveryAt")]
|
|
public DateTimeOffset? LastDeliveryAt { get; init; }
|
|
|
|
[JsonPropertyName("avgLatencyMs")]
|
|
public double? AvgLatencyMs { get; init; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Notify channel health status.
|
|
/// </summary>
|
|
internal sealed class NotifyChannelHealth
|
|
{
|
|
[JsonPropertyName("status")]
|
|
public string Status { get; init; } = string.Empty;
|
|
|
|
[JsonPropertyName("lastCheckAt")]
|
|
public DateTimeOffset? LastCheckAt { get; init; }
|
|
|
|
[JsonPropertyName("consecutiveFailures")]
|
|
public int ConsecutiveFailures { get; init; }
|
|
|
|
[JsonPropertyName("errorMessage")]
|
|
public string? ErrorMessage { get; init; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Channel test request.
|
|
/// </summary>
|
|
internal sealed class NotifyChannelTestRequest
|
|
{
|
|
[JsonPropertyName("tenant")]
|
|
public string? Tenant { get; init; }
|
|
|
|
[JsonPropertyName("channelId")]
|
|
public string ChannelId { get; init; } = string.Empty;
|
|
|
|
[JsonPropertyName("message")]
|
|
public string? Message { get; init; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Channel test result.
|
|
/// </summary>
|
|
internal sealed class NotifyChannelTestResult
|
|
{
|
|
[JsonPropertyName("success")]
|
|
public bool Success { get; init; }
|
|
|
|
[JsonPropertyName("channelId")]
|
|
public string ChannelId { get; init; } = string.Empty;
|
|
|
|
[JsonPropertyName("latencyMs")]
|
|
public long? LatencyMs { get; init; }
|
|
|
|
[JsonPropertyName("responseCode")]
|
|
public int? ResponseCode { get; init; }
|
|
|
|
[JsonPropertyName("errorMessage")]
|
|
public string? ErrorMessage { get; init; }
|
|
|
|
[JsonPropertyName("deliveryId")]
|
|
public string? DeliveryId { get; init; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Notify rule list request.
|
|
/// </summary>
|
|
internal sealed class NotifyRuleListRequest
|
|
{
|
|
[JsonPropertyName("tenant")]
|
|
public string? Tenant { get; init; }
|
|
|
|
[JsonPropertyName("enabled")]
|
|
public bool? Enabled { get; init; }
|
|
|
|
[JsonPropertyName("eventType")]
|
|
public string? EventType { get; init; }
|
|
|
|
[JsonPropertyName("channelId")]
|
|
public string? ChannelId { get; init; }
|
|
|
|
[JsonPropertyName("limit")]
|
|
public int? Limit { get; init; }
|
|
|
|
[JsonPropertyName("offset")]
|
|
public int? Offset { get; init; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Notify rule list response.
|
|
/// </summary>
|
|
internal sealed class NotifyRuleListResponse
|
|
{
|
|
[JsonPropertyName("items")]
|
|
public IReadOnlyList<NotifyRuleSummary> Items { get; init; } = [];
|
|
|
|
[JsonPropertyName("total")]
|
|
public int Total { get; init; }
|
|
|
|
[JsonPropertyName("hasMore")]
|
|
public bool HasMore { get; init; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Notify rule summary.
|
|
/// </summary>
|
|
internal sealed class NotifyRuleSummary
|
|
{
|
|
[JsonPropertyName("ruleId")]
|
|
public string RuleId { get; init; } = string.Empty;
|
|
|
|
[JsonPropertyName("name")]
|
|
public string Name { get; init; } = string.Empty;
|
|
|
|
[JsonPropertyName("description")]
|
|
public string? Description { get; init; }
|
|
|
|
[JsonPropertyName("enabled")]
|
|
public bool Enabled { get; init; }
|
|
|
|
[JsonPropertyName("eventTypes")]
|
|
public IReadOnlyList<string> EventTypes { get; init; } = [];
|
|
|
|
[JsonPropertyName("channelIds")]
|
|
public IReadOnlyList<string> ChannelIds { get; init; } = [];
|
|
|
|
[JsonPropertyName("priority")]
|
|
public int Priority { get; init; }
|
|
|
|
[JsonPropertyName("matchCount")]
|
|
public long MatchCount { get; init; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Notify delivery list request.
|
|
/// </summary>
|
|
internal sealed class NotifyDeliveryListRequest
|
|
{
|
|
[JsonPropertyName("tenant")]
|
|
public string? Tenant { get; init; }
|
|
|
|
[JsonPropertyName("channelId")]
|
|
public string? ChannelId { get; init; }
|
|
|
|
[JsonPropertyName("status")]
|
|
public string? Status { get; init; }
|
|
|
|
[JsonPropertyName("eventType")]
|
|
public string? EventType { get; init; }
|
|
|
|
[JsonPropertyName("since")]
|
|
public DateTimeOffset? Since { get; init; }
|
|
|
|
[JsonPropertyName("until")]
|
|
public DateTimeOffset? Until { get; init; }
|
|
|
|
[JsonPropertyName("limit")]
|
|
public int? Limit { get; init; }
|
|
|
|
[JsonPropertyName("cursor")]
|
|
public string? Cursor { get; init; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Notify delivery list response.
|
|
/// </summary>
|
|
internal sealed class NotifyDeliveryListResponse
|
|
{
|
|
[JsonPropertyName("items")]
|
|
public IReadOnlyList<NotifyDeliverySummary> Items { get; init; } = [];
|
|
|
|
[JsonPropertyName("total")]
|
|
public int Total { get; init; }
|
|
|
|
[JsonPropertyName("hasMore")]
|
|
public bool HasMore { get; init; }
|
|
|
|
[JsonPropertyName("nextCursor")]
|
|
public string? NextCursor { get; init; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Notify delivery summary.
|
|
/// </summary>
|
|
internal sealed class NotifyDeliverySummary
|
|
{
|
|
[JsonPropertyName("deliveryId")]
|
|
public string DeliveryId { get; init; } = string.Empty;
|
|
|
|
[JsonPropertyName("channelId")]
|
|
public string ChannelId { get; init; } = string.Empty;
|
|
|
|
[JsonPropertyName("channelName")]
|
|
public string? ChannelName { get; init; }
|
|
|
|
[JsonPropertyName("channelType")]
|
|
public string ChannelType { get; init; } = string.Empty;
|
|
|
|
[JsonPropertyName("eventType")]
|
|
public string EventType { get; init; } = string.Empty;
|
|
|
|
[JsonPropertyName("status")]
|
|
public string Status { get; init; } = string.Empty;
|
|
|
|
[JsonPropertyName("attemptCount")]
|
|
public int AttemptCount { get; init; }
|
|
|
|
[JsonPropertyName("createdAt")]
|
|
public DateTimeOffset CreatedAt { get; init; }
|
|
|
|
[JsonPropertyName("sentAt")]
|
|
public DateTimeOffset? SentAt { get; init; }
|
|
|
|
[JsonPropertyName("latencyMs")]
|
|
public long? LatencyMs { get; init; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Notify delivery detail.
|
|
/// </summary>
|
|
internal sealed class NotifyDeliveryDetail
|
|
{
|
|
[JsonPropertyName("deliveryId")]
|
|
public string DeliveryId { get; init; } = string.Empty;
|
|
|
|
[JsonPropertyName("tenantId")]
|
|
public string TenantId { get; init; } = string.Empty;
|
|
|
|
[JsonPropertyName("channelId")]
|
|
public string ChannelId { get; init; } = string.Empty;
|
|
|
|
[JsonPropertyName("channelName")]
|
|
public string? ChannelName { get; init; }
|
|
|
|
[JsonPropertyName("channelType")]
|
|
public string ChannelType { get; init; } = string.Empty;
|
|
|
|
[JsonPropertyName("ruleId")]
|
|
public string? RuleId { get; init; }
|
|
|
|
[JsonPropertyName("eventId")]
|
|
public string? EventId { get; init; }
|
|
|
|
[JsonPropertyName("eventType")]
|
|
public string EventType { get; init; } = string.Empty;
|
|
|
|
[JsonPropertyName("status")]
|
|
public string Status { get; init; } = string.Empty;
|
|
|
|
[JsonPropertyName("subject")]
|
|
public string? Subject { get; init; }
|
|
|
|
[JsonPropertyName("attemptCount")]
|
|
public int AttemptCount { get; init; }
|
|
|
|
[JsonPropertyName("attempts")]
|
|
public IReadOnlyList<NotifyDeliveryAttempt>? Attempts { get; init; }
|
|
|
|
[JsonPropertyName("createdAt")]
|
|
public DateTimeOffset CreatedAt { get; init; }
|
|
|
|
[JsonPropertyName("sentAt")]
|
|
public DateTimeOffset? SentAt { get; init; }
|
|
|
|
[JsonPropertyName("failedAt")]
|
|
public DateTimeOffset? FailedAt { get; init; }
|
|
|
|
[JsonPropertyName("errorMessage")]
|
|
public string? ErrorMessage { get; init; }
|
|
|
|
[JsonPropertyName("idempotencyKey")]
|
|
public string? IdempotencyKey { get; init; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Notify delivery attempt.
|
|
/// </summary>
|
|
internal sealed class NotifyDeliveryAttempt
|
|
{
|
|
[JsonPropertyName("attemptNumber")]
|
|
public int AttemptNumber { get; init; }
|
|
|
|
[JsonPropertyName("status")]
|
|
public string Status { get; init; } = string.Empty;
|
|
|
|
[JsonPropertyName("attemptedAt")]
|
|
public DateTimeOffset AttemptedAt { get; init; }
|
|
|
|
[JsonPropertyName("latencyMs")]
|
|
public long? LatencyMs { get; init; }
|
|
|
|
[JsonPropertyName("responseCode")]
|
|
public int? ResponseCode { get; init; }
|
|
|
|
[JsonPropertyName("errorMessage")]
|
|
public string? ErrorMessage { get; init; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retry delivery request.
|
|
/// </summary>
|
|
internal sealed class NotifyRetryRequest
|
|
{
|
|
[JsonPropertyName("tenant")]
|
|
public string? Tenant { get; init; }
|
|
|
|
[JsonPropertyName("deliveryId")]
|
|
public string DeliveryId { get; init; } = string.Empty;
|
|
|
|
[JsonPropertyName("idempotencyKey")]
|
|
public string? IdempotencyKey { get; init; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retry delivery result.
|
|
/// </summary>
|
|
internal sealed class NotifyRetryResult
|
|
{
|
|
[JsonPropertyName("success")]
|
|
public bool Success { get; init; }
|
|
|
|
[JsonPropertyName("deliveryId")]
|
|
public string DeliveryId { get; init; } = string.Empty;
|
|
|
|
[JsonPropertyName("newStatus")]
|
|
public string? NewStatus { get; init; }
|
|
|
|
[JsonPropertyName("errors")]
|
|
public IReadOnlyList<string>? Errors { get; init; }
|
|
|
|
[JsonPropertyName("auditEventId")]
|
|
public string? AuditEventId { get; init; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Send notification request.
|
|
/// </summary>
|
|
internal sealed class NotifySendRequest
|
|
{
|
|
[JsonPropertyName("tenant")]
|
|
public string? Tenant { get; init; }
|
|
|
|
[JsonPropertyName("channelId")]
|
|
public string? ChannelId { get; init; }
|
|
|
|
[JsonPropertyName("eventType")]
|
|
public string EventType { get; init; } = string.Empty;
|
|
|
|
[JsonPropertyName("subject")]
|
|
public string? Subject { get; init; }
|
|
|
|
[JsonPropertyName("body")]
|
|
public string Body { get; init; } = string.Empty;
|
|
|
|
[JsonPropertyName("severity")]
|
|
public string? Severity { get; init; }
|
|
|
|
[JsonPropertyName("metadata")]
|
|
public IReadOnlyDictionary<string, string>? Metadata { get; init; }
|
|
|
|
[JsonPropertyName("idempotencyKey")]
|
|
public string? IdempotencyKey { get; init; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Send notification result.
|
|
/// </summary>
|
|
internal sealed class NotifySendResult
|
|
{
|
|
[JsonPropertyName("success")]
|
|
public bool Success { get; init; }
|
|
|
|
[JsonPropertyName("eventId")]
|
|
public string? EventId { get; init; }
|
|
|
|
[JsonPropertyName("deliveryIds")]
|
|
public IReadOnlyList<string>? DeliveryIds { get; init; }
|
|
|
|
[JsonPropertyName("channelsMatched")]
|
|
public int ChannelsMatched { get; init; }
|
|
|
|
[JsonPropertyName("errors")]
|
|
public IReadOnlyList<string>? Errors { get; init; }
|
|
|
|
[JsonPropertyName("idempotencyKey")]
|
|
public string? IdempotencyKey { get; init; }
|
|
}
|