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
@@ -6,17 +6,31 @@ using PnvPanel.Domain.Configs;
namespace PnvPanel.Application.Subscriptions;
public sealed class GetConfigSubscriptionQueryHandler(IAppDbContext dbContext, IXuiPanelGateway gateway)
: IQueryHandler<GetConfigSubscriptionQuery, Result<SubscriptionDto>>
public sealed class GetConfigSubscriptionQueryHandler(
IAppDbContext dbContext,
IXuiPanelGateway gateway
) : IQueryHandler<GetConfigSubscriptionQuery, Result<SubscriptionDto>>
{
public async Task<Result<SubscriptionDto>> Handle(GetConfigSubscriptionQuery query, CancellationToken cancellationToken)
public async Task<Result<SubscriptionDto>> Handle(
GetConfigSubscriptionQuery query,
CancellationToken cancellationToken
)
{
var config = await dbContext.VpnConfigs.AsNoTracking()
.FirstOrDefaultAsync(c => c.SubscriptionToken == query.Token && c.Status == ConfigStatus.Active, cancellationToken);
var config = await dbContext
.VpnConfigs.AsNoTracking()
.FirstOrDefaultAsync(
c => c.SubscriptionToken == query.Token && c.Status == ConfigStatus.Active,
cancellationToken
);
if (config is null)
return Result.Failure<SubscriptionDto>(SubscriptionErrors.NotFound);
return await SubscriptionAssembler.BuildAsync([config], dbContext, gateway, cancellationToken);
return await SubscriptionAssembler.BuildAsync(
[config],
dbContext,
gateway,
cancellationToken
);
}
}
@@ -6,19 +6,34 @@ using PnvPanel.Domain.Configs;
namespace PnvPanel.Application.Subscriptions;
public sealed class GetUserSubscriptionQueryHandler(IAppDbContext dbContext, IIdentityService identityService, IXuiPanelGateway gateway)
: IQueryHandler<GetUserSubscriptionQuery, Result<SubscriptionDto>>
public sealed class GetUserSubscriptionQueryHandler(
IAppDbContext dbContext,
IIdentityService identityService,
IXuiPanelGateway gateway
) : IQueryHandler<GetUserSubscriptionQuery, Result<SubscriptionDto>>
{
public async Task<Result<SubscriptionDto>> Handle(GetUserSubscriptionQuery query, CancellationToken cancellationToken)
public async Task<Result<SubscriptionDto>> Handle(
GetUserSubscriptionQuery query,
CancellationToken cancellationToken
)
{
var userId = await identityService.FindUserIdBySubscriptionTokenAsync(query.Token, cancellationToken);
var userId = await identityService.FindUserIdBySubscriptionTokenAsync(
query.Token,
cancellationToken
);
if (userId is null)
return Result.Failure<SubscriptionDto>(SubscriptionErrors.NotFound);
var configs = await dbContext.VpnConfigs.AsNoTracking()
var configs = await dbContext
.VpnConfigs.AsNoTracking()
.Where(c => c.UserId == userId && c.Status == ConfigStatus.Active)
.ToListAsync(cancellationToken);
return await SubscriptionAssembler.BuildAsync(configs, dbContext, gateway, cancellationToken);
return await SubscriptionAssembler.BuildAsync(
configs,
dbContext,
gateway,
cancellationToken
);
}
}
@@ -9,7 +9,11 @@ namespace PnvPanel.Application.Subscriptions;
internal static class SubscriptionAssembler
{
public static async Task<Result<SubscriptionDto>> BuildAsync(
IReadOnlyList<VpnConfig> configs, IAppDbContext dbContext, IXuiPanelGateway gateway, CancellationToken cancellationToken)
IReadOnlyList<VpnConfig> configs,
IAppDbContext dbContext,
IXuiPanelGateway gateway,
CancellationToken cancellationToken
)
{
var lines = new List<string>();
long usedUp = 0;
@@ -18,18 +22,26 @@ internal static class SubscriptionAssembler
foreach (var config in configs)
{
var inbound = await dbContext.Inbounds.AsNoTracking()
var inbound = await dbContext
.Inbounds.AsNoTracking()
.FirstOrDefaultAsync(i => i.Id == config.InboundId, cancellationToken);
if (inbound is null)
continue;
var node = await dbContext.Nodes.AsNoTracking()
var node = await dbContext
.Nodes.AsNoTracking()
.FirstOrDefaultAsync(n => n.Id == inbound.NodeId, cancellationToken);
if (node is null || !node.IsEnabled)
continue;
var linkResult = await gateway.BuildConnectionStringAsync(
node, inbound, config.ClientExternalId, config.Label ?? config.ClientEmail, node.BaseAddress.Host, cancellationToken);
node,
inbound,
config.ClientExternalId,
config.Label ?? config.ClientEmail,
node.BaseAddress.Host,
cancellationToken
);
if (linkResult.IsSuccess)
lines.Add(linkResult.Value);
@@ -1,4 +1,8 @@
namespace PnvPanel.Application.Subscriptions;
public sealed record SubscriptionDto(
IReadOnlyList<string> ConnectionStrings, long UsedUpBytes, long UsedDownBytes, DateTimeOffset? ExpiresAt);
IReadOnlyList<string> ConnectionStrings,
long UsedUpBytes,
long UsedDownBytes,
DateTimeOffset? ExpiresAt
);
@@ -4,5 +4,8 @@ namespace PnvPanel.Application.Subscriptions;
public static class SubscriptionErrors
{
public static readonly Error NotFound = Error.NotFound("Subscription.NotFound", "Подписка не найдена.");
public static readonly Error NotFound = Error.NotFound(
"Subscription.NotFound",
"Подписка не найдена."
);
}