feat(admin): панельная идентичность под Remnawave 3.0.0

Remnawave 3.0.0 удалил `uuid` из модели пользователя — панельный аккаунт
адресуется числовым `id`, и бот переименовал соответствующие поля своего
API. Без этих правок вкладка Sync показывала бы «не привязан» у ВСЕХ
пользователей: оба операнда стали бы undefined, причём без ошибки TS —
интерфейсы продолжали бы декларировать несуществующие поля.

Типы: `UserDetailResponse.remnawave_uuid` → `remnawave_id: number | null`,
`PanelSyncStatusResponse.remnawave_uuid` → `remnawave_id`,
`SyncToPanelResponse.panel_uuid` → `panel_user_id`,
`PanelUserInfo.uuid` → `id: number` (бэкенд отдаёт его обязательным).

В SyncTab используется `??`, а не `||`: идентификатор числовой, и `0`
нужно отличать от отсутствия значения. Ярлык — «Remnawave ID».

Локаль: ключ настройки бота переименован в TRAFFIC_EXCLUDED_USER_IDS,
подпись обновлена — значения теперь числовые id, а не UUID.
This commit is contained in:
Fringg
2026-08-02 19:38:11 +03:00
parent 653d683835
commit e840ed2b60
3 changed files with 10 additions and 10 deletions

View File

@@ -142,7 +142,7 @@ export interface UserDetailResponse {
promo_offer_discount_source: string | null; promo_offer_discount_source: string | null;
promo_offer_discount_expires_at: string | null; promo_offer_discount_expires_at: string | null;
recent_transactions: UserTransactionItem[]; recent_transactions: UserTransactionItem[];
remnawave_uuid: string | null; remnawave_id: number | null;
} }
export interface UserPanelInfo { export interface UserPanelInfo {
@@ -271,7 +271,7 @@ export interface UserAvailableTariffsResponse {
// Sync types // Sync types
export interface PanelUserInfo { export interface PanelUserInfo {
uuid: string | null; id: number;
short_uuid: string | null; short_uuid: string | null;
username: string | null; username: string | null;
status: string | null; status: string | null;
@@ -295,7 +295,7 @@ export interface SyncToPanelResponse {
success: boolean; success: boolean;
message: string; message: string;
action: string; action: string;
panel_uuid: string | null; panel_user_id: number | null;
changes: Record<string, unknown>; changes: Record<string, unknown>;
errors: string[]; errors: string[];
} }
@@ -303,7 +303,7 @@ export interface SyncToPanelResponse {
export interface PanelSyncStatusResponse { export interface PanelSyncStatusResponse {
user_id: number; user_id: number;
telegram_id: number; telegram_id: number;
remnawave_uuid: string | null; remnawave_id: number | null;
subscription_id: number | null; subscription_id: number | null;
subscription_tariff_name: string | null; subscription_tariff_name: string | null;
last_sync: string | null; last_sync: string | null;

View File

@@ -151,16 +151,16 @@ export function SyncTab({
</div> </div>
)} )}
{/* UUID info */} {/* Panel identity */}
<div className="rounded-xl bg-dark-800/50 p-4"> <div className="rounded-xl bg-dark-800/50 p-4">
{syncStatus?.subscription_tariff_name && ( {syncStatus?.subscription_tariff_name && (
<div className="mb-2 text-xs text-dark-500">{syncStatus.subscription_tariff_name}</div> <div className="mb-2 text-xs text-dark-500">{syncStatus.subscription_tariff_name}</div>
)} )}
<div className="mb-1 text-sm text-dark-400">Remnawave UUID</div> <div className="mb-1 text-sm text-dark-400">Remnawave ID</div>
<div className="break-all font-mono text-sm text-dark-100"> <div className="break-all font-mono text-sm text-dark-100">
{syncStatus?.remnawave_uuid || {/* Remnawave 3.0.0 identifies a panel user by a numeric id, so 0 is not
user.remnawave_uuid || a valid id but ?? would still render it — check for null explicitly. */}
t('admin.users.detail.sync.notLinked')} {syncStatus?.remnawave_id ?? user.remnawave_id ?? t('admin.users.detail.sync.notLinked')}
</div> </div>
</div> </div>

View File

@@ -2580,7 +2580,7 @@
"Traffic Daily Check Enabled": "Ежедневная проверка", "Traffic Daily Check Enabled": "Ежедневная проверка",
"Traffic Daily Check Time": "Время проверки", "Traffic Daily Check Time": "Время проверки",
"Traffic Daily Threshold Gb": "Порог в день (ГБ)", "Traffic Daily Threshold Gb": "Порог в день (ГБ)",
"Traffic Excluded User Uuids": "Исключённые UUID", "Traffic Excluded User Ids": "Исключённые ID пользователей панели",
"Traffic Fast Check Enabled": "Быстрая проверка", "Traffic Fast Check Enabled": "Быстрая проверка",
"Traffic Fast Check Interval Minutes": "Интервал (мин)", "Traffic Fast Check Interval Minutes": "Интервал (мин)",
"Traffic Fast Check Threshold Gb": "Порог (ГБ)", "Traffic Fast Check Threshold Gb": "Порог (ГБ)",