using Sonex.Data.Database; using Sonex.Data.Messages; namespace Sonex.Data.Records; public sealed class ActiveSessionRecord { public const string MessageAction = "message"; public const string LogoutAction = "logout"; public const string CloseAction = "close"; public string? FirstName { get; set; } public string? LastName { get; set; } public string AccountName { get; set; } = string.Empty; public string? Department { get; set; } public string? State { get; set; } public string? ApplicationName { get; set; } public string? DatabaseName { get; set; } public string? ClientAddr { get; set; } public int? ClientPort { get; set; } public int? Pid { get; set; } public string? ApplicationVersion => GetApplicationNamePart(1); public string? InstanceId => GetApplicationNamePart(2); public string? OsVersion => GetApplicationNamePart(3); public Task SendMessage(string title, string text, CancellationToken ct = default) { var instanceId = GetRequiredInstanceId(); return string.IsNullOrWhiteSpace(instanceId) ? Task.CompletedTask : SendMessage(title, text, instanceId, ct); } public Task SendLogout(CancellationToken ct = default) { var instanceId = GetRequiredInstanceId(); return string.IsNullOrWhiteSpace(instanceId) ? Task.CompletedTask : SendLogout(instanceId, ct); } public Task SendClose(CancellationToken ct = default) { var instanceId = GetRequiredInstanceId(); return string.IsNullOrWhiteSpace(instanceId) ? Task.CompletedTask : SendClose(instanceId, ct); } public static Task SendMessage(string title, string text, string instanceId, CancellationToken ct = default) { return SendAsync(instanceId, MessageAction, title, text, ct); } public static Task SendLogout(string instanceId, CancellationToken ct = default) { return SendAsync(instanceId, LogoutAction, "Logout", "Logout", ct); } public static Task SendClose(string instanceId, CancellationToken ct = default) { return SendAsync(instanceId, CloseAction, "Close", "Close", ct); } public static Task> GetAll() { return DB.QueryListAsync( """ SELECT first_name, last_name, account_name, department, state, application_name, database_name, client_addr::text AS client_addr, client_port, pid FROM sonex.v_active_sessions; """); } public string? GetRequiredInstanceId() { return Normalize(InstanceId); } private string? GetApplicationNamePart(int index) { if (string.IsNullOrWhiteSpace(ApplicationName)) return null; var parts = ApplicationName.Split('|', StringSplitOptions.TrimEntries); return parts.Length > index && !string.IsNullOrWhiteSpace(parts[index]) ? Normalize(parts[index]) : null; } private static Task SendAsync( string instanceId, string action, string? title = null, string? text = null, CancellationToken ct = default) { ArgumentException.ThrowIfNullOrWhiteSpace(instanceId); ArgumentException.ThrowIfNullOrWhiteSpace(action); return DB.Notifications.NotifyInstanceAsync( instanceId.Trim(), new Message { Action = action.Trim().ToLowerInvariant(), Title = Normalize(title), Text = Normalize(text) }, ct); } private static string? Normalize(string? value) { return string.IsNullOrWhiteSpace(value) ? null : value.Trim(); } }