Модель системы

Компоненты

Browser / tester
       |
       | HTTPS + session cookie + CSRF
       v
  Nginx :443
       |
       v
  QA Hub API/UI  -----> SQLite/WAL
       |                 runs, jobs, audit
       |
       +---------------> artifact storage
       ^
       |
       | HTTPS + agent Bearer token
       |
  Agent runner --------> target environment
                         browser / API / VideoGrace

QA Hub отвечает за управление состоянием. Runner отвечает за исполнение и изоляцию теста. Такая граница не позволяет JSON-каталогу превратиться в удаленное выполнение команд на agent host.

Основные сущности

Environment

Окружение содержит:

  • уникальное имя, например stage1;
  • base_url, например https://stage1.videograce.ru;
  • необязательный secret_ref;
  • признак активности.

Имя окружения участвует в маршрутизации jobs. Если агент зарегистрирован с "environments":["stage1"], задания других окружений он не получит.

Suite и test case

Suite задается JSON-файлом и импортируется идемпотентно по suite.slug. Тест-кейс идентифицируется полем id внутри набора. Повторный импорт обновляет описание и шаги, сохраняя историю уже созданных прогонов.

Тип исполнения:

execution Ручная часть Agent job
manual да нет
agent нет да
combined да да

Режим прогона дополнительно ограничивает исполнение. Например, suite с combined-кейсами можно запустить в режиме manual, и jobs созданы не будут.

Run и case run

При старте прогон делает snapshot состава suite: для каждого тест-кейса создается case_run. Ручной и агентский статусы существуют раздельно, а общий статус вычисляется по ним.

pending -> running -> passed
                   \-> failed
                   \-> skipped

Прогон имеет два разных момента:

  • completed_at — все обязательные части получили конечный статус;
  • finalized_at — человек явно зафиксировал отчет.

Это позволяет исправить ошибочно выбранный результат до публикации отчета.

Job и lease

Для agent-части создается job со статусом:

queued -> claimed -> passed
                  \-> failed
                  \-> cancelled

После claim агент владеет заданием только до lease_expires_at. Heartbeat продлевает lease. Если агент исчез, Hub возвращает job в очередь, и его может забрать другой совместимый runner.

Artifact

Artifact привязывается к прогону, а при необходимости — к case_run и job. Файл хранится на диске, а в SQLite находятся имя, MIME type, размер, SHA-256, автор и время загрузки.

Как выбирается агент

Hub просматривает jobs в порядке создания и проверяет:

  1. Все required_capabilities входят в capabilities агента.
  2. Имя окружения разрешено агенту.
  3. Прогон все еще имеет статус running.

Пустой список environments у агента означает доступ ко всем окружениям. Capabilities сравниваются как точные строки; иерархии и wildcard нет.

Модель доверия

  • Browser session хранится в HttpOnly, Secure, SameSite=Strict cookie.
  • Изменяющие browser-запросы требуют CSRF token.
  • CLI-пользователь получает отдельный Bearer session token.
  • Агент получает отдельный qaa_... Bearer token, показанный один раз.
  • В БД session и agent tokens находятся только в виде SHA-256.
  • Agent payload не содержит фактических секретов окружения.
  • Увольнение пользователя немедленно отзывает его sessions.
  • Удаление обезличивает аккаунт, не разрушая audit trail.

Матрица ролей

Permission viewer tester devops qa_lead admin
Читать каталог и прогоны
Создавать прогоны
Заполнять ручной результат
Загружать ручные артефакты
Управлять окружениями
Регистрировать агентов
Импортировать каталог
Управлять пользователями