5.8 KiB
Запрос к 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. Нужно спроектировать:
- Схему БД для хранения истории тестов
- Подключение (connection pool для multi-worker gunicorn)
- Миграции (как управлять схемой при обновлениях)
- 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 1DOCS/sonnet-architecture-review-v1.0.89.md— запрос Round 1