Категория: feature · Приоритет: medium · Размер: XL · Ранг: 7/10
Что построить
Поле «Лимит IP/устройств» (0 = без лимита) в форме пользователя и просмотр текущих IP клиента в детальной карточке. Старт — display-only список активных IP; энфорсмент (отключение при превышении) добавляется позже поверх флага enable (#89).
Паритет с конкурентами
3x-ui (limitIp + CheckClientIpJob по access-логу Xray), Remnawave (HWID device limit по x-hwid заголовкам), Hiddify. Ограничение шеринга — флагманская анти-resale фича.
Чего не хватает сейчас (код)
add_client.go хардкодит limitIp:0; ClientSpec не несёт лимита IP. Главное: subgen вообще не читает access-логи узлов (xui-клиент знает только inbounds/clients) — нет источника текущих IP и нет цикла энфорсмента. Самый тяжёлый пункт списка.
Зачем
Один оплаченный аккаунт, расшаренный на компанию друзей, — крупнейшая утечка выручки у VPN-реселлеров; лимит IP/устройств её закрывает. Subgen сегодня не ограничивает число подключений с одного credential.
Предлагаемая реализация
Фаза 1 (display-only): новый метод xui-клиента GetClientIps (POST /panel/api/inbounds/clientIps/:email) — один файл + тест; провести limitIp как ClientSpec.LimitIp в AddClient; колонка limit_ip в users. Карточка пользователя показывает текущие IP. Фаза 2 (энфорсмент): периодический воркер сравнивает число IP с лимитом и отключает через флаг enable (#89). Чтение access-логов узла — отдельный большой кусок, в фазу 2. Поэтому в беклоге это xl, но начинается с дешёвого read-пути.
Затронутые файлы
internal/entity/panel.go (ClientSpec.LimitIp), internal/clients/xui/get_client_ips.go (новый) + тест, contract.go, add_client.go
internal/service/provisioning/service.go, migrations/NNNN-user-limit-ip.sql
openapi/{user_create,user_edit,user_ips}.yaml, internal/handlers/user_ips/, internal/handlers/web/static/
Продуктовый ресёрч: изучены аналоги (Marzban/Marzneshin, 3x-ui, Remnawave, Hiddify, sub-store + клиентские стандарты импорта). Паритет и subgen-gap код-обоснованы. Ранг = продуктовый приоритет.
Категория: feature · Приоритет: medium · Размер: XL · Ранг: 7/10
Что построить
Поле «Лимит IP/устройств» (0 = без лимита) в форме пользователя и просмотр текущих IP клиента в детальной карточке. Старт — display-only список активных IP; энфорсмент (отключение при превышении) добавляется позже поверх флага enable (#89).
Паритет с конкурентами
3x-ui (
limitIp+CheckClientIpJobпо access-логу Xray), Remnawave (HWID device limit поx-hwidзаголовкам), Hiddify. Ограничение шеринга — флагманская анти-resale фича.Чего не хватает сейчас (код)
add_client.goхардкодитlimitIp:0;ClientSpecне несёт лимита IP. Главное: subgen вообще не читает access-логи узлов (xui-клиент знает только inbounds/clients) — нет источника текущих IP и нет цикла энфорсмента. Самый тяжёлый пункт списка.Зачем
Один оплаченный аккаунт, расшаренный на компанию друзей, — крупнейшая утечка выручки у VPN-реселлеров; лимит IP/устройств её закрывает. Subgen сегодня не ограничивает число подключений с одного credential.
Предлагаемая реализация
Фаза 1 (display-only): новый метод xui-клиента
GetClientIps(POST /panel/api/inbounds/clientIps/:email) — один файл + тест; провестиlimitIpкакClientSpec.LimitIpвAddClient; колонкаlimit_ipвusers. Карточка пользователя показывает текущие IP. Фаза 2 (энфорсмент): периодический воркер сравнивает число IP с лимитом и отключает через флаг enable (#89). Чтение access-логов узла — отдельный большой кусок, в фазу 2. Поэтому в беклоге это xl, но начинается с дешёвого read-пути.Затронутые файлы
internal/entity/panel.go(ClientSpec.LimitIp),internal/clients/xui/get_client_ips.go(новый) + тест,contract.go,add_client.gointernal/service/provisioning/service.go,migrations/NNNN-user-limit-ip.sqlopenapi/{user_create,user_edit,user_ips}.yaml,internal/handlers/user_ips/,internal/handlers/web/static/Продуктовый ресёрч: изучены аналоги (Marzban/Marzneshin, 3x-ui, Remnawave, Hiddify, sub-store + клиентские стандарты импорта). Паритет и subgen-gap код-обоснованы. Ранг = продуктовый приоритет.