# Ревью Соннета: история тестов — ответы и решения > Дата: 2026-07-26 > Рецензируемый файл: `DOCS/test-results-history-plan.md` ## Вопрос 1: SQLite в `/tmp/` — надёжно? **Ответ:** ✅ Да, для тестового инструмента достаточно. `/tmp/` теряется только при рестарте пода (OOMKill, node restart, редеплой с новым контейнером). PostgreSQL добавил бы зависимость от отдельного сервиса, provisioning и точки отказа — несоразмерно задаче. **Решение:** SQLite, `/tmp/autotest_results.db`. --- ## Вопрос 2: Схема БД — нормально? **Ответ:** В целом да, но: - Добавить `UNIQUE` индекс на `op_uid` — это внешний идентификатор облака, должен быть уникальным - `test_params` **убрать из MVP** (Фаза 1). Добавить в Фазе 2 когда понадобится «повторный запуск с теми же параметрами» **Решение:** Фаза 1 — только `test_runs` + `test_stages`. Параметры позже. --- ## Вопрос 3: Хранить `stageMsg`? **Ответ:** ✅ Да, обязательно. 100 запусков × 5 стадий × 5 КБ = 2.5 МБ. SQLite справляется без проблем. `stageMsg` — самое ценное для диагностики «почему упало». **Решение:** Хранить. Поле `TEXT`, ограничений нет. --- ## Вопрос 4: API эндпоинты — достаточный набор? **Ответ:** Да, плюс один: - `DELETE /api/results` (без ``) — очистка всей истории или старше N дней (`?older_than_days=30`). Нужно чтобы `/tmp/` не раздувался. **Решение:** Добавить `DELETE /api/results` с опциональным `?older_than_days=N`. --- ## Вопрос 5: UI — серверный рендеринг или SPA? **Ответ:** Оставить текущий подход (Jinja2 + vanilla JS). Фильтры-кнопки + раскрытие строк — 30 строк JS. SPA для одной страницы — избыточно. **Решение:** Серверный рендеринг, фильтры на JS. --- ## Вопрос 6: Экспорт — поток или файл? **Ответ:** Файл. ```python return jsonify(data), 200, { "Content-Disposition": "attachment; filename=results.json" } ``` На 1000 записей — мгновенно, стриминг не нужен. **Решение:** `GET /api/results/export` → JSON-файл. --- ## Вопрос 7: Что упущено? **Ответ:** `_finish_op()` сейчас не получает `op_name` и `svc_op_id` — а они нужны для `save_result()`. Сейчас сигнатура: ```python def _finish_op(client, op_uid, instance_uid, svc_id, display_name, is_create, is_delete=False) ``` Нужно: ```python def _finish_op(client, op_uid, instance_uid, svc_id, display_name, op_name, svc_op_id, is_create, is_delete=False) ``` И передавать `op_name` и `svc_op_id` из `api_test()` при вызове `threading.Thread(...)`. **Решение:** Исправить сигнатуру до реализации `results_db.py`. --- ## Итоговый план (скорректированный) ### Фаза 1 (MVP) 1. Исправить `_finish_op()` — добавить `op_name`, `svc_op_id` 2. `site/operations/results_db.py` — SQLite (только `test_runs` + `test_stages`) 3. `_finish_op()` → `save_result()` 4. `GET /api/results`, `DELETE /api/results` 5. UI — простая таблица без фильтров ### Фаза 2 1. `GET /api/results/` — детали 2. `GET /api/results/stats` — статистика 3. `test_params` таблица 4. UI — фильтры, раскрытие ### Фаза 3 1. Экспорт JSON 2. Повторный запуск 3. Таймлайн