Files
harbor-net/docs/goals/windows-client-three-panel-ui/PLAN.md

33 KiB
Raw Blame History

План реализации трехпанельного интерфейса Windows Client

Intent: Перестроить текущий монолитный экран Windows-клиента в три переключаемые панели: read-only сводка, настройки ProxiFyre и настройки VPN/прокси. Current Behavior: Сейчас apps/windows-client/src/app/App.tsx смешивает статус ProxiFyre, выбор маршрута, Local sing-box, список приложений, применение конфига и журнал событий на одном экране. Пользователь сразу видит все управляющие элементы, поэтому главная страница не отделяет состояние системы от действий. Expected Outcome: Пользователь открывает приложение и сначала видит чистую сводку без редактирования. Управление ProxiFyre, список приложений и диагностика компонента находятся во второй панели. Выбор локального или внешнего прокси, подписка, серверы, ping и генерация VPN/proxy-конфига находятся в третьей панели. Target-Perspective Output: Пользователь может за 5-10 секунд понять, работает ли система, запущен ли ProxiFyre, какой маршрут применен, локальный он или внешний, и какой файл конфига активен. Затем пользователь переключается во вкладку ProxiFyre для сервисных действий и списка приложений либо во вкладку VPN/Прокси для выбора маршрута и проверки соединения. Truth Owner: Rust/Tauri команды и JSON-файлы под C:\ProgramData\VpnProxy остаются источником правды. React хранит только состояние текущей вкладки, черновики полей, loading/error/success состояния и производные view model для отображения. Contract Boundary: UI вызывает существующие typed Tauri commands из apps/windows-client/src/api/tauriCommands.ts. Rust владеет профилями, targets, компонентами, local-singbox config/cache, generated config и применением ProxiFyre. Новые UI-панели не должны писать напрямую в derived/generated артефакты. Cutover: Текущий единый экран в App.tsx заменяется shell-layout с тремя вкладками. Существующие функции загрузки, установки, запуска, выбора сервера, ping, apply и notifications переиспользуются, но раскладываются по панелям. Displaced Path: Убирается доминирующий путь "все настройки на одной странице". Сводка не дублирует формы и кнопки apply; она только отображает состояние и ведет пользователя к нужной панели. Value Density: Самый ценный срез: верхняя навигация по трем панелям плюс read-only сводка, которая корректно собирает текущее состояние из уже загружаемых данных. После этого переносим существующие настройки без изменения backend-контракта. Evidence Gate: Приемка требует не только npm run build, но и доказательство глазами пользователя: скриншоты/состояния всех трех панелей, read-only поведение сводки, dirty/apply состояние на вкладках настроек, responsive-проверка. Acceptance Evidence: npm run build проходит; при необходимости Rust tests проходят для нового ping/target DTO; в EVIDENCE.md записаны скриншоты или browser/Tauri state для трех панелей, а также проверка, что сводка не содержит изменяющих controls. Evidence Lane: Доказательства исполнения будут фиксироваться в docs/goals/windows-client-three-panel-ui/EVIDENCE.md. Kill Criteria: Нет input/button apply на сводке; нет второго источника состояния маршрута; нет скрытой установки компонентов при открытии вкладок; нет изменения root src/web или root src/server; нет расхождения терминов ProxiFyre / Local sing-box / внешний прокси. Architecture Slice: Изменения сосредоточены в apps/windows-client/src/app/App.tsx, apps/windows-client/src/styles/app.css, при необходимости apps/windows-client/src/api/tauriCommands.ts, apps/windows-client/src/domain/types.ts, apps/windows-client/src-tauri/src/commands.rs и связанных tests для проверки внешнего target ping. Plan Review Gate: Требуется PRE review перед исполнением.

Краткий дизайн-brief

Продукт: Windows desktop utility для маршрутизации выбранных приложений через ProxiFyre и внешний или локальный proxy path.

Визуальный источник: текущий темный utilitarian-стиль apps/windows-client/src/styles/app.css: компактные панели, 4px radius, статусные точки, lucide icons, сдержанные borders, без landing/hero.

