Доска связей на живых данных хаба (viewer-live, #17) #18

Merged
aep merged 11 commits from feat/17-viewer-live into main 2026-10-14 17:29:06 +03:00
Owner

Closes #17.

Что сделано

  • GET /board (клиентский токен) — снимок зеркала в одной транзакции чтения: все задачи с fact_status/work_kind, все связи {source, target, link_type}, last_sync — последний успешный полный прогон (mirror.board).
  • GET /, GET /links без токена — страница доски связей src/jira_hub/web/links.html (статический файл без данных, Cache-Control: no-cache; не-JSON ответ api.Raw).
  • Страница — развитие «Спринт 2 линк» (первый коммит c35151b — копия как есть, дальше правки читаются диффом):
    • вход по клиентскому токену (localStorage["jira-hub-token"]), форма при первом входе и после 401, проверка допустимых символов;
    • доска из GET /board: эпики — дорожки, соседи — обычные карточки, срок — плановая дата окончания, вид работы — метки kind-*; неизвестные типы связей и связи с эпиками пропускаются, ключи вне зеркала — дорожка «Нет в зеркале»;
    • «Перечитать»; «Обновить из Jira» — POST /refresh {full, author: "viewer"} и опрос пакета раз в 3 с, предупреждение «агент офлайн», текст ошибки пакета, возобновление опроса после перезагрузки;
    • импорт JSON при работе с хабом переносит только раскладку, дорожки и фильтры; CSV — снимок «(из файла)» до «Перечитать»; «⋯ → Сменить токен хаба»;
    • встроенная выгрузка от 11.10.2026 удалена.
  • README (раздел «Доска связей», таблица API), ARCHITECTURE, CLAUDE.md.

Проверка

  • uv run pytest -q — 211 passed (было 206).
  • Скрипт страницы — node --check.
  • Playwright на тестовом хабе с учебным агентом: первый вход, токен с пробелом/кириллицей, неверный и устаревший токен, доска и заглушки, тема с HTML-разметкой (показана текстом), «Перечитать», остановленный хаб (доска остаётся / пустая доска с причиной), CSV, «Обновить из Jira» (пакет viewer, одна команда refresh по базовой JQL), агент офлайн, перезагрузка во время пакета, ошибка агента, хаб остановлен посреди опроса, токен пересоздан посреди опроса, перенос раскладки JSON-ом старой страницы, JSON при недоступном хабе, смена токена, светлая/тёмная тема, ширина 900 px.
  • Копия живой базы (токены пересозданы, реле и автообновление выключены): 182 задачи без эпиков, 29 связей из 30 (Cloners отброшена), спринт по умолчанию — 36 задач, импорт JSON старой страницы применил раскладку. Копия удалена.
  • Финальное ревью ветки (opus): Critical нет; I-1 исправлена.

Rulings I made

Спека и план (design.md, «Decisions made without discussion»):

  • R-1 (design #2) GET /board — сырые данные зеркала, перевод в модель доски — на странице. Цена: лишний перевод на клиенте.
  • R-2 (design #3) «Данные на» — последний полный прогон, обновления по ключам не учитываются. Цена: время может быть старше изменений отдельных задач.
  • R-3 (design #5) Пакет обновления — автор viewer, опрос раз в 3 с. Цена: нет.
  • R-4 (design #6) Соседи — обычные карточки, заглушки только для ключей вне зеркала. Цена: соседей без спринта скрывает фильтр спринта.
  • R-5 (design #8) Встроенная выгрузка удалена. Цена: без хаба доска пуста до загрузки файла.
  • R-6 (design #3) last_sync — только прогон с командой done. Цена: нет.
  • R-7 (design #5) После перезагрузки опрос незавершённого пакета viewer возобновляется. Цена: лишний запрос при открытии.
  • R-8 (design #6) Связи с эпиками не показываются. Цена: связь задачи с эпиком не видна на доске.
  • R-9 (design #7) Импорт JSON при недоступном хабе — снимок из файла; при 401 — форма входа. Цена: нет.
  • R-10 (design #1) <!doctype html> и <html lang="ru">. Цена: возможны мелкие отличия вёрстки (проверено скриншотами).
  • R-11 (design #4) «Сменить токен хаба»; токен проверяется на печатные ASCII. Цена: нет.
  • R-12 (design #7) «(из файла)» для CSV и JSON; «заменить…» → «файл…». Цена: нет.
  • R-13 (design #5) Неудачное «Перечитать» оставляет доску и предупреждает. Цена: можно не заметить, что данные не обновились.

Исполнение:

  • R-14 (design #4) Текст 401: «Токен не подошёл. Проверьте его по uv run jira-hub tokens: токен могли пересоздать.» Цена: нет.
  • R-15 (design #1) favicon data:, (хаб отвечал 404) и .bar>span:empty{display:none}. Цена: нет.
  • R-16 (design #8) Пустая доска: «Нет данных: <причина>. Запустите хаб…» (было «Хаб не отвечает (хаб не отвечает)»). Цена: нет.
  • R-17 (design #7) Импорт JSON при недоступном хабе: «хаб не отвечает — показан снимок из <файл>». Цена: нет.
  • R-18 (design #5) Строка состояния хаба переносится на узком окне. Цена: нет.
  • R-19 (design #7) Подсказка экспорта JSON ссылается на «файл…». Цена: нет.
  • R-20 (design #6) Связи из зеркала — только между ключами KEY_RE (I-1). Цена: связь с нестандартным ключом не видна на доске.
  • Проверочный стенд (не код): учебный агент нумерует прогоны по id команды; пустая доска без хаба проверена перехватом /board в Playwright (file: в Playwright MCP запрещён); «агент офлайн» проверялся после истечения долгого claim остановленного агента; JSON старой страницы получен её exportJson() с локального http.server.
  • Declined to judge ревьюера (confirmed_by_state у refresh, 0.0.0.0 без TLS, Google Fonts, словари стр��ницы vs настройки хаба, work_kind не используется, /board без Cache-Control) — по спеке или вне change, без исправлений.

Находки

Маркер Находка Статус
I-1 ключи связей из зеркала без KEY_RE попадали в innerHTML (разметка исполнялась на странице с токеном) fixed c7d1aaa
M-1 поздний ответ loadHub затирает показанный снимок CSV/JSON deferred
M-2 «Обновить из Jira» снова включается, пока /agent+/refresh в пути; двойной опрос одного пакета deferred
M-3 R-7 срабатывает только при первой удачной загрузке, не после «Перечитать» deferred
M-4 опрос бесконечен при постоянном 404/500 от /batches/{id} deferred
M-5 сообщения: «выполнен» затирает «прежние данные»; JSON — «хаб не отвечает» на любую ошибку; исключение в fromHub оставляет «Загрузка…» deferred
M-6 форма входа: видны кнопки хаба с устаревшим токеном; шаг опроса с 401 стирает набираемый токен deferred
M-7 ветка own=False в mirror.board без теста deferred
O-1 Playwright MCP запрещает file:; скриншоты с относительным путём пишутся в корень workspace rejected: инструменты, обойдено
O-2 долгий claim остановленного агента ещё до 30 с обновляет last_seen_at и может взять команду — её довыдаст следующий claim rejected: поведение довыдачи по спеке bridge-reliability

После merge

git pull в jira-hub, launchctl kickstart -k gui/$(id -u)/ru.aepif.jira-hub, открыть http://127.0.0.1:8790/, ввести клиентский токен, «Обновить из Jira» с живым агентом, импорт JSON из старой страницы.

🤖 Generated with Claude Code

Closes #17. ## Что сделано - `GET /board` (клиентский токен) — снимок зеркала в одной транзакции чтения: все задачи с `fact_status`/`work_kind`, все связи `{source, target, link_type}`, `last_sync` — последний успешный полный прогон (`mirror.board`). - `GET /`, `GET /links` без токена — страница доски связей `src/jira_hub/web/links.html` (статический файл без данных, `Cache-Control: no-cache`; не-JSON ответ `api.Raw`). - Страница — развитие «Спринт 2 линк» (первый коммит c35151b — копия как есть, дальше правки читаются диффом): - вход по клиентскому токену (`localStorage["jira-hub-token"]`), форма при первом входе и после 401, проверка допустимых символов; - доска из `GET /board`: эпики — дорожки, соседи — обычные карточки, срок — плановая дата окончания, вид работы — метки `kind-*`; неизвестные типы связей и связи с эпиками пропускаются, ключи вне зеркала — дорожка «Нет в зеркале»; - «Перечитать»; «Обновить из Jira» — `POST /refresh {full, author: "viewer"}` и опрос пакета раз в 3 с, предупреждение «агент офлайн», текст ошибки пакета, возобновление опроса после перезагрузки; - импорт JSON при работе с хабом переносит только раскладку, дорожки и фильтры; CSV — снимок «(из файла)» до «Перечитать»; «⋯ → Сменить токен хаба»; - встроенная выгрузка от 11.10.2026 удалена. - README (раздел «Доска связей», таблица API), ARCHITECTURE, CLAUDE.md. ## Проверка - `uv run pytest -q` — 211 passed (было 206). - Скрипт страницы — `node --check`. - Playwright на тестовом хабе с учебным агентом: первый вход, токен с пробелом/кириллицей, неверный и устаревший токен, доска и заглушки, тема с HTML-разметкой (показана текстом), «Перечитать», остановленный хаб (доска остаётся / пустая доска с причиной), CSV, «Обновить из Jira» (пакет `viewer`, одна команда `refresh` по базовой JQL), агент офлайн, перезагрузка во время пакета, ошибка агента, хаб остановлен посреди опроса, токен пересоздан посреди опроса, перенос раскладки JSON-ом старой страницы, JSON при недоступном хабе, смена токена, светлая/тёмная тема, ширина 900 px. - Копия живой базы (токены пересозданы, реле и автообновление выключены): 182 задачи без эпиков, 29 связей из 30 (`Cloners` отброшена), спринт по умолчанию — 36 задач, импорт JSON старой страницы применил раскладку. Копия удалена. - Финальное ревью ветки (opus): Critical нет; I-1 исправлена. ## Rulings I made Спека и план (design.md, «Decisions made without discussion»): - R-1 (design #2) `GET /board` — сырые данные зеркала, перевод в модель доски — на странице. Цена: лишний перевод на клиенте. - R-2 (design #3) «Данные на» — последний полный прогон, обновления по ключам не учитываются. Цена: время может быть старше изменений отдельных задач. - R-3 (design #5) Пакет обновления — автор `viewer`, опрос раз в 3 с. Цена: нет. - R-4 (design #6) Соседи — обычные карточки, заглушки только для ключей вне зеркала. Цена: соседей без спринта скрывает фильтр спринта. - R-5 (design #8) Встроенная выгрузка удалена. Цена: без хаба доска пуста до загрузки файла. - R-6 (design #3) `last_sync` — только прогон с командой `done`. Цена: нет. - R-7 (design #5) После перезагрузки опрос незавершённого пакета `viewer` возобновляется. Цена: лишний запрос при открытии. - R-8 (design #6) Связи с эпиками не показываются. Цена: связь задачи с эпиком не видна на доске. - R-9 (design #7) Импорт JSON при недоступном хабе — снимок из файла; при 401 — форма входа. Цена: нет. - R-10 (design #1) `<!doctype html>` и `<html lang="ru">`. Цена: возможны мелкие отличия вёрстки (проверено скриншотами). - R-11 (design #4) «Сменить токен хаба»; токен проверяется на печатные ASCII. Цена: нет. - R-12 (design #7) «(из файла)» для CSV и JSON; «заменить…» → «файл…». Цена: нет. - R-13 (design #5) Неудачное «Перечитать» оставляет доску и предупреждает. Цена: можно не заметить, что данные не обновились. Исполнение: - R-14 (design #4) Текст 401: «Токен не подошёл. Проверьте его по uv run jira-hub tokens: токен могли пересоздать.» Цена: нет. - R-15 (design #1) favicon `data:,` (хаб отвечал 404) и `.bar>span:empty{display:none}`. Цена: нет. - R-16 (design #8) Пустая доска: «Нет данных: <причина>. Запустите хаб…» (было «Хаб не отвечает (хаб не отвечает)»). Цена: нет. - R-17 (design #7) Импорт JSON при недоступном хабе: «хаб не отвечает — показан снимок из <файл>». Цена: нет. - R-18 (design #5) Строка состояния хаба переносится на узком окне. Цена: нет. - R-19 (design #7) Подсказка экспорта JSON ссылается на «файл…». Цена: нет. - R-20 (design #6) Связи из зеркала — только между ключами `KEY_RE` (I-1). Цена: связь с нестандартным ключом не видна на доске. - Проверочный стенд (не код): учебный агент нумерует прогоны по id команды; пустая доска без хаба проверена перехватом `/board` в Playwright (file: в Playwright MCP запрещён); «агент офлайн» проверялся после истечения долгого claim остановленного агента; JSON старой страницы получен её `exportJson()` с локального http.server. - Declined to judge ревьюера (`confirmed_by_state` у refresh, 0.0.0.0 без TLS, Google Fonts, словари стр��ницы vs настройки хаба, `work_kind` не используется, `/board` без Cache-Control) — по спеке или вне change, без исправлений. ## Находки | Маркер | Находка | Статус | |---|---|---| | I-1 | ключи связей из зеркала без `KEY_RE` попадали в `innerHTML` (разметка исполнялась на странице с токеном) | fixed c7d1aaa | | M-1 | поздний ответ `loadHub` затирает показанный снимок CSV/JSON | deferred | | M-2 | «Обновить из Jira» снова включается, пока `/agent`+`/refresh` в пути; двойной опрос одного пакета | deferred | | M-3 | R-7 срабатывает только при первой удачной загрузке, не после «Перечитать» | deferred | | M-4 | опрос бесконечен при постоянном 404/500 от `/batches/{id}` | deferred | | M-5 | сообщения: «выполнен» затирает «прежние данные»; JSON — «хаб не отвечает» на любую ошибку; исключение в `fromHub` оставляет «Загрузка…» | deferred | | M-6 | форма входа: видны кнопки хаба с устаревшим токеном; шаг опроса с 401 стирает набираемый токен | deferred | | M-7 | ветка `own=False` в `mirror.board` без теста | deferred | | O-1 | Playwright MCP запрещает `file:`; скриншоты с относительным путём пишутся в корень workspace | rejected: инструменты, обойдено | | O-2 | долгий `claim` остановленного агента ещё до 30 с обновляет `last_seen_at` и может взять команду — её довыдаст следующий claim | rejected: поведение довыдачи по спеке bridge-reliability | ## После merge `git pull` в `jira-hub`, `launchctl kickstart -k gui/$(id -u)/ru.aepif.jira-hub`, открыть `http://127.0.0.1:8790/`, ввести клиентский токен, «Обновить из Jira» с живым агентом, импорт JSON из старой страницы. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
aep added 11 commits 2026-10-14 17:23:55 +03:00
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Копия admin/sprint-2-links.html от 11.10.2026 без правок, чтобы дальнейшие изменения читались диффом.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Встроенная выгрузка от 11.10.2026 удалена; CSV и JSON — загрузка файла.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Ключ из issue_link попадал в разметку карточки без проверки: строка зеркала с разметкой в target_key исполнялась на странице с токеном.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
aep merged commit fdc07b42af into main 2026-10-14 17:29:06 +03:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: aep/sdlc-hub#18
No description provided.