# Live Testing Tool

Сервис для передачи багов от тестировщиков разработчикам: заметки на элементах
страницы со скриншотами и аннотациями, запись алгоритма воспроизведения,
веб-панель с неугадываемыми ссылками для Jira.

## Состав

| Часть | Стек | Где |
|---|---|---|
| Сервер (API) | Python 3.13, FastAPI, SQLAlchemy async, Postgres 16, Alembic | `server/` (Docker) |
| Веб-панель | Vue 3, vue-router, vue-i18n (en/ru), [gnexus-ui-kit](https://git.gnexus.space/git/root/gnexus-ui-kit.git) | `packages/web` |
| Общий код UI | Аннотации на скриншотах, контекст элемента | `packages/ui` |
| Расширение | Chrome + Firefox (MV3), Vite, closed shadow-DOM overlay | `packages/extension` |
| Общие типы/клиент API | TypeScript | `packages/shared` |

## Быстрый старт

```sh
npm install          # workspaces: shared, ui, web, extension
make dev             # postgres + API в docker, панель на http://localhost:5173
```

API: `http://localhost:8001` (healthcheck: `/api/healthz`).
Миграции применяются при старте контейнера; вручную — `make migrate`.

## Расширение

```sh
make ext             # сборка в packages/extension/dist/{chrome,firefox}
```

Установка (dev):

- **Chrome/Chromium**: `chrome://extensions` → Developer mode → *Load unpacked* → `packages/extension/dist/chrome`
- **Firefox**: `about:debugging#/runtime/this-firefox` → *Load Temporary Add-on* → `packages/extension/dist/firefox/manifest.json`

Затем: иконка расширения → Settings (или Alt+Shift+B → контекстное меню настроек
не используется, страница настроек открывается из chrome://extensions → Details →
Extension options): указать URL сервера, войти (email/пароль), выбрать проект по умолчанию.

Управление:

- **Alt+Shift+B** — пикер элемента: клик по элементу → скриншот → аннотации
  (перо/стрелка/прямоугольник/текст) → комментарий → Submit.
- **Alt+Shift+R** — старт/стоп записи: клики, ввод (с дебаунсом 250 мс), переходы
  по URL; скриншоты ключевых шагов прикладываются автоматически. Кнопка **Note**
  в рекордер-баре открывает тот же пикер для заметки на элемент.

Пароли не сохраняются: маскирование ввода дублируется на сервере.

### Почему /assets

`kit.css` из gnexus-ui-kit ссылается на шрифты абсолютными путями `/assets/...`.
Веб-панель копирует ассеты кита в свой `dist/assets` (dev-миддлварь + `vite-plugin-static-copy`).
Расширение раздаёт их как `web_accessible_resources` и переписывает пути на
`chrome-extension://.../assets/...` при загрузке стилей в shadow root
(constructable stylesheets — CSS хост-страницы и её CSP не затрагиваются).

## E2E-проверка расширения

`make ext:test` (нужен поднятый `make dev`) — headless Chromium грузит собранное
расширение, проходит сценарий «пикер → заметка» и «рекордер: клики + ввод»,
проверяет репорты через API.

## Прод

```sh
make prod            # web dist + docker-compose.prod.yml
# панель и API на одном origin: http://localhost:8081 (caddy: статика + /api → server)
```

## Ссылки и доступ

- PK — UUIDv7; публичные ссылки — случайные 128-битные токены (`/p/<token>`, `/r/<token>`).
- Токен = авторизация: страницы проекта и репорта открываются без логина.
- Ротация токена: кнопка в панели (`POST .../share/rotate`).

## Структура

```
server/app/routers/   auth, projects, reports, uploads
packages/web/src/     pages (Login, Register, Projects, Project, Report, Settings), i18n
packages/ui/src/      AnnotationEditor, ScreenshotViewer, ElementContext, EnvironmentInfo
packages/extension/src/  background (SW: сеть, captureVisibleTab, буфер рекордера),
                         content (shadow-DOM оверлей: PickerLayer, NoteComposer, RecorderBar),
                         options (сервер, логин, проект по умолчанию)
```