## 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.