v1.0.89: Sonnet Round 2 prompt — PostgreSQL schema, auth.py, dynamic services
This commit is contained in:
@@ -1,5 +1,44 @@
|
||||
# История разработки app-autotest
|
||||
|
||||
## v1.0.89 (27.07.2026) — Sonnet Round 1: архитектурный аудит
|
||||
|
||||
### Результаты анализа
|
||||
Sonnet провёл полный аудит кода и документации. Ключевые выводы:
|
||||
|
||||
**✅ Что хорошо:**
|
||||
- Разделение слоёв (api/operations/routes)
|
||||
- Multi-worker safety через fcntl.flock
|
||||
- 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. Инлайн `<style>` дублирует `style.css`
|
||||
|
||||
**🟡 Захардкодено:**
|
||||
1. `SVC_ID=1` и список сервисов в HTML — хотя `/api/services` существует
|
||||
2. `create_client()` в main.py vs `_client()` в api_test.py — разные подходы
|
||||
|
||||
**Приоритетный план исправлений:**
|
||||
1. 🔴 `_op_results` — добавить очистку/TTL
|
||||
2. 🔴 Cookie `httponly=True, samesite='Strict'`
|
||||
3. 🟡 Вынести `_client_id()` / `get_token()` в общий модуль `api/auth.py`
|
||||
4. 🟡 Загрузка сервисов из `/api/services` вместо хардкода
|
||||
5. 🟡 Вынести JS в `/static/app.js`
|
||||
6. 🟢 SQLite история запусков
|
||||
7. 🟢 `/api/log` проверка токена
|
||||
|
||||
### Создан запрос Round 2
|
||||
Файл: `DOCS/sonnet-architecture-review-v1.0.89-r2.md` — уточняющие вопросы по реализации.
|
||||
|
||||
## v1.0.89 (27.07.2026) — документация и комментарии кода
|
||||
|
||||
## v1.0.87 (27.07.2026) — документация: ARCHITECTURE.md переписан, legacy-доки помечены
|
||||
|
||||
## v1.0.84 (27.07.2026) — лог-панель скрыта по умолчанию
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
# Запрос к Claude (Sonnet): архитектурный аудит — Round 2
|
||||
|
||||
> **Контекст**: Round 1 анализ получен, исправления по приоритетам приняты.
|
||||
> **Новое**: проект будет подключать **PostgreSQL** (отдельный сервис Nubes).
|
||||
> **Дата**: 27.07.2026
|
||||
> **Версия**: 1.0.89
|
||||
|
||||
---
|
||||
|
||||
## Контекст Round 1
|
||||
|
||||
Sonnet в первом раунде выявил:
|
||||
- 🔴 Утечка `_op_results` — нужно TTL/очистка
|
||||
- 🔴 Cookie без `httponly`/`samesite`
|
||||
- 🟡 Дублирование `_client_id()` в main.py и api_test.py
|
||||
- 🟡 Захардкожен `SVC_ID=1` — хотя `/api/services` существует
|
||||
- 🟢 Рекомендация: SQLite для истории → **теперь PostgreSQL**
|
||||
|
||||
Все исправления из Round 1 приняты к реализации. Начинаем со среднего приоритета (общий модуль `auth.py`).
|
||||
|
||||
---
|
||||
|
||||
## Новый контекст: PostgreSQL
|
||||
|
||||
Проект получает отдельный PostgreSQL-сервис в Nubes. Нужно спроектировать:
|
||||
1. **Схему БД** для хранения истории тестов
|
||||
2. **Подключение** (connection pool для multi-worker gunicorn)
|
||||
3. **Миграции** (как управлять схемой при обновлениях)
|
||||
4. **API** для чтения/записи результатов
|
||||
|
||||
---
|
||||
|
||||
## Вопросы Round 2
|
||||
|
||||
### 1. PostgreSQL — схема данных
|
||||
|
||||
Нужна схема для истории запусков. Минимальный набор полей:
|
||||
- id, created_at
|
||||
- client_id, stand (изоляция по пользователю и стенду)
|
||||
- svc_id, svc_name
|
||||
- op_name (create/modify/delete/...), svc_op_id
|
||||
- instance_uid, display_name
|
||||
- status (OK/FAIL/TIMEOUT), duration_sec
|
||||
- error_log (текст ошибки)
|
||||
- params (JSON — все параметры запуска)
|
||||
- stages (JSON — этапы выполнения с длительностью)
|
||||
|
||||
Вопросы:
|
||||
- Какие индексы нужны? (по client_id+stand, по created_at, по instance_uid?)
|
||||
- Нужна ли отдельная таблица для stages или JSON в основном поле?
|
||||
- Нужна ли таблица `instances` (связь instance_uid → последний статус)?
|
||||
- Как хранить чувствительные params (пароли, токены в map-параметрах)?
|
||||
|
||||
### 2. PostgreSQL — connection pool
|
||||
|
||||
Сейчас gunicorn с несколькими воркерами. Каждый воркер — отдельный процесс.
|
||||
|
||||
Вопросы:
|
||||
- Какой connection pooler использовать? (psycopg2.pool? SQLAlchemy? asyncpg?)
|
||||
- Где создавать пул? (в app.py при старте? lazy в каждом воркере?)
|
||||
- Как передавать соединение в роуты? (flask.g? внедрение через blueprint?)
|
||||
- Нужен ли `@app.teardown_appcontext` для возврата соединения в пул?
|
||||
|
||||
### 3. PostgreSQL — миграции
|
||||
|
||||
Вопросы:
|
||||
- Нужна ли полноценная миграция (Alembic) или простая схема в `init_db.py`?
|
||||
- Где хранить SQL-файлы миграций? (отдельная папка `migrations/`?)
|
||||
- Как применять при деплое? (автоматически при старте приложения?)
|
||||
|
||||
### 4. Объединение с текущим трекером
|
||||
|
||||
Сейчас трекер (`tracker.py`) хранит UID'ы в JSON-файлах `/tmp/`. После появления PostgreSQL:
|
||||
|
||||
Вопросы:
|
||||
- Заменяет ли PostgreSQL трекер полностью? (хранить UID'ы в БД вместо /tmp/)
|
||||
- Или оставить трекер для краткосрочного кеша, а БД — для истории?
|
||||
- Если заменить — нужна ли миграция существующих данных из /tmp/ в БД?
|
||||
|
||||
### 5. Унификация `auth.py`
|
||||
|
||||
Из Round 1: вынести `_client_id()`, `get_client()`, `get_stand()`, `get_token_info()` в общий модуль `api/auth.py`.
|
||||
|
||||
Вопросы:
|
||||
- Использовать `flask.g` + `@bp.before_request` или явные вызовы функций?
|
||||
- Как обрабатывать роуты без обязательного токена (GET / без авторизации)?
|
||||
- Где создавать `HttpClient` — в `before_request` (на каждый запрос) или lazy?
|
||||
|
||||
### 6. Фронтенд — динамические сервисы
|
||||
|
||||
Сейчас `SVC_ID=1` захардкожен. Нужно загружать список из `/api/services`.
|
||||
|
||||
Вопросы:
|
||||
- Показывать ВСЕ сервисы или только из whitelist в config.yaml?
|
||||
- Какой UI для переключения между сервисами? (выпадающий список? вкладки?)
|
||||
- При смене сервиса — сбрасывать `selectedInst` и форму параметров?
|
||||
|
||||
### 7. JS в отдельный файл
|
||||
|
||||
Вынести весь JS из `<script>` в `/static/app.js`.
|
||||
|
||||
Вопросы:
|
||||
- Нужно ли использовать ES modules (`type="module"`) или классический скрипт?
|
||||
- Если модули — как разбить на файлы (instances.js, params.js, log.js)?
|
||||
- Как передавать Jinja2-переменные (config.VERSION, token_info) в JS-файл?
|
||||
|
||||
---
|
||||
|
||||
## 4. Файлы для изучения (если нужно)
|
||||
|
||||
Те же что в Round 1, плюс:
|
||||
- `DOCS/HISTORY.md` — обновлён результатами Round 1
|
||||
- `DOCS/sonnet-architecture-review-v1.0.89.md` — запрос Round 1
|
||||
Reference in New Issue
Block a user