diff --git a/backend/src/PnvPanel.Application/Configs/VpnConfigDto.cs b/backend/src/PnvPanel.Application/Configs/VpnConfigDto.cs
index f6233be..aaa8053 100644
--- a/backend/src/PnvPanel.Application/Configs/VpnConfigDto.cs
+++ b/backend/src/PnvPanel.Application/Configs/VpnConfigDto.cs
@@ -5,13 +5,15 @@ namespace PnvPanel.Application.Configs;
///
/// Пользователю показываем только DisplayName + протокол инбаунда — адрес/хост ноды и прочие
-/// детали 3x-ui в этот DTO не попадают (см. domain-model.md).
+/// детали 3x-ui в этот DTO не попадают (см. domain-model.md). Исключение — ClientEmail: это не
+/// секрет и не адрес ноды, а просто ключ клиента в 3x-ui, полезный владельцу для диагностики
+/// (сверка конфига с записью в панели у админа).
///
public sealed record VpnConfigDto(
- Guid Id, string? Label, VpnProtocol Protocol, string Location,
+ Guid Id, string? Label, string ClientEmail, VpnProtocol Protocol, string Location,
long UsedUpBytes, long UsedDownBytes, DateTimeOffset? ExpiresAt, ConfigStatus Status, DateTimeOffset CreatedAt)
{
public static VpnConfigDto FromDomain(VpnConfig config, Inbound inbound) => new(
- config.Id, config.Label, config.Protocol, inbound.DisplayName ?? inbound.Remark,
+ config.Id, config.Label, config.ClientEmail, config.Protocol, inbound.DisplayName ?? inbound.Remark,
config.UsedUpBytes, config.UsedDownBytes, config.ExpiresAt, config.Status, config.CreatedAt);
}
diff --git a/frontend/src/features/configs/ConfigCard.tsx b/frontend/src/features/configs/ConfigCard.tsx
index d7a63a8..e2a1908 100644
--- a/frontend/src/features/configs/ConfigCard.tsx
+++ b/frontend/src/features/configs/ConfigCard.tsx
@@ -80,6 +80,9 @@ export function ConfigCard({ config }: { config: VpnConfigDto }) {
↑ {formatBytes(config.usedUpBytes)} ↓ {formatBytes(config.usedDownBytes)}
+
+ {t('configs.panelEmail', { email: config.clientEmail })}
+