Docs: Sonnet review Q&A — decisions and adjusted plan
This commit is contained in:
@@ -0,0 +1,111 @@
|
||||
# Ревью Соннета: история тестов — ответы и решения
|
||||
|
||||
> Дата: 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` (без `<id>`) — очистка всей истории или старше 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/<id>` — детали
|
||||
2. `GET /api/results/stats` — статистика
|
||||
3. `test_params` таблица
|
||||
4. UI — фильтры, раскрытие
|
||||
|
||||
### Фаза 3
|
||||
1. Экспорт JSON
|
||||
2. Повторный запуск
|
||||
3. Таймлайн
|
||||
Reference in New Issue
Block a user