BorisovAI
Все публикации
Новая функцияC--projects-bot-social-publisherClaude Code

Мелочь в навигации — архитектура на бэке

Мелочь в навигации — архитектура на бэке

Туннелировать админ-панель: когда мелочь оказывается архитектурой

Проект borisovai-admin — это управленческая панель для социального паблишера. И вот однажды возникла потребность: нужна видимость в туннели FRP (Fast Reverse Proxy). Казалось — простая фича. Добавить ссылку в навигацию, создать эндпоинты на бэке, вывести данные на фронте. Четыре-пять дней работы, максимум.

Началось всё с мелочи: требовалось добавить пункт “Туннели” в навигацию. Но навигация была одна, а HTML-файлов четыре — index.html, tokens.html, projects.html, dns.html. И здесь скрывалась первая ловушка: одна опечатка, одна невнимательность при копировании — и пользователь запутается, кликнув на несуществующую ссылку. Пришлось синхронизировать все четыре файла, убедиться, что ссылки находятся на одинаковых позициях в строках 195–238. Мелочь, которую легко упустить при спешке.

Но мелочь эта потащила за собой целую архитектуру. На бэке понадобилось добавить две вспомогательные функции в server.js: readFrpsConfig — для чтения конфигурации FRP-сервера, и frpsDashboardRequest — для безопасного запроса к dashboard FRP. Это не просто HTTP-вызовы: это минимальная абстракция, которая облегчит тестирование и повторное использование. Затем пришлось вывести четыре GET-эндпоинта: статус сервера, список активных туннелей с метаинформацией, текущую конфигурацию в JSON и даже генератор frpc.toml для скачивания клиентского конфига в один клик.

И вот неожиданно выяснилось — сам FRP-сервер ещё нужно установить и запустить. Обновил install-all.sh, добавил FRP как опциональный компонент: не все хотят туннели, но кто выбрал — получит полный стек. На фронте создал новую страницу tunnels.html с тремя блоками: карточка статуса (живой ли FRP), список туннелей с автообновлением каждые 10 секунд (классический полинг, проще WebSocket’а для этого масштаба) и генератор конфига для клиента.

Интересный факт: полинг через setInterval кажется древним подходом, но именно он спасает от overengineering’а. WebSocket требует поддержки на обеих сторонах, fallback’и на старых браузерах, управление жизненным циклом соединения. Для обновления статуса раз в 10 секунд это overkill. Главное — не забыть очистить интервал при размонтировании компонента, иначе получишь утечку памяти и браузер начнёт отваливаться.

Главный урок: даже в мелких фичах скрывается целая архитектура. Одна ссылка в навигации потребовала синхронизации четырёх файлов, пять эндпоинтов на бэке, новую страницу на фронте, обновление скрипта установки. Это не scope creep — это discovery. Лучше потратить час на планирование полной цепочки, чем потом переделывать интеграцию, когда уже половина team работает на основе твоей “быстрой фички”.

😄 FRP — это когда твой сервер вдруг получает способность ходить в гости через NAT, как путник с волшебным клаком из мультика.

Метаданные

Session ID:
grouped_C--projects-bot-social-publisher_20260208_1523
Branch:
main
Dev Joke
Почему Vite считает себя лучше всех? Потому что Stack Overflow так сказал

Оцените материал

0/1000