# История разработки app-autotest ## v1.0.89 (27.07.2026) — Sonnet Round 2: PostgreSQL, auth.py, детальный план ### Результаты анализа Sonnet дал конкретные ответы на все 7 вопросов Round 2: **1. PostgreSQL схема:** - Таблица `runs` с JSONB-полями `params` и `stages` - 3 индекса: `(client_id, stand, created_at DESC)`, `(instance_uid)`, `(created_at)` - Stages в JSONB (не отдельная таблица), instances не нужны (API — source of truth) - Чувствительные params маскировать при сохранении **2. Connection pool:** - `psycopg2.pool.ThreadedConnectionPool` — минимум зависимостей - Lazy-init в `db/pool.py` — безопасно для fork-модели gunicorn - `flask.g` + `@app.teardown_appcontext` для возврата соединений **3. Миграции:** - `db/init_db.py` с `IF NOT EXISTS` — идемпотентно, авто-применение при старте - Alembic — когда 3+ таблицы или нужен rollback (сейчас не нужно) **4. Трекер vs PostgreSQL:** - **НЕ заменять** трекер на БД — это разные слои - Трекер = кеш (секунды), PostgreSQL = история (недели) - Сетевое обращение к БД на критическом пути CREATE недопустимо **5. auth.py:** - Явные функции вместо `before_request` — проще, нет скрытых зависимостей - Одна реализация `get_client_id()` вместо двух копий - Кеширование `token → endpoint` (опционально, TTL 5 мин) **6. Динамические сервисы:** - `/api/services` из API → фильтр по `enabled: true` из config.yaml - UI: заменить хардкод `SVC_ID=1` на динамическую загрузку в `selectService()` **7. JS в файл:** - Классический скрипт, один файл `app.js` (300 строк — не нужно ES modules) - `window.APP = {...}` через `tojson` фильтр Jinja2 для передачи переменных ### Итоговый порядок реализации (9 шагов) 1. `api/auth.py` — вынести get_token/get_client/get_client_id/get_stand 2. Заменить дублирующиеся функции в main.py и api_test.py 3. Cookie `httponly=True, samesite='Strict'` 4. `_op_results` TTL/очистка 5. JS вынести в `/static/app.js` + `window.APP` 6. Динамические сервисы из `/api/services` 7. `db/pool.py` + `db/init_db.py` (PostgreSQL) 8. Запись истории в runs при завершении операции 9. `/api/history` эндпоинт + UI ## v1.0.89 (27.07.2026) — Sonnet Round 1: архитектурный аудит - Cloud-first подход с tracker-fallback - HTML-экранирование в JS **🔴 Критические находки:** 1. `_op_results` dict растёт бесконечно — утечка памяти, нужен TTL/очистка 2. Cookie токена без `httponly` и `samesite` 3. `/api/log` без проверки авторизации **🟡 Дублирование:** 1. `_client_id()` — идентичный код в main.py и api_test.py 2. `_client()` — разное поведение в main.py и api_test.py 3. Инлайн `