114 lines
5.8 KiB
Markdown
114 lines
5.8 KiB
Markdown
# Запрос к 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
|