Files
git.stella-ops.org/src/Cli/StellaOps.Cli/Services/Models/NotifyModels.cs
master d1cbb905f8
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
up
2025-11-28 18:21:46 +02:00

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; }
}