using PnvPanel.Application.Common.Models; namespace PnvPanel.Application.Common.Interfaces; public sealed record AuthenticatedUser(Guid Id, string UserName, string Role); public sealed record CurrentUserProfile( Guid Id, string UserName, Guid RoleId, string Role, bool IsActivated, bool IsBlocked, int MaxConfigs, int MaxIpLimit, string SubscriptionToken); public sealed record UserSummaryDto(Guid Id, string UserName, string Role, bool IsActivated, bool IsBlocked, DateTimeOffset? ActivatedAt); public sealed record UserStatsDto(int Total, int Activated); public sealed record TelegramLinkInfo(bool IsLinked, long? TelegramUserId, string? Username); public interface IIdentityService { Task> CreateUserAsync(string userName, string password, CancellationToken cancellationToken); Task> ValidateCredentialsAsync(string userName, string password, CancellationToken cancellationToken); Task GetProfileAsync(Guid userId, CancellationToken cancellationToken); Task ChangePasswordAsync(Guid userId, string currentPassword, string newPassword, CancellationToken cancellationToken); Task ChangeUserNameAsync(Guid userId, string newUserName, CancellationToken cancellationToken); /// /// Помечает пользователя активированным. Изменение не коммитится немедленно (в отличие от /// CreateUserAsync/ChangePasswordAsync) — оно попадает в трекер того же DbContext и сохраняется /// вместе с изменением ActivationRequest одной транзакцией через UnitOfWorkBehavior. /// Task ActivateUserAsync(Guid userId, Guid activatedBy, CancellationToken cancellationToken); Task> GetUserNamesAsync(IReadOnlyCollection userIds, CancellationToken cancellationToken); /// Удаляет аккаунт (самоудаление). Конфиги должны быть отозваны заранее вызывающей стороной. Task DeleteUserAsync(Guid userId, CancellationToken cancellationToken); /// Для агрегированной подписки /sub/{userToken} (все активные конфиги пользователя). Task FindUserIdBySubscriptionTokenAsync(string token, CancellationToken cancellationToken); /// Блокировка: вход запрещён (см. ValidateCredentialsAsync). Конфиги гасит вызывающая сторона. Task BlockUserAsync(Guid userId, CancellationToken cancellationToken); Task UnblockUserAsync(Guid userId, CancellationToken cancellationToken); /// Сброс пароля админом — для пользователей без привязанного Telegram (M7). Task ResetPasswordAsync(Guid userId, string newPassword, CancellationToken cancellationToken); Task> ListUsersAsync(int page, int pageSize, string? search, CancellationToken cancellationToken); Task GetUserStatsAsync(CancellationToken cancellationToken); Task LinkTelegramAsync(Guid userId, long telegramUserId, string? telegramUsername, CancellationToken cancellationToken); Task UnlinkTelegramAsync(Guid userId, CancellationToken cancellationToken); Task FindUserIdByTelegramUserIdAsync(long telegramUserId, CancellationToken cancellationToken); Task GetTelegramLinkInfoAsync(Guid userId, CancellationToken cancellationToken); /// Telegram ID активных (активированных, не заблокированных) пользователей с привязкой — /// для рассылки уведомлений вроде публикации новости. Task> GetActivatedLinkedTelegramUserIdsAsync(CancellationToken cancellationToken); }