## Why Доска связей (`src/jira_hub/web/links.html`, change `viewer-live`) работает на живых данных хаба, но это один HTML-файл с ~900 строками императивного JS: каждая новая возможность (запись из доски — `viewer-edit`, другие экраны моста) ложится на него всё тяжелее, а гонки загрузки и опроса (jira-hub#20, M-1…M-6) вытекают из его устройства. Решение владельца 14.10.2026: завернуть хаб в нормальное веб-приложение на React, где доска — одна из страниц. Решения владельца (brainstorming 14.10.2026): - React + TypeScript + Vite; статику отдаёт сам хаб; открывают пока только на Mac mini; вход — клиентский токен в `localStorage`, как на доске; - доска переписывается на React (вариант A): логика — чистые TS-модули с golden-тестами против старой страницы, отрисовка — React-компоненты с SVG; поведение доски не расширяется, кроме действия «Открыть карточку»; - в первой версии, кроме доски, — страница «Задачи»: список зеркала с фильтрами, карточка задачи, правка служебных заметок; - приложение — под префиксом `/app/`; `/` и `/links` перенаправляют на доску; сборка не хранится в git, выкатка — `git pull`, `make web`, перезапуск; - словари видов работ и типов связей — из `GET /settings`, не дублируются в коде. ## What Changes - **Новый проект `web/`** (npm): приложение React + TS + Vite, сборка в `src/jira_hub/web/app/` (в `.gitignore`). - Оболочка: экран входа по клиентскому токену, навигация «Доска» / «Задачи», «Сменить токен». - Страница «Доска» (`/app/board`) — перенос `links.html` один в один; закрывает M-1…M-6 jira-hub#20 устройством загрузки (явный источник данных, один опрос пакета, остановка опроса на 404 и после 5 ошибок подряд, одна строка состояния, экран входа без панели доски); действие «Открыть карточку» у карточки доски. - Страница «Задачи» (`/app/issues`, `/app/issues/{key}`) — список `GET /issues` с фильтрами в адресной строке и порциями по 50, карточка `GET /issues/{key}` (поля, описание, связи, последние команды), правка заметок `PUT /issues/{key}/note`. - **jira-hub**: раздача приложения — `GET /app/assets/*` (файлы сборки), прочие `GET /app…` → `index.html`, 503 с подсказкой при отсутствии сборки, `GET /` и `GET /links` → 302 на `/app/board`; `links.html` удаляется; тест `mirror.board(own=False)` (M-7 #20). - `Makefile`: `make web` (сборка), `make check` (pytest + lint + тесты фронта). - Спеки: новая `web-app`; `hub-api` — MODIFIED «Процесс и доступ», ADDED «Раздача веб-приложения», REMOVED «Страница доски связей». ## Non-goals - Запись в Jira из интерфейса (спринт, срок, связи, исполнитель) — change `viewer-edit`. - Страницы очереди, агента и синхронизаций, настроек — позже. - Изменения API хаба для приложения (новые поля, общее количество в `GET /issues`, адрес Jira в настройках). - Изменения логики доски (граф, раскладка, критический путь, проблемы, таблица, тема), кроме «Открыть карточку». - Доступ со других машин сети, вход без токена, хранение раскладки в базе хаба. - Разбор разметки Jira в описании задачи. ## Impact - `jira-hub`: новый каталог `web/` (npm-проект), `api.py` (маршруты `/app…`, редирект `/`/`/links`, удаление `PAGE`), `src/jira_hub/web/links.html` удаляется, `.gitignore`, `Makefile`, тесты API и `mirror`, README, `ARCHITECTURE.md`, `CLAUDE.md`. - Новые зависимости — только для разработки и сборки фронта (Node 24 уже есть на Mac mini); у Python-пакета зависимостей не прибавляется. - Контракт с агентом и MCP не меняется; схема базы не меняется. - Ключи `localStorage` (`jira-hub-token`, `graph-<имя>…`) сохраняются: вход и раскладки переживают переход. - Issue: aep/jira-hub#21; закрывает jira-hub#20.