#region FeatureSpec [C:3] [TYPE ADR] [SEMANTICS spec,requirements,feature,task,status,monitoring] @BRIEF Feature specification — единый центр просмотра статусов всех фоновых задач superset-tools: переводы, миграции, бекапы, валидации, документация и прочие. Без привязки к реализации Python/Svelte. ## Navigation (DSA Indexer keywords) @SEMANTICS: spec, requirements, feature, task, status, monitoring, dashboard **Feature Branch**: `034-task-status-center` **Created**: 2026-06-18 | **Status**: Draft **Input**: "я хочу единый центр просмотра статусов всех задач - переводов миграций бекапов валидаций и прочих." ## Clarifications ### Session 2026-06-18 - Q: Центр статусов — новая страница или переработка существующей `/reports`? → A: Переработка `/reports` — добавляем сводную панель, real-time обновления и интеграцию с Task Drawer на существующей странице. Новый роут `/tasks` не создаётся. Старый режим «только история» остаётся доступным через фильтр. - Q: Какие задачи видит каждая роль (admin, analyst, viewer) на `/reports`? → A: Admin — все задачи всех пользователей; analyst — свои задачи + задачи без владельца (системные); viewer — только задачи, запущенные им лично. - Q: Показывать ли в сводке и списке задачи, удалённые retention-политиками? → A: Нет. Сводка и список — оперативная панель, показывающая только незаархивированные задачи. Архивные задачи исключены из выборки. ## User Scenarios Each story is an independently testable unit. Prioritized P1 (MVP) → P2 → P3. All stories share `@SEMANTICS` domain keywords from the feature header. ### Story 1 — Сводный обзор всех задач (P1) **Why P1**: Существующая страница `/reports` показывает только исторические отчёты завершённых задач. Оператору нужна сводная картина «прямо сейчас»: сколько задач выполняется, ожидает, требует ввода — без переключения между страницами. Сводная панель добавляется поверх существующего списка отчётов на `/reports`. **Independent Test**: Открыть страницу `/reports` → над списком отчётов появилась сводная панель с агрегированными счётчиками задач по статусам (pending, running, awaiting_input, success, failed) для каждого типа. **Acceptance**: 1. **Given** в системе есть задачи разных типов (миграция выполняется, перевод ожидает, бекап завершён с ошибкой) **When** оператор открывает `/reports` **Then** он видит сводную панель над списком отчётов с агрегированными счётчиками по статусам и типам задач. 2. **Given** оператор находится на `/reports` **When** запускается новая задача или меняется статус существующей **Then** сводка обновляется в реальном времени (без ручной перезагрузки страницы). 3. **Given** в системе нет ни одной задачи **When** оператор открывает `/reports` **Then** сводная панель показывает нули по всем категориям, список отчётов пуст с пояснением «Нет задач». --- ### Story 2 — Детальный список задач с фильтрацией (P2) **Why P2**: Сводка даёт общую картину, но оператору нужно найти конкретную задачу: «что там с миграцией дашборда X?», «какие переводы упали сегодня?», «показать только бекапы за последние сутки». **Independent Test**: На странице `/reports` кликнуть по карточке сводки «Миграция / Выполняется (3)» → список отчётов фильтруется: только миграции в статусе running. **Acceptance**: 1. **Given** в системе есть задачи всех типов **When** оператор применяет фильтр по типу задачи **Then** список обновляется и показывает только задачи выбранного типа. 2. **Given** в системе есть задачи в разных статусах **When** оператор применяет фильтр по статусу (только running + pending) **Then** список показывает только активные задачи. 3. **Given** оператор ввёл текст в строку поиска **When** текст совпадает с названием задачи или идентификатором дашборда/конфигурации **Then** список фильтруется по совпадению. 4. **Given** оператор выбрал временной диапазон «последний час» **When** задачи созданы более часа назад **Then** они не отображаются в списке. --- ### Story 3 — Быстрый переход к логам и результатам задачи (P3) **Why P3**: Увидев, что задача упала или выполняется, оператор хочет немедленно посмотреть логи или результат — без поиска задачи на другой странице. **Independent Test**: На странице `/reports` кликнуть на строку задачи со статусом FAILED → открывается Task Drawer с логами этой задачи. **Acceptance**: 1. **Given** оператор на `/reports` видит задачу со статусом FAILED **When** он кликает по задаче **Then** открывается Task Drawer с логами задачи, курсор прокручивается к последней ошибке. 2. **Given** оператор на `/reports` видит задачу со статусом RUNNING **When** он кликает по задаче **Then** открывается Task Drawer и начинает показывать live-логи через WebSocket. 3. **Given** оператор навёлся на строку задачи **When** курсор находится над строкой **Then** появляется тултип с краткой информацией: тип, время запуска, длительность, ключевой параметр (например, название дашборда). --- ### Edge Cases - **Массовое завершение задач**: Одновременно завершаются десятки задач (например, batch-перевод) → сводка и список должны корректно отобразить все изменения без зависания UI (debounce обновлений, batch-обработка WebSocket-событий). - **Потеря WebSocket-соединения**: Соединение разрывается → индикатор состояния соединения в интерфейсе; автоматический reconnect с экспоненциальной задержкой; на время разрыва показывается «данные могут быть неактуальны». - **Длительная загрузка истории**: В системе тысячи завершённых задач → пагинация и серверная фильтрация предотвращают загрузку полного списка; активные задачи всегда показываются первыми. - **Задача с типом UNKNOWN**: Плагин не сопоставлен ни с одним известным типом → отображается с меткой «Неизвестный тип», не ломает фильтрацию. - **Задача в статусе AWAITING_INPUT**: Задача ожидает ввода пользователя → отображается в сводке отдельной категорией «Ожидает ввода»; в списке — с визуальным индикатором и кнопкой «Ответить». - **Отсутствие прав**: Пользователь с ролью viewer видит только свои задачи в списке и сводке; задачи других пользователей не отображаются. Попытка прямого доступа к чужой задаче через URL — 403. - **Переключение между страницами**: Оператор уходит с `/reports` и возвращается → восстанавливается последний набор фильтров (из URL query params), сводка перезапрашивается. - **Задачи, удалённые retention-политикой**: Задача очищена из БД → исчезает из сводки и списка при следующем обновлении данных. Оператору не нужно видеть «призраки» удалённых задач. ## Requirements ### Functional (IDs survive HCA 128× via hierarchical naming) - **TSC-FR-001**: Страница `/reports` отображает сводную панель над списком отчётов с агрегированными счётчиками задач по статусам (pending, running, awaiting_input, success, failed) для каждого типа задач (перевод, миграция, бекап, валидация, документация, прочие). - **TSC-FR-002**: Сводная панель обновляется в реальном времени через WebSocket без перезагрузки страницы. - **TSC-FR-003**: Список отчётов (задач) отображается с пагинацией, сортировкой по времени создания (свежие сверху) и возможностью изменить сортировку. - **TSC-FR-004**: Оператор может фильтровать список отчётов по: типу задачи, статусу, текстовому поиску (по названию задачи, идентификатору ресурса), временному диапазону. Клик по карточке сводки автоматически устанавливает соответствующий фильтр. - **TSC-FR-005**: Каждая задача в списке показывает: тип (с иконкой), название/идентификатор, статус (с цветовой индикацией), время запуска, длительность, связанный ресурс (дашборд, датасет, конфигурация перевода). - **TSC-FR-006**: Клик по задаче открывает Task Drawer с логами этой задачи через WebSocket (`/ws/logs/{task_id}`). Для завершённых задач — загружает архивные логи. - **TSC-FR-007**: Задачи в статусе AWAITING_INPUT отображаются с визуальным индикатором и кнопкой «Ответить», открывающей форму ввода в Task Drawer. - **TSC-FR-008**: Статус WebSocket-соединения отображается индикатором; при разрыве — автоматический reconnect с уведомлением оператора. - **TSC-FR-009**: Страница `/reports` соблюдает RBAC: admin видит задачи всех пользователей; analyst видит свои задачи и системные задачи (без владельца); viewer видит только задачи, запущенные им лично. Сводная панель отражает только видимые пользователю задачи. - **TSC-FR-010**: Активные задачи (running, pending, awaiting_input) всегда показываются в начале списка, независимо от выбранной сортировки. ### Key Entities - **Task**: Фоновая задача, запущенная через любой плагин superset-tools. Ключевые атрибуты: идентификатор, тип (translate, migration, backup, validation, documentation, git, storage, debug, search, mapper, maintenance, clean_release, unknown), статус (PENDING, RUNNING, SUCCESS, FAILED, AWAITING_INPUT, AWAITING_MAPPING), время создания/запуска/завершения, связанный ресурс, идентификатор пользователя. Архивные задачи (удалённые retention-политикой) исключаются из сводки и списка. - **TaskSummary**: Агрегированная сводка — срез количества задач по каждой комбинации (тип × статус). Обновляется в реальном времени. - **TaskFilter**: Набор параметров фильтрации, применяемых к списку задач: типы, статусы, поисковый запрос, временной диапазон. ## Success Criteria - **SC-001**: Оператор получает сводку по всем задачам не более чем за 1 секунду после открытия `/reports`. - **SC-002**: Изменение статуса задачи отражается в сводке и списке не более чем через 2 секунды после события на backend (измеряется от отправки WebSocket-события до обновления DOM). - **SC-003**: Оператор находит нужную задачу (фильтрация + поиск или клик по карточке сводки) не более чем за 2 действия после открытия `/reports`. - **SC-004**: При 100+ одновременно активных задачах интерфейс остаётся отзывчивым (частота кадров не падает ниже 30 fps при прокрутке списка). - **SC-005**: Восстановление WebSocket-соединения после разрыва происходит автоматически в течение 5 секунд с экспоненциальной задержкой. #endregion FeatureSpec