Enhance user management and node health check features
CI / Backend (build + test) (push) Failing after 2m14s
CI / Frontend (lint + typecheck + build) (push) Successful in 51s

- Updated `ListUsersQueryHandler` to include plan names and config quotas in `UserSummaryDto`, enriching user data retrieval.
- Implemented `WithPlanNamesAsync` method to fetch plan names based on user plan IDs, improving user experience in the admin interface.
- Enhanced `Node` class with a `ConsecutiveProbeFailures` property for better status management during health checks.
- Modified `NodeHealthCheckService` to utilize the new `RecordProbe` method, implementing a hysteresis mechanism for node status changes.
- Updated frontend components to display user config quotas and plan names, improving clarity in user management.
- Enhanced tests for user listing and node status handling to ensure robust functionality and coverage.
- Updated documentation to reflect changes in user and node management features.
This commit is contained in:
Leonid Pershin
2026-08-05 08:34:17 +03:00
parent c2ed3240bd
commit 4b34c37ce3
20 changed files with 1563 additions and 28 deletions
+7
View File
@@ -382,6 +382,13 @@ approve/reject над `ActivationRequest`.
отличие от `VpnConfigDto`): `{ id, userId, userName, label, clientEmail, protocol, location, nodeName,
usedUpBytes, usedDownBytes, expiresAt, status, createdAt }`. `search` матчится по `clientEmail`/`label`.
`UserSummaryDto`: `{ id, userName, role, isActivated, isBlocked, activatedAt, billingEnabled,
billingPaidUntil, configQuota, planId, billingPendingReview, planName }`. `configQuota` — фактическая
квота конфигов (`-1` = без лимита), `planName` — имя каталожного тарифа по `planId` (`null`, если
квота задана вручную); и `planName`, и `billingPendingReview` домешивает `ListUsersQueryHandler`
`IIdentityService` не знает ни про `Plans`, ни про `PaymentRequests`. Менять квоту админ может через
`PATCH /api/admin/users/{id}/plan` (см. Admin — Roles & Plans), доплата при этом не создаётся.
**Блокировка/разблокировка — два отдельных эндпоинта без тела**, не один переключатель `isBlocked`.
`StatsDto`: `{ totalUsers, activatedUsers, pendingActivationRequests, totalNodes, onlineNodes,
totalConfigs, activeConfigs, totalUsedUpBytes, totalUsedDownBytes }` — считается на лету при запросе,