From f8029562579b202b1e8d3e18ee659f821f0cb613 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CNaeel=E2=80=9D?= Date: Mon, 27 Jul 2026 22:21:44 +0400 Subject: [PATCH] =?UTF-8?q?v1.0.89:=20Sonnet=20Round=202=20results=20?= =?UTF-8?q?=E2=80=94=20PostgreSQL=20schema,=20auth.py,=209-step=20plan?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DOCS/HISTORY.md | 52 ++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 47 insertions(+), 5 deletions(-) diff --git a/DOCS/HISTORY.md b/DOCS/HISTORY.md index 351b530..ed2fa80 100644 --- a/DOCS/HISTORY.md +++ b/DOCS/HISTORY.md @@ -1,13 +1,55 @@ # История разработки app-autotest -## v1.0.89 (27.07.2026) — Sonnet Round 1: архитектурный аудит +## v1.0.89 (27.07.2026) — Sonnet Round 2: PostgreSQL, auth.py, детальный план ### Результаты анализа -Sonnet провёл полный аудит кода и документации. Ключевые выводы: +Sonnet дал конкретные ответы на все 7 вопросов Round 2: -**✅ Что хорошо:** -- Разделение слоёв (api/operations/routes) -- Multi-worker safety через fcntl.flock +**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