namespace IronServices.Client; /// /// API client for IronTelemetry operations. /// Access via IronServicesClient.Telemetry /// public class TelemetryApi { private readonly IronServicesClient _client; private readonly string _baseUrl; internal TelemetryApi(IronServicesClient client, string baseUrl) { _client = client; _baseUrl = baseUrl; } private string Url(string endpoint) => IronServicesClient.BuildUrl(_baseUrl, endpoint); #region Dashboard & Stats /// /// Get issue statistics (serves as dashboard stats). /// public async Task GetDashboardStatsAsync(Guid? projectId = null, CancellationToken ct = default) { var query = projectId.HasValue ? $"?projectId={projectId}" : ""; return await _client.GetAsync(Url($"api/v1/issues/stats{query}"), ct) ?? new TelemetryDashboardStats(); } #endregion #region Issues /// /// Get issues with optional filtering. /// public async Task> GetIssuesAsync(Guid? projectId = null, string? status = null, int page = 1, int pageSize = 20, CancellationToken ct = default) { var query = new List { $"page={page}", $"pageSize={pageSize}" }; if (projectId.HasValue) query.Add($"projectId={projectId}"); if (!string.IsNullOrEmpty(status)) query.Add($"status={status}"); var queryString = "?" + string.Join("&", query); var result = await _client.GetAsync(Url($"api/v1/issues{queryString}"), ct); return result?.Items ?? []; } /// /// Get a specific issue by ID. /// public async Task GetIssueAsync(Guid issueId, CancellationToken ct = default) { return await _client.GetAsync(Url($"api/v1/issues/{issueId}"), ct); } /// /// Acknowledge an issue. /// public async Task AcknowledgeIssueAsync(Guid issueId, CancellationToken ct = default) { return await _client.PostAsync(Url($"api/v1/issues/{issueId}/acknowledge"), new { }, ct); } /// /// Resolve an issue. /// public async Task ResolveIssueAsync(Guid issueId, CancellationToken ct = default) { return await _client.PostAsync(Url($"api/v1/issues/{issueId}/resolve"), new { }, ct); } /// /// Ignore an issue. /// public async Task IgnoreIssueAsync(Guid issueId, CancellationToken ct = default) { return await _client.PostAsync(Url($"api/v1/issues/{issueId}/ignore"), new { }, ct); } /// /// Update an issue's status and other properties. /// public async Task UpdateIssueAsync(Guid issueId, UpdateIssueRequest request, CancellationToken ct = default) { return await _client.PutAsync(Url($"api/v1/issues/{issueId}"), request, ct); } #endregion #region Signals /// /// Get signals (telemetry notifications). /// public async Task> GetSignalsAsync(Guid? projectId = null, int page = 1, int pageSize = 50, CancellationToken ct = default) { var query = new List { $"page={page}", $"pageSize={pageSize}" }; if (projectId.HasValue) query.Add($"projectId={projectId}"); var queryString = "?" + string.Join("&", query); var result = await _client.GetAsync(Url($"api/v1/signals{queryString}"), ct); return result?.Signals ?? []; } /// /// Get signal statistics. /// public async Task GetSignalStatsAsync(Guid? projectId = null, CancellationToken ct = default) { var query = projectId.HasValue ? $"?projectId={projectId}" : ""; return await _client.GetAsync(Url($"api/v1/signals/stats{query}"), ct); } /// /// Dismiss a signal. /// public async Task DismissSignalAsync(Guid signalId, CancellationToken ct = default) { return await _client.PostAsync(Url($"api/v1/signals/{signalId}/dismiss"), new { }, ct); } #endregion #region Projects /// /// Get all projects. /// public async Task> GetProjectsAsync(CancellationToken ct = default) { return await _client.GetAsync>(Url("api/v1/projects"), ct) ?? []; } /// /// Get a specific project by ID. /// public async Task GetProjectAsync(Guid projectId, CancellationToken ct = default) { return await _client.GetAsync(Url($"api/v1/projects/{projectId}"), ct); } /// /// Create a new telemetry project. /// public async Task CreateProjectAsync(string name, string platform = "DotNet", CancellationToken ct = default) { return await _client.PostAsync(Url("api/v1/projects"), new { name, platform }, ct); } /// /// Update a project. /// public async Task UpdateProjectAsync(Guid projectId, UpdateProjectRequest request, CancellationToken ct = default) { return await _client.PutAsync(Url($"api/v1/projects/{projectId}"), request, ct); } /// /// Regenerate project DSN. /// public async Task RegenerateDsnAsync(Guid projectId, CancellationToken ct = default) { return await _client.PostAsync(Url($"api/v1/projects/{projectId}/regenerate-dsn"), new { }, ct); } #endregion } public class IssuesListResponse { public List Items { get; set; } = []; public int Total { get; set; } public int Page { get; set; } public int PageSize { get; set; } } public class SignalListResponse { public List Signals { get; set; } = []; public int Total { get; set; } public int Page { get; set; } public int PageSize { get; set; } public int TotalPages { get; set; } } public class SignalStatsResponse { public int TotalSignals { get; set; } public int SignalsLast24Hours { get; set; } public int SignalsLast7Days { get; set; } public int SentToNotify { get; set; } public int PendingSignals { get; set; } } public class UpdateIssueRequest { public string? Status { get; set; } public string? Severity { get; set; } public Guid? AssignedToUserId { get; set; } public bool? NotifyOnRegression { get; set; } public bool? NotifyOnNewOccurrence { get; set; } } public class UpdateProjectRequest { public string? Name { get; set; } public string? Platform { get; set; } public bool? IsActive { get; set; } public bool? StackTraceGroupingEnabled { get; set; } public bool? JourneyTrackingEnabled { get; set; } public bool? SourceMapEnabled { get; set; } public int? SampleRate { get; set; } }