Enhance user plan management and update related endpoints
CI / Backend (build + test) (push) Failing after 1m23s
CI / Frontend (lint + typecheck + build) (push) Successful in 34s

- Added new configuration options for user plans in `.env.example`, including `Plans__MaxCustomConfigCount` and `Plans__MinCustomConfigCount`.
- Introduced `MapPlanEndpoints` in `Program.cs` to handle plan-related API routes.
- Implemented `SetUserPlan` endpoint in `RoleEndpoints` to allow admins to assign plans to users.
- Removed deprecated role request approval endpoints from `AdminSupportEndpoints`.
- Updated `ITelegramNotifier` and related classes to reflect changes in role request handling and payment notifications.
- Refactored role management commands to remove `MaxConfigs` and focus on `MaxIpLimit` and billing settings.
- Enhanced billing request handling to accommodate plan changes instead of role changes.
- Updated various interfaces and command handlers to support new plan management features.
This commit is contained in:
Leonid Pershin
2026-07-23 22:52:20 +03:00
parent 2c5b730500
commit fad03c2834
152 changed files with 4060 additions and 2240 deletions
@@ -11,7 +11,7 @@ public class ConfigQuotaTests(PnvPanelWebApplicationFactory factory)
private const int Quota = 2;
private const int ConcurrentAttempts = 6;
private sealed record RoleResponse(Guid Id, string Name, int MaxConfigs, bool IsSystem);
private sealed record RoleResponse(Guid Id, string Name, bool IsSystem);
private sealed record NodeResponse(Guid Id, string Name);
@@ -33,7 +33,7 @@ public class ConfigQuotaTests(PnvPanelWebApplicationFactory factory)
DateTimeOffset CreatedAt
);
private sealed record MyConfigsResponse(List<object> Configs, int MaxConfigs);
private sealed record MyConfigsResponse(List<object> Configs, int ConfigQuota);
/// <summary>
/// Доказывает, что pg_advisory_xact_lock в CreateVpnConfigCommandHandler реально защищает
@@ -54,7 +54,7 @@ public class ConfigQuotaTests(PnvPanelWebApplicationFactory factory)
var updateRoleResponse = await adminClient.SendPutJsonAsync(
$"/api/admin/roles/{userRole.Id}",
new { maxConfigs = Quota, maxIpLimit = -1 }
new { maxIpLimit = -1, billingEnabled = false }
);
Assert.Equal(HttpStatusCode.OK, updateRoleResponse.StatusCode);
@@ -109,6 +109,13 @@ public class ConfigQuotaTests(PnvPanelWebApplicationFactory factory)
);
Assert.Equal(HttpStatusCode.NoContent, approveResponse.StatusCode);
// Квота конфигов больше не на роли — пользователь сам выбирает тариф (см. ChangePlanCommand).
var changePlanResponse = await userClient.PostJsonAsync(
"/api/plans/change",
new { customConfigCount = Quota, configIdsToRevoke = Array.Empty<Guid>() }
);
Assert.Equal(HttpStatusCode.OK, changePlanResponse.StatusCode);
var tasks = Enumerable
.Range(0, ConcurrentAttempts)
.Select(async i =>