Refactor project files for improved readability and structure
CI / Backend (build + test) (push) Successful in 1m18s
CI / Frontend (lint + typecheck + build) (push) Successful in 31s

- Cleaned up whitespace in Directory.Build.props and Directory.Packages.props for consistency.
- Reformatted project file references in PnvPanel.Api.csproj for better clarity.
- Enhanced code readability in various endpoint files by adjusting line breaks and indentation.
- Standardized method signatures and improved formatting in ResultExtensions and multiple endpoint classes for better maintainability.
This commit is contained in:
Leonid Pershin
2026-07-14 07:24:13 +03:00
parent 9d5424bb9c
commit df137ca5a7
285 changed files with 6911 additions and 2063 deletions
@@ -5,10 +5,25 @@ 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);
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 UserSummaryDto(
Guid Id,
string UserName,
string Role,
bool IsActivated,
bool IsBlocked,
DateTimeOffset? ActivatedAt
);
public sealed record UserStatsDto(int Total, int Activated);
@@ -16,30 +31,57 @@ public sealed record TelegramLinkInfo(bool IsLinked, long? TelegramUserId, strin
public interface IIdentityService
{
Task<Result<Guid>> CreateUserAsync(string userName, string password, CancellationToken cancellationToken);
Task<Result<Guid>> CreateUserAsync(
string userName,
string password,
CancellationToken cancellationToken
);
Task<Result<AuthenticatedUser>> ValidateCredentialsAsync(string userName, string password, CancellationToken cancellationToken);
Task<Result<AuthenticatedUser>> ValidateCredentialsAsync(
string userName,
string password,
CancellationToken cancellationToken
);
Task<CurrentUserProfile?> GetProfileAsync(Guid userId, CancellationToken cancellationToken);
Task<Result> ChangePasswordAsync(Guid userId, string currentPassword, string newPassword, CancellationToken cancellationToken);
Task<Result> ChangePasswordAsync(
Guid userId,
string currentPassword,
string newPassword,
CancellationToken cancellationToken
);
Task<Result> ChangeUserNameAsync(Guid userId, string newUserName, CancellationToken cancellationToken);
Task<Result> ChangeUserNameAsync(
Guid userId,
string newUserName,
CancellationToken cancellationToken
);
/// <summary>
/// Помечает пользователя активированным. Изменение не коммитится немедленно (в отличие от
/// CreateUserAsync/ChangePasswordAsync) — оно попадает в трекер того же DbContext и сохраняется
/// вместе с изменением ActivationRequest одной транзакцией через UnitOfWorkBehavior.
/// </summary>
Task<Result> ActivateUserAsync(Guid userId, Guid activatedBy, CancellationToken cancellationToken);
Task<Result> ActivateUserAsync(
Guid userId,
Guid activatedBy,
CancellationToken cancellationToken
);
Task<IReadOnlyDictionary<Guid, string>> GetUserNamesAsync(IReadOnlyCollection<Guid> userIds, CancellationToken cancellationToken);
Task<IReadOnlyDictionary<Guid, string>> GetUserNamesAsync(
IReadOnlyCollection<Guid> userIds,
CancellationToken cancellationToken
);
/// <summary>Удаляет аккаунт (самоудаление). Конфиги должны быть отозваны заранее вызывающей стороной.</summary>
Task<Result> DeleteUserAsync(Guid userId, CancellationToken cancellationToken);
/// <summary>Для агрегированной подписки /sub/{userToken} (все активные конфиги пользователя).</summary>
Task<Guid?> FindUserIdBySubscriptionTokenAsync(string token, CancellationToken cancellationToken);
Task<Guid?> FindUserIdBySubscriptionTokenAsync(
string token,
CancellationToken cancellationToken
);
/// <summary>Блокировка: вход запрещён (см. ValidateCredentialsAsync). Конфиги гасит вызывающая сторона.</summary>
Task<Result> BlockUserAsync(Guid userId, CancellationToken cancellationToken);
@@ -47,21 +89,43 @@ public interface IIdentityService
Task<Result> UnblockUserAsync(Guid userId, CancellationToken cancellationToken);
/// <summary>Сброс пароля админом — для пользователей без привязанного Telegram (M7).</summary>
Task<Result> ResetPasswordAsync(Guid userId, string newPassword, CancellationToken cancellationToken);
Task<Result> ResetPasswordAsync(
Guid userId,
string newPassword,
CancellationToken cancellationToken
);
Task<PagedList<UserSummaryDto>> ListUsersAsync(int page, int pageSize, string? search, CancellationToken cancellationToken);
Task<PagedList<UserSummaryDto>> ListUsersAsync(
int page,
int pageSize,
string? search,
CancellationToken cancellationToken
);
Task<UserStatsDto> GetUserStatsAsync(CancellationToken cancellationToken);
Task<Result> LinkTelegramAsync(Guid userId, long telegramUserId, string? telegramUsername, CancellationToken cancellationToken);
Task<Result> LinkTelegramAsync(
Guid userId,
long telegramUserId,
string? telegramUsername,
CancellationToken cancellationToken
);
Task<Result> UnlinkTelegramAsync(Guid userId, CancellationToken cancellationToken);
Task<Guid?> FindUserIdByTelegramUserIdAsync(long telegramUserId, CancellationToken cancellationToken);
Task<Guid?> FindUserIdByTelegramUserIdAsync(
long telegramUserId,
CancellationToken cancellationToken
);
Task<TelegramLinkInfo> GetTelegramLinkInfoAsync(Guid userId, CancellationToken cancellationToken);
Task<TelegramLinkInfo> GetTelegramLinkInfoAsync(
Guid userId,
CancellationToken cancellationToken
);
/// <summary>Telegram ID активных (активированных, не заблокированных) пользователей с привязкой —
/// для рассылки уведомлений вроде публикации новости.</summary>
Task<IReadOnlyCollection<long>> GetActivatedLinkedTelegramUserIdsAsync(CancellationToken cancellationToken);
Task<IReadOnlyCollection<long>> GetActivatedLinkedTelegramUserIdsAsync(
CancellationToken cancellationToken
);
}