Интерактивность: полная. Вкладки, меню, установка/запуск/остановка, добавление приложений, выбор маршрута, подписка, выбор сервера, ping, генерация и apply должны работать через реальные текущие команды.

Архитектурный срез

Файлы для создания:

  • docs/goals/windows-client-three-panel-ui/PLAN.md
  • docs/goals/windows-client-three-panel-ui/GOAL.md
  • docs/goals/windows-client-three-panel-ui/EVIDENCE.md

Файлы для изменения:

  • apps/windows-client/src/app/App.tsx
  • apps/windows-client/src/styles/app.css
  • apps/windows-client/src/api/tauriCommands.ts, только если понадобится новый внешний proxy ping command.
  • apps/windows-client/src/domain/types.ts, только если понадобится новый DTO для внешнего proxy ping.
  • apps/windows-client/src-tauri/src/commands.rs, только если понадобится новый внешний proxy ping command.
  • apps/windows-client/src-tauri/src/main.rs, только для регистрации нового command.
  • apps/windows-client/src-tauri/tests/*, только для нового command или сохранения существующих контрактов.
  • docs/goals/windows-client-three-panel-ui/EVIDENCE.md, при исполнении.

Файлы, которых не касаться:

  • src/web/*
  • src/server/*
  • Docker/compose/entrypoint файлы.
  • Installer scripts, если UI-разрез не требует изменения install boundary.
  • Старые goal packages, кроме ссылок в evidence при необходимости.

Источник правды:

  • C:\ProgramData\VpnProxy\config\profiles.json
  • C:\ProgramData\VpnProxy\config\targets.json
  • C:\ProgramData\VpnProxy\config\components.json
  • C:\ProgramData\VpnProxy\config\local-singbox.json
  • C:\ProgramData\VpnProxy\state\singbox-subscription-cache.json
  • C:\ProgramData\VpnProxy\state\activity.json

Производные артефакты:

  • C:\ProgramData\VpnProxy\generated\proxifyre-app-config.json
  • C:\ProgramData\VpnProxy\generated\sing-box-config.json

Путь чтения:

  • React вызывает get_saved_state, get_components, get_proxifyre_setup_status, get_singbox_status, get_singbox_setup_status.
  • Summary panel строит производную view model из уже загруженных profiles, targets, components, setupStatus, singBoxStatus, generatedConfigPath, serverPings и hasUnappliedChanges.
  • ProxiFyre panel читает proxyfier, setupStatus, items, loadedProfiles, generatedConfigPath.
  • VPN/Proxy panel читает routeMode, proxyInput, singBoxStatus, singBoxSetupStatus, serverPings, selected server и target.

Путь записи:

  • ProxiFyre panel пишет только через существующие handlers: install/start/stop/uninstall ProxiFyre, add/remove app items, updateConfig.
  • VPN/Proxy panel пишет только через route/subscription/server/config handlers: changeRouteMode, changeProxyInput, saveSingBoxSubscription, fetchSingBoxSubscription, forgetSingBoxSubscription, selectSingBoxServer, ping*, generateSingBoxConfig, service actions, updateConfig.
  • Summary panel не пишет ничего, кроме глобального non-mutating refresh, если refresh остается в header.

Граница контракта:

  • App.tsx отвечает за orchestration и view composition.
  • Typed Tauri command wrappers отвечают за API shape.
  • Rust commands отвечают за validation, persistence, service/check actions и generated config.
  • CSS отвечает за layout, tab transitions, loading skeletons, menu/popover transitions и responsive behavior.

Точки интеграции:

  • routeMode === 'external' показывает внешний/глобальный proxy target.
  • routeMode === 'local-singbox' показывает Local sing-box path.
  • hasUnappliedChanges остается общим индикатором для вкладок настроек.
  • log-dock остается глобальным и не привязывается к одной вкладке.

Миграция и переключение:

  • Сначала добавить activePanel и shell-вкладки без изменения бизнес-логики.
  • Затем перенести JSX блоки в три render-функции или локальные компоненты в том же файле.
  • После стабилизации можно вынести панели в отдельные файлы, но только если это уменьшит размер App.tsx без изменения контрактов.

Гейт приемочных доказательств:

  • Доказательство должно показать каждую панель отдельно.
  • Должно быть видно, что summary read-only.
  • Должно быть видно, что actions доступны на вкладках настроек.
  • Должно быть видно, что mobile layout не ломает tab bar, app list, server list и bottom log dock.

Детальное описание интерфейса

Общая оболочка

Верхняя часть экрана остается компактной, но становится навигационной:

  • слева: VPN Proxy и заголовок Прокси для приложений;
  • справа: кнопка Обновить, которая запускает текущий refresh;
  • под заголовком: segmented tabs из трех пунктов: Сводка, ProxiFyre, VPN / Прокси.

Поведение вкладок:

  • активная вкладка имеет более яркий border/background и status underline;
  • при клике меняется только activePanel, данные не перезагружаются автоматически;
  • переход между панелями: fade + легкий slide по Y на 6-8px, длительность 140-180ms;
  • при prefers-reduced-motion: reduce transition отключается;
  • keyboard support: tabs работают как buttons с aria-pressed или role="tablist"/role="tab"/role="tabpanel.

Глобальные состояния:

  • isLoading показывает skeleton в содержимом активной панели;
  • isDetectingComponents показывает проверку компонентов без блокировки переключения вкладок;
  • log-dock остается закрепленным снизу и продолжает показывать success/error/info;
  • dirty/apply bar появляется только на вкладках ProxiFyre и VPN / Прокси, не на read-only сводке.

Панель 1: Сводка

Назначение: главная read-only страница, которая отвечает на вопрос "что сейчас происходит с системой".

Содержимое:

  • Статус системы: одно агрегированное состояние Работает, Требует внимания, Не настроено, Проверяю.
  • ProxiFyre: установлен/не установлен, запущен/остановлен, путь или первая проблема.
  • Подключение: корректность текущего маршрута: ProxiFyre running, выбран target, для Local sing-box выбран сервер и служба запущена, для внешнего proxy валиден host/port и есть последний результат ping/check, если он уже запускался.
  • Маршрут: Локальный прокси или Внешний прокси; рядом человекочитаемый endpoint: 127.0.0.1:1080, LAN адрес Local sing-box или внешний host:port.
  • Активный сервер: selected Local sing-box server tag, если применим; иначе не используется.
  • Приложения в профиле: количество настроенных process/folder/exe items.
  • Примененный конфиг: путь generatedConfigPath для ProxiFyre и, если есть, singBoxStatus.generatedConfigPath.
  • Состояние изменений: Все применено или Есть непримененные изменения, но без кнопки apply.
  • Последнее событие: последний элемент logEntries или activity, если он уже доступен на клиенте.

Визуально:

  • это не форма, а read-only dashboard;
  • вместо input используются value rows: label слева, value справа, status dot рядом;
  • важные значения не спрятаны в tooltip;
  • длинные пути переносятся через overflow-wrap: anywhere;
  • при широкой ширине блоки идут сеткой 2-3 колонки, на узком экране складываются в один столбец.

Действия при нажатии:

  • клик по строке ProxiFyre переключает на вкладку ProxiFyre;
  • клик по строке Маршрут или Активный сервер переключает на вкладку VPN / Прокси;
  • клик по Приложения в профиле переключает на вкладку ProxiFyre и фокусирует список приложений;
  • никаких input, add/remove, install/start/stop, apply или clear на этой панели нет.

Анимации:

  • при refresh status rows показывают мягкий shimmer/skeleton;
  • status dot для Проверяю использует текущий spinner pattern;
  • при смене агрегированного статуса value row подсвечивается на 400-600ms через background flash;
  • предупреждение Есть непримененные изменения может слегка проявляться fade-in, но без кнопки.

Панель 2: ProxiFyre

Назначение: диагностика и настройка того, что относится именно к ProxiFyre и маршрутизируемым приложениям.

Содержимое:

  • главный статус ProxiFyre: найден/не найден, запущен/остановлен, path/problem;
  • setup/modules list из setupStatus.items: binary/service/install folder/config capability и все, что возвращает backend;
  • service controls: install, start, stop, uninstall через меню MoreHorizontal;
  • Список приложений: настроенные process/folder/exe items, сгруппированные или помеченные типом;
  • счетчик приложений и отдельные пустые состояния для "ничего не настроено";
  • generated ProxiFyre config path;
  • dirty/apply state для изменений списка приложений.

Визуально:

  • верхний status block сохраняет текущий finder-card pattern, status-light и animated border glow;
  • modules list разворачивается внутри панели через Состав ProxiFyre / Что будет установлено;
  • список приложений становится основной частью панели, а не хвостом общей страницы;
  • app rows имеют icon по типу: process, exe, folder;
  • add-toolbar остается с icon buttons: process, exe, folder, с tooltip/title.

Действия при нажатии:

  • Установить: вызывает текущий installProxiFyrePackage, показывает loading на кнопке и animated border;
  • Запустить/Остановить: вызывает setProxiFyreServiceRunning, блокирует повторный клик на время action;
  • Еще открывает popover с Удалить ProxiFyre; uninstall сохраняет текущий confirm boundary;
  • Состав ProxiFyre: раскрывает/скрывает setup details;
  • Добавить процесс: открывает inline input, Enter добавляет, Escape закрывает;
  • Добавить EXE: открывает file picker через Tauri dialog;
  • Добавить папку: открывает directory picker;
  • Удалить у app row удаляет item и выставляет hasUnappliedChanges;
  • Применить в ProxiFyre: валидирует items и текущий route, затем вызывает updateConfig;
  • Открыть конфиг: открывает generated config location, если эта кнопка остается в ProxiFyre panel.

Анимации:

  • поиск/установка/запуск используют существующий moving border glow;
  • раскрытие modules list: height/opacity transition 160-220ms;
  • добавление app row: fade/slide-in;
  • удаление app row: быстрый opacity collapse, если реализация не усложнит state;
  • dirty bar появляется slide-up/fade-in над command row;
  • меню Еще: fade + scale 0.98 -> 1.

Панель 3: VPN / Прокси

Назначение: выбор маршрута и настройка самого proxy/VPN path.

Содержимое:

  • segmented control Внешний прокси / Локальный прокси;
  • для Внешний прокси: input адреса socks5://host:port или host:port, validation hint, кнопка проверки доступности;
  • для Локальный прокси: Local sing-box status, install/start/stop/uninstall, setup details, локальный и LAN endpoint, selected server, generated sing-box config path;
  • subscription input: paste URL/link, load/update, clear;
  • server list из singBoxStatus.cache.servers;
  • ping controls: Ping все, per-server ping action, отображение latency/error рядом с server row;
  • generate sing-box config action;
  • route preview: Выбранные приложения -> ProxiFyre -> внешний proxy или Выбранные приложения -> ProxiFyre -> Local sing-box -> selected server;
  • dirty/apply state для route/proxy/subscription/server changes.

Визуально:

  • mode switch остается заметным вверху панели;
  • внешний proxy block не должен выглядеть менее важным, потому что это полноценный route path;
  • Local sing-box block визуально похож на ProxiFyre status block, но расположен только в VPN/Proxy panel;
  • server list может оставаться grid, но row должен показывать selected dot, server name и ping badge;
  • для плохого ping row получает amber/red border, для хорошего ping зеленый badge;
  • route preview оформляется как read-only line/flow, без декоративной схемы.

Действия при нажатии:

  • Внешний прокси: меняет routeMode на external, выставляет dirty state;
  • ввод адреса proxy: обновляет proxyInput, выставляет dirty state, frontend validation показывает ошибки до apply;
  • Проверить: парсит внешний proxy и вызывает новый или переиспользованный backend TCP connect check; результат сохраняется в UI state и отображается на этой панели и в summary;
  • Локальный прокси: меняет routeMode на local-singbox, выставляет dirty state;
  • Установить Local sing-box: вызывает текущий install handler;
  • Запустить/Остановить: вызывает текущий service handler;
  • Состав Local sing-box: раскрывает setup details;
  • Подробности: показывает локальный endpoint, LAN, server, binary path, config path;
  • Загрузить/Обновить подписку: вызывает текущий subscription flow;
  • Очистить: вызывает forget flow, очищает server pings и selected server;
  • click по server row: вызывает selectSingBoxServer, выставляет dirty state;
  • Ping все: вызывает pingAllSingBoxServers;
  • per-server ping: вызывает существующий pingSingBoxServer(tag), если добавляем кнопку/иконку в row;
  • Конфиг: вызывает generateSingBoxConfig;
  • Применить маршрут: вызывает общий updateConfig.

Анимации:

  • mode switch меняет активный segment без скачка высоты;
  • при смене mode panel content cross-fade;
  • ping badge показывает loading spinner только на проверяемых row;
  • server row после ping обновляет latency с короткой подсветкой;
  • subscription/server empty state появляется fade-in;
  • generated config success подсвечивает config path на 400-600ms.

Задачи исполнения

Задача 1: Ввести shell вкладок и производные view models

Разрешенные файлы:

  • apps/windows-client/src/app/App.tsx
  • apps/windows-client/src/styles/app.css

Ожидаемый результат:

  • activePanel: 'summary' | 'proxifyre' | 'proxy'.
  • Общий header с tab control.
  • Производные функции для summary: system status, route label, endpoint label, config labels, app count, issue list.
  • Старые JSX-блоки временно остаются, но render path начинает разделяться.

Проверка:

  • cd apps/windows-client && npm run build

Приемочные доказательства:

  • Screenshot/state показывает три tab buttons и корректную активную вкладку.

Параллельное выполнение: нет, общий App.tsx.

Задача 2: Реализовать read-only панель Сводка

Разрешенные файлы:

  • apps/windows-client/src/app/App.tsx
  • apps/windows-client/src/styles/app.css

Ожидаемый результат:

  • Summary panel без input/apply/install/start/stop/delete.
  • Статус системы, ProxiFyre, подключение, маршрут, активный server, apps count, config paths, dirty state.
  • Навигационные клики по read-only строкам переводят на соответствующие вкладки.

Проверка:

  • cd apps/windows-client && npm run build
  • Manual DOM/visual check: на summary нет изменяющих controls.

Приемочные доказательства:

  • Screenshot summary panel.
  • Запись в evidence: какие элементы read-only и куда ведут navigation clicks.

Параллельное выполнение: нет.

Задача 3: Перенести ProxiFyre и список приложений во вторую панель

Разрешенные файлы:

  • apps/windows-client/src/app/App.tsx
  • apps/windows-client/src/styles/app.css

Ожидаемый результат:

  • ProxiFyre panel содержит status card, setup details, service actions, app add/remove, generated config path и apply/open config actions.
  • Существующие handlers переиспользованы без изменения backend ownership.
  • hasUnappliedChanges продолжает работать после add/remove.

Проверка:

  • cd apps/windows-client && npm run build

Приемочные доказательства:

  • Screenshot ProxiFyre panel с service status и apps list.
  • Проверка add/remove вызывает dirty state.

Параллельное выполнение: нет.

Задача 4: Перенести VPN/Proxy route settings в третью панель

Разрешенные файлы:

  • apps/windows-client/src/app/App.tsx
  • apps/windows-client/src/styles/app.css
  • apps/windows-client/src/api/tauriCommands.ts, если нужен внешний target ping.
  • apps/windows-client/src/domain/types.ts, если нужен внешний target ping DTO.

Ожидаемый результат:

  • VPN/Proxy panel содержит route mode switch, external proxy editor, Local sing-box controls, subscription, server selection, ping, generate config, route preview и apply.
  • Внешний proxy path не зависит от Local sing-box.
  • Local sing-box UI не показывается на summary и не смешивается с ProxiFyre panel.

Проверка:

  • cd apps/windows-client && npm run build

Приемочные доказательства:

  • Screenshot external proxy mode.
  • Screenshot local proxy mode с server list или empty state.

Параллельное выполнение: нет.

Задача 5: Добавить или переиспользовать проверку доступности внешнего proxy target

Разрешенные файлы:

  • apps/windows-client/src-tauri/src/commands.rs
  • apps/windows-client/src-tauri/src/main.rs
  • apps/windows-client/src/api/tauriCommands.ts
  • apps/windows-client/src/domain/types.ts
  • apps/windows-client/src-tauri/tests/command_tests.rs или отдельный focused test.

Ожидаемый результат:

  • Если существующих данных недостаточно для "все ли окей с подключением" во внешнем proxy mode, добавить typed command наподобие ping_proxy_target.
  • Command делает TCP connect check к host/port с timeout, возвращает { ok, latency, error }.
  • UI отображает результат в VPN/Proxy panel и summary.
  • Это не заменяет apply и не пишет source config.

Проверка:

  • cd apps/windows-client/src-tauri && cargo test command
  • cd apps/windows-client && npm run build

Приемочные доказательства:

  • Test или manual state показывает успешный/ошибочный result shape.

Параллельное выполнение: частично, если UI DTO names согласованы заранее; интеграция не parallel-safe.

Задача 6: Привести CSS, анимации и responsive behavior

Разрешенные файлы:

  • apps/windows-client/src/styles/app.css
  • apps/windows-client/src/app/App.tsx, только className/ARIA adjustments.

Ожидаемый результат:

  • Tab bar, panel transitions, setup expand/collapse, ping badges, dirty/apply bar и responsive grids.
  • Нет перекрытия текста, длинные paths/servers переносятся.
  • Mobile layout: tabs не ломаются, server list минимум 2 колонки или 1 колонка на очень узком экране, command row складывается.
  • prefers-reduced-motion отключает декоративные transitions.

Проверка:

  • cd apps/windows-client && npm run build
  • Browser/Tauri visual check на desktop и узком viewport.

Приемочные доказательства:

  • Screenshots desktop + narrow viewport.

Параллельное выполнение: нет, потому что зависит от финальной разметки.

Задача 7: Финальная проверка и evidence

Разрешенные файлы:

  • docs/goals/windows-client-three-panel-ui/EVIDENCE.md
  • При необходимости apps/windows-client/README.md, если нужно зафиксировать новую навигацию.

Ожидаемый результат:

  • Evidence содержит commands, результаты build/tests, screenshots/state checks и список остаточных рисков.
  • Если Tauri service actions не проверялись на реальной Windows elevated среде, это явно помечено как implemented but unproven только для service lane.

Проверка:

  • git status --short
  • cd apps/windows-client && npm run build
  • cd apps/windows-client/src-tauri && cargo test, если Rust command менялся.

Приемочные доказательства:

  • Summary read-only verified.
  • ProxiFyre actions verified.
  • VPN/Proxy route switch and ping states verified.
  • No root web/server changes.

Параллельное выполнение: нет.

Prompt для PRE review

Использовать C:\Users\PC\.agents\skills\krypton-planning\plan-reviewer-prompt.md со следующими данными:

Файл плана:

  • docs/goals/windows-client-three-panel-ui/PLAN.md

Исходный запрос:

  • Разбить Windows client UI на три переключаемые панели: общая read-only сводка, настройки ProxiFyre, настройки VPN/proxy; подробно описать внешний вид, анимации и действия.

Контракт результата:

  • Пользователь сначала видит статус системы и примененный route/config без изменения данных, затем переходит в нужную панель для ProxiFyre или VPN/proxy действий.

Архитектурный срез:

  • Основной scope: apps/windows-client/src/app/App.tsx и apps/windows-client/src/styles/app.css; backend только для внешнего target ping, если текущих команд недостаточно.

Требование к приемочным доказательствам:

  • Build/tests плюс screenshots/state proof трех панелей и read-only summary.

Известные non-goals:

  • Не менять root src/web/src/server.
  • Не переписывать Tauri backend без нужды.
  • Не добавлять скрытую установку компонентов.
  • Не делать summary редактируемой.

Опасные пути или слои:

  • Дублирование source of truth в React.
  • Изменение generated config напрямую.
  • Смешивание Local sing-box controls обратно в ProxiFyre panel.
  • Потеря external proxy path как полноценного режима.