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, bool BillingEnabled, DateTimeOffset? BillingPaidUntil, bool BillingSuspended ); /// Срез биллинг-полей пользователя — для фоновой джобы приостановки (см. BillingService), /// не требует полного CurrentUserProfile (роль/квоты там не нужны). public sealed record BillingUserDto( Guid UserId, DateTimeOffset? PaidUntil, bool Suspended, DateTimeOffset? LastWarnedForPaidUntil ); public sealed record UserSummaryDto( Guid Id, string UserName, string Role, bool IsActivated, bool IsBlocked, DateTimeOffset? ActivatedAt, bool BillingEnabled, DateTimeOffset? BillingPaidUntil, /// Есть Subscription-заявка на оплату в AwaitingConfirmation — конфиги не гасятся, пока /// админ не решит (см. BillingService). Заполняется в ListUsersQueryHandler (не здесь — Identity /// не должен знать про PaymentRequests), false по умолчанию для мест, не подгружающих это поле. bool BillingPendingReview = false ); 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 ); /// Все Id пользователей, кроме указанного — для полного сброса панели (сохраняется /// только текущий админ). Task> ListAllUserIdsExceptAsync( Guid exceptUserId, CancellationToken cancellationToken ); /// Пользователи с billing-ролью (role.BillingEnabled), не заблокированные — обход для /// BillingService (приостановка за неуплату / предупреждения). Task> ListBillingUsersAsync(CancellationToken cancellationToken); /// Гасит конфиги за неуплату на уровне пользователя (BillingSuspended=true) — сами /// конфиги гасит вызывающая сторона (см. BillingService, по образцу BlockUserCommandHandler). Task SuspendBillingAsync(Guid userId, CancellationToken cancellationToken); /// Продлевает оплаченный период, снимает приостановку и сбрасывает флаг "предупреждение /// отправлено" (новый срок ещё не близко к истечению). Используется и при подтверждении оплаты, /// и при первичной выдаче грейс-периода. Task ExtendBillingPaidUntilAsync( Guid userId, DateTimeOffset paidUntil, CancellationToken cancellationToken ); Task MarkBillingWarningSentAsync( Guid userId, DateTimeOffset paidUntil, CancellationToken cancellationToken ); }