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 committed 2026-08-05 08:34:17 +03:00
1 parent c2ed3240bd
commit 4b34c37ce3
20 files changed
+1563 -28

No files matched your search

+6
View File
@@ -177,9 +177,15 @@ export type UserSummaryDto = {
activatedAt: string | null
billingEnabled: boolean
billingPaidUntil: string | null
/** Квота конфигов пользователя; -1 = без лимита (только admin). */
configQuota: number
/** Выбранный каталожный тариф; null — квота задана вручную. */
planId: string | null
/** Есть Subscription-заявка на оплату, ожидающая решения админа — конфиги не гасятся, пока он не
* решит (см. BillingService). Бейдж должен показывать нейтральный статус, а не тревожный "Истекло". */
billingPendingReview: boolean
/** Имя тарифа по planId; null для кастомной квоты. */
planName: string | null
}
export type RoleDto = {
+22
View File
@@ -307,6 +307,17 @@ const resources = {
giftDaysPlaceholder: 'Дней',
giftGrant: 'Подарить',
giftGranted: 'Дни подписки подарены пользователю.',
configQuota: 'Конфигов',
customQuota: 'своя квота',
unlimitedQuota: 'без лимита',
planDisabled: 'отключён',
customQuotaPlaceholder: 'Своё число конфигов',
selectPlan: 'Выбрать тариф',
planConfigCount: 'конфигов: {{count}}',
quotaCurrent: 'Сейчас: {{quota}} — {{plan}}',
applyQuota: 'Применить',
quotaChanged: 'Квота конфигов изменена.',
quotaHint: 'Смена админом — без доплаты; при понижении уже созданные конфиги не отзываются, новые не создать до входа в квоту.',
},
configs: {
searchPlaceholder: 'Поиск по email в панели или метке',
@@ -907,6 +918,17 @@ const resources = {
giftDaysPlaceholder: 'Days',
giftGrant: 'Grant',
giftGranted: 'Subscription days granted to the user.',
configQuota: 'Configs',
customQuota: 'custom quota',
unlimitedQuota: 'unlimited',
planDisabled: 'disabled',
customQuotaPlaceholder: 'Custom config count',
selectPlan: 'Select plan',
planConfigCount: 'configs: {{count}}',
quotaCurrent: 'Current: {{quota}} — {{plan}}',
applyQuota: 'Apply',
quotaChanged: 'Config quota updated.',
quotaHint: 'Admin change is free of charge; on downgrade existing configs are kept, new ones are blocked until the user is within quota.',
},
configs: {
searchPlaceholder: 'Search by panel email or label',