Категория: feature · Приоритет: high · Размер: XL · Ранг: 1/10
Что построить
Поле «Лимит трафика (ГБ)» (0 = без лимита) в форме создания/редактирования пользователя; колонка «использовано / лимит» с прогресс-баром и процентом в таблице; кнопка «Сбросить трафик» в меню действий строки. Бэкенд хранит лимит на пользователе и прокидывает его в 3x-ui при провижининге.
Паритет с конкурентами
Marzban/Marzneshin (data_limit + used_traffic), 3x-ui (ClientTraffic.totalGB + resetClientTraffic), Remnawave и Hiddify — у всех квота трафика с живым учётом. Базовый биллинговый примитив.
Чего не хватает сейчас (код)
entity.ClientSpec несёт только ID/Email/Flow/SubID, а add_client.go жёстко шлёт totalGB:0 — квота никогда не задаётся. Фронт (users_get) уже показывает Up/Down из кэша флита (fleet/build.go суммирует cs.Up/cs.Down, берёт max cs.Total), но Total не редактируется, нет прогресс-бара, нет принудительного отключения при исчерпании и нет сброса. xui-клиент умеет только ListInbounds/AddClient/DelClient — нет UpdateClient и resetClientTraffic.
Зачем
Операторы продают планы с фиксированной квотой (напр. 50 ГБ/мес) и требуют жёсткого ограничения плюс сброса в один клик без пересоздания клиента. Это самый важный недостающий продуктовый примитив — на его данных стоят бары, предупреждения и автоотключение.
Предлагаемая реализация
Расширить entity.ClientSpec полем TotalGB, убрать хардкод в add_client.go (брать из спеки). Колонка total_bytes в users (миграция) + поле в UserCreateParams/UserEditParams; provisioning прокидывает в AddClient. Учёт расхода уже доступен — вынести used/total/percent в users_get-ответ, нарисовать бар во Vue SPA. Для сброса — новый метод xui-клиента ResetClientTraffic (один файл reset_client_traffic.go + httptest-тест), сервисный метод ResetUsage, ручка user_reset_traffic (openapi → ogen → handler). Энфорсмент исчерпания — через флаг enable (опирается на #89).
Затронутые файлы
internal/entity/panel.go (ClientSpec.TotalGB), internal/entity/user.go
internal/clients/xui/add_client.go, reset_client_traffic.go (новый) + тест, contract.go
internal/service/provisioning/service.go, migrations/NNNN-user-traffic-limit.sql
openapi/{user_create,user_edit,user_reset_traffic}.yaml, internal/handlers/{users_get,user_reset_traffic}/
internal/handlers/web/static/{app.js,index.html,app.css}
Продуктовый ресёрч: изучены аналоги (Marzban/Marzneshin, 3x-ui, Remnawave, Hiddify, sub-store + клиентские стандарты импорта). Паритет и subgen-gap код-обоснованы. Ранг = продуктовый приоритет.
Категория: feature · Приоритет: high · Размер: XL · Ранг: 1/10
Что построить
Поле «Лимит трафика (ГБ)» (0 = без лимита) в форме создания/редактирования пользователя; колонка «использовано / лимит» с прогресс-баром и процентом в таблице; кнопка «Сбросить трафик» в меню действий строки. Бэкенд хранит лимит на пользователе и прокидывает его в 3x-ui при провижининге.
Паритет с конкурентами
Marzban/Marzneshin (
data_limit+used_traffic), 3x-ui (ClientTraffic.totalGB+resetClientTraffic), Remnawave и Hiddify — у всех квота трафика с живым учётом. Базовый биллинговый примитив.Чего не хватает сейчас (код)
entity.ClientSpecнесёт толькоID/Email/Flow/SubID, аadd_client.goжёстко шлётtotalGB:0— квота никогда не задаётся. Фронт (users_get) уже показывает Up/Down из кэша флита (fleet/build.goсуммируетcs.Up/cs.Down, берёт maxcs.Total), ноTotalне редактируется, нет прогресс-бара, нет принудительного отключения при исчерпании и нет сброса. xui-клиент умеет толькоListInbounds/AddClient/DelClient— нетUpdateClientиresetClientTraffic.Зачем
Операторы продают планы с фиксированной квотой (напр. 50 ГБ/мес) и требуют жёсткого ограничения плюс сброса в один клик без пересоздания клиента. Это самый важный недостающий продуктовый примитив — на его данных стоят бары, предупреждения и автоотключение.
Предлагаемая реализация
Расширить
entity.ClientSpecполемTotalGB, убрать хардкод вadd_client.go(брать из спеки). Колонкаtotal_bytesвusers(миграция) + поле вUserCreateParams/UserEditParams; provisioning прокидывает вAddClient. Учёт расхода уже доступен — вынести used/total/percent вusers_get-ответ, нарисовать бар во Vue SPA. Для сброса — новый метод xui-клиентаResetClientTraffic(один файлreset_client_traffic.go+ httptest-тест), сервисный методResetUsage, ручкаuser_reset_traffic(openapi → ogen → handler). Энфорсмент исчерпания — через флаг enable (опирается на #89).Затронутые файлы
internal/entity/panel.go(ClientSpec.TotalGB),internal/entity/user.gointernal/clients/xui/add_client.go,reset_client_traffic.go(новый) + тест,contract.gointernal/service/provisioning/service.go,migrations/NNNN-user-traffic-limit.sqlopenapi/{user_create,user_edit,user_reset_traffic}.yaml,internal/handlers/{users_get,user_reset_traffic}/internal/handlers/web/static/{app.js,index.html,app.css}Продуктовый ресёрч: изучены аналоги (Marzban/Marzneshin, 3x-ui, Remnawave, Hiddify, sub-store + клиентские стандарты импорта). Паритет и subgen-gap код-обоснованы. Ранг = продуктовый приоритет.