164 lines
5.9 KiB
C#
164 lines
5.9 KiB
C#
namespace IronServices.Client;
|
|
|
|
/// <summary>
|
|
/// API client for IronLicensing operations.
|
|
/// Access via IronServicesClient.Licensing
|
|
/// </summary>
|
|
public class LicensingApi
|
|
{
|
|
private readonly IronServicesClient _client;
|
|
private readonly string _baseUrl;
|
|
|
|
internal LicensingApi(IronServicesClient client, string baseUrl)
|
|
{
|
|
_client = client;
|
|
_baseUrl = baseUrl;
|
|
}
|
|
|
|
private string Url(string endpoint) => IronServicesClient.BuildUrl(_baseUrl, endpoint);
|
|
|
|
/// <summary>
|
|
/// Get dashboard statistics.
|
|
/// </summary>
|
|
public async Task<LicensingDashboardStats> GetDashboardStatsAsync(CancellationToken ct = default)
|
|
{
|
|
return await _client.GetAsync<LicensingDashboardStats>(Url("api/v1/dashboard/stats"), ct)
|
|
?? new LicensingDashboardStats();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get recent activity from audit logs.
|
|
/// </summary>
|
|
public async Task<List<ActivityItem>> GetRecentActivityAsync(int limit = 50, CancellationToken ct = default)
|
|
{
|
|
return await _client.GetAsync<List<ActivityItem>>(Url($"api/v1/admin/audit?limit={limit}"), ct) ?? [];
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get licenses with optional filtering.
|
|
/// </summary>
|
|
public async Task<List<LicenseDto>> GetLicensesAsync(string? status = null, Guid? productId = null, int page = 1, int limit = 50, CancellationToken ct = default)
|
|
{
|
|
var query = new List<string> { $"page={page}", $"limit={limit}" };
|
|
if (!string.IsNullOrEmpty(status)) query.Add($"status={status}");
|
|
if (productId.HasValue) query.Add($"productId={productId}");
|
|
var queryString = "?" + string.Join("&", query);
|
|
|
|
return await _client.GetAsync<List<LicenseDto>>(Url($"api/v1/admin/licenses{queryString}"), ct) ?? [];
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get a specific license by ID.
|
|
/// </summary>
|
|
public async Task<LicenseDto?> GetLicenseAsync(Guid id, CancellationToken ct = default)
|
|
{
|
|
return await _client.GetAsync<LicenseDto>(Url($"api/v1/admin/licenses/{id}"), ct);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Create a new license.
|
|
/// </summary>
|
|
public async Task<LicenseDto?> CreateLicenseAsync(CreateLicenseRequest request, CancellationToken ct = default)
|
|
{
|
|
return await _client.PostAsync<CreateLicenseRequest, LicenseDto>(Url("api/v1/admin/licenses"), request, ct);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Suspend a license.
|
|
/// </summary>
|
|
public async Task<LicenseDto?> SuspendLicenseAsync(Guid id, string? reason = null, CancellationToken ct = default)
|
|
{
|
|
return await _client.PostAsync<object, LicenseDto>(Url($"api/v1/admin/licenses/{id}/suspend"), new { reason }, ct);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Revoke a license.
|
|
/// </summary>
|
|
public async Task<LicenseDto?> RevokeLicenseAsync(Guid id, string? reason = null, CancellationToken ct = default)
|
|
{
|
|
return await _client.PostAsync<object, LicenseDto>(Url($"api/v1/admin/licenses/{id}/revoke"), new { reason }, ct);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Reactivate a suspended license.
|
|
/// </summary>
|
|
public async Task<LicenseDto?> ReactivateLicenseAsync(Guid id, CancellationToken ct = default)
|
|
{
|
|
return await _client.PostAsync<object, LicenseDto>(Url($"api/v1/admin/licenses/{id}/reactivate"), new { }, ct);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Resend activation email for a license.
|
|
/// </summary>
|
|
public async Task ResendActivationEmailAsync(Guid id, CancellationToken ct = default)
|
|
{
|
|
await _client.PostAsync<object, object>(Url($"api/v1/admin/licenses/{id}/resend-activation"), new { }, ct);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Update user profile.
|
|
/// </summary>
|
|
public async Task UpdateProfileAsync(UpdateProfileRequest request, CancellationToken ct = default)
|
|
{
|
|
await _client.PutAsync<UpdateProfileRequest, object>(Url("api/v1/profile"), request, ct);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get tickets with optional status filter.
|
|
/// </summary>
|
|
public async Task<List<TicketDto>> GetTicketsAsync(string? status = null, CancellationToken ct = default)
|
|
{
|
|
var query = !string.IsNullOrEmpty(status) ? $"?status={status}" : "";
|
|
return await _client.GetAsync<List<TicketDto>>(Url($"api/v1/tickets{query}"), ct) ?? [];
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get a specific ticket with messages.
|
|
/// </summary>
|
|
public async Task<TicketDetailDto?> GetTicketAsync(Guid id, CancellationToken ct = default)
|
|
{
|
|
return await _client.GetAsync<TicketDetailDto>(Url($"api/v1/tickets/{id}"), ct);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Create a new ticket.
|
|
/// </summary>
|
|
public async Task<TicketDto?> CreateTicketAsync(string subject, string message, string? category = null, CancellationToken ct = default)
|
|
{
|
|
return await _client.PostAsync<object, TicketDto>(Url("api/v1/tickets"), new { subject, message, category }, ct);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Reply to a ticket.
|
|
/// </summary>
|
|
public async Task<TicketMessageDto?> ReplyToTicketAsync(Guid ticketId, string content, CancellationToken ct = default)
|
|
{
|
|
return await _client.PostAsync<object, TicketMessageDto>(Url($"api/v1/tickets/{ticketId}/messages"), new { content }, ct);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Close a ticket.
|
|
/// </summary>
|
|
public async Task<TicketDto?> CloseTicketAsync(Guid id, CancellationToken ct = default)
|
|
{
|
|
return await _client.PostAsync<object, TicketDto>(Url($"api/v1/tickets/{id}/close"), new { }, ct);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Reopen a closed ticket.
|
|
/// </summary>
|
|
public async Task<TicketDto?> ReopenTicketAsync(Guid id, CancellationToken ct = default)
|
|
{
|
|
return await _client.PostAsync<object, TicketDto>(Url($"api/v1/tickets/{id}/reopen"), new { }, ct);
|
|
}
|
|
}
|
|
|
|
public class CreateLicenseRequest
|
|
{
|
|
public Guid ProductId { get; set; }
|
|
public string? Email { get; set; }
|
|
public string? TierId { get; set; }
|
|
public int? MaxActivations { get; set; }
|
|
public DateTime? ExpiresAt { get; set; }
|
|
}
|