docs(plan): web-app-followups — 8 задач; спека: сценарий T10.4, решение 12 (#29)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Andrey Epifancev 2026-10-15 00:55:25 +04:00
parent 14e6e7fcf3
commit f79494d5c6
3 changed files with 1165 additions and 9 deletions

File diff suppressed because it is too large Load Diff

View File

@ -33,7 +33,9 @@ jira-hub#29 (46 пунктов, маркеры сохраняются из PR #2
`active !== null`; сообщения о файле (`file-error`, `json-applied`) по-прежнему заменяют его (одно событие, M-5 #20), а `active !== null`; сообщения о файле (`file-error`, `json-applied`) по-прежнему заменяют его (одно событие, M-5 #20), а
следующий ответ опроса возвращает строку пакета. следующий ответ опроса возвращает строку пакета.
3. **Ошибка хаба при снимке из файла (T10.4).** Событие `hub-down` получает признак `fromFile`; текст — «хаб не отвечает — 3. **Ошибка хаба при снимке из файла (T10.4).** Событие `hub-down` получает признак `fromFile`; текст — «хаб не отвечает —
на доске снимок из файла». `hasData` при JSON-снимке без данных хаба — `true` только если в модели есть задачи. на доске снимок из файла». Он ставится, когда снимок хаба не загрузился при показанном файле (перечитывание после
завершения пакета) и когда JSON-снимок загружен без данных хаба; `hasData` в последнем случае — есть ли в модели задачи.
«Перечитать» по-прежнему возвращает источник «хаб».
4. **Подхват пакета (T10.6, T10.1).** Кандидат из `GET /batches` (автор `viewer`, `queued`/`running`) проверяется запросом 4. **Подхват пакета (T10.6, T10.1).** Кандидат из `GET /batches` (автор `viewer`, `queued`/`running`) проверяется запросом
`GET /batches/{id}`: подхватывается, только если первая команда — `refresh`. Подхват не запускается по обновлению `GET /batches/{id}`: подхватывается, только если первая команда — `refresh`. Подхват не запускается по обновлению
снимка, которое вызвал сам `finish()` (флаг «снимок после своего пакета»), — без лишнего `GET /batches` (T10.1). снимка, которое вызвал сам `finish()` (флаг «снимок после своего пакета»), — без лишнего `GET /batches` (T10.1).
@ -52,9 +54,10 @@ jira-hub#29 (46 пунктов, маркеры сохраняются из PR #2
`font/woff2`. Версии — точные, `npm install --before=2026-10-01 --save-exact`. `font/woff2`. Версии — точные, `npm install --before=2026-10-01 --save-exact`.
11. **source-map-js (O-1).** `overrides: {"source-map-js": "1.2.2"}` в `package.json`, проверка `npm audit` (0 high) 11. **source-map-js (O-1).** `overrides: {"source-map-js": "1.2.2"}` в `package.json`, проверка `npm audit` (0 high)
и сборка; если 1.2.2 не закрывает уязвимость — O-1 rejected с текстом аудита. и сборка; если 1.2.2 не закрывает уязвимость — O-1 rejected с текстом аудита.
12. **Эталоны (T5.1).** В фикстуру `hub-basic` добавляются задачи с длинной темой и узкие/низкие сохранённые раскладки, чтобы 12. **Эталоны (T5.1).** `layout.clamp` — число строк заголовка при ручной высоте карточки; «unset» — у карточек с
`layout.clamp` давал не только «unset»; эталоны перегенерируются `npm run golden` из `links.html@3931a88`. автоматической высотой. В `scenarios.json` добавляется сценарий `saved-short` с сохранённой раскладкой четырёх карточек
Остальные эталоны не меняются. разной высоты (120, 136, 200, 320), эталоны перегенерируются `npm run golden` из `links.html@3931a88`; прежние
сценарии и фикстура `hub-basic.board.json` не меняются.
13. **e2e (T15.4, T15.6).** Порт тестового хаба — одна константа в `web/e2e/hub.ts` и `playwright.config.ts` берёт её же; 13. **e2e (T15.4, T15.6).** Порт тестового хаба — одна константа в `web/e2e/hub.ts` и `playwright.config.ts` берёт её же;
`scripts/test-hub.sh` перед стартом проверяет, что порт свободен, и выходит с понятной ошибкой. Готовность — e2e `scripts/test-hub.sh` перед стартом проверяет, что порт свободен, и выходит с понятной ошибкой. Готовность — e2e
проходит 10 раз подряд. проходит 10 раз подряд.
@ -94,7 +97,7 @@ jira-hub#29 (46 пунктов, маркеры сохраняются из PR #2
| T14.2 | ожидания через `waitFor`/`expect.poll` вместо пауз 20 мс | задачи и карточка | | T14.2 | ожидания через `waitFor`/`expect.poll` вместо пауз 20 мс | задачи и карточка |
| T14.3 | уникальный id `datalist` (`useId`) | задачи и карточка | | T14.3 | уникальный id `datalist` (`useId`) | задачи и карточка |
| T2.1 | `canon.ts` — сравнение по кодам символов | модель, хранилище, эталоны | | T2.1 | `canon.ts` — сравнение по кодам символов | модель, хранилище, эталоны |
| T5.1 | фикстуры для `layout.clamp` (решение 12) | модель, хранилище, эталоны | | T5.1 | сценарий `saved-short` для `layout.clamp` (решение 12) | модель, хранилище, эталоны |
| T6.3 | прямые тесты `util.ts` | модель, хранилище, эталоны | | T6.3 | прямые тесты `util.ts` | модель, хранилище, эталоны |
| T7.1 | `initialWho` считает `whoItems` один раз | модель, хранилище, эталоны | | T7.1 | `initialWho` считает `whoItems` один раз | модель, хранилище, эталоны |
| T9.1 | `colWidths()` пропускает только конечные числа | модель, хранилище, эталоны | | T9.1 | `colWidths()` пропускает только конечные числа | модель, хранилище, эталоны |
@ -136,6 +139,7 @@ jira-hub#29 (46 пунктов, маркеры сохраняются из PR #2
- **R-5 (решение 11), 15.10.2026.** O-1 закрывается `overrides`, а не обновлением прямых зависимостей. Обоснование: - **R-5 (решение 11), 15.10.2026.** O-1 закрывается `overrides`, а не обновлением прямых зависимостей. Обоснование:
уязвимость только в транзитивной dev-зависимости; обновление vite/vitest шире задачи. Цена: `overrides` надо снять, когда уязвимость только в транзитивной dev-зависимости; обновление vite/vitest шире задачи. Цена: `overrides` надо снять, когда
прямые зависимости подтянут 1.2.2 сами. прямые зависимости подтянут 1.2.2 сами.
- **R-6 (решение 12), 15.10.2026.** T5.1 закрывается расширением фикстуры `hub-basic`, а не новой фикстурой. Цена: - **R-6 (решение 12), 15.10.2026.** T5.1 закрывается новым сценарием `saved-short` с ручными высотами, а не новыми
перегенерация большого `hub-basic.expected.json`. задачами в фикстуре: обрезку заголовка в генераторе определяет только ручная высота (заглушка DOM меряет все карточки
одинаково). Цена: длинные темы на реальной вёрстке проверяет e2e, не эталон.
- **R-7 (M-5), 15.10.2026.** M-5 rejected — показано владельцу в сводке понимания до утверждения разделов, возражений не было. - **R-7 (M-5), 15.10.2026.** M-5 rejected — показано владельцу в сводке понимания до утверждения разделов, возражений не было.

View File

@ -101,8 +101,9 @@ SHALL проверять агента (`GET /agent`; офлайн — преду
- **THEN** шапка по-прежнему показывает «пакет #N выполняется» - **THEN** шапка по-прежнему показывает «пакет #N выполняется»
#### Scenario: Хаб недоступен при снимке из файла #### Scenario: Хаб недоступен при снимке из файла
- **WHEN** на доске снимок из CSV, нажато «Перечитать», хаб не ответил - **WHEN** хаб не отвечает и загружен JSON-снимок доски, либо на доске снимок из CSV и хаб не ответил на перечитывание
- **THEN** шапка показывает «хаб не отвечает — на доске снимок из файла» снимка после завершения пакета
- **THEN** шапка показывает «хаб не отвечает — на доске снимок из файла», а не «показаны прежние данные»
#### Scenario: Чужой пакет не подхватывается #### Scenario: Чужой пакет не подхватывается
- **WHEN** незавершённый пакет автора `viewer` состоит из команд `ensure_fields` - **WHEN** незавершённый пакет автора `viewer` состоит из команд `ensure_fields`