diff --git a/HISTORY/2026-07-23-session-4.md b/HISTORY/2026-07-23-session-4.md new file mode 100644 index 0000000..7b9e3ca --- /dev/null +++ b/HISTORY/2026-07-23-session-4.md @@ -0,0 +1,74 @@ +# Уточнение архитектуры — изоляция операций — 2026-07-23 + +## Принцип: каждая операция = отдельный изолированный модуль + +Никаких «сервисов на все случаи». Один файл — одна операция. +Максимальная независимость. Лёгкое тестирование. + +## Структура проекта (уточнённая) + +``` +app-autotest/ +├── requirements.txt +├── run.py +├── config.py +└── app/ + ├── __init__.py # create_app() фабрика + ├── api/ + │ ├── __init__.py + │ └── http_client.py # Только HTTP: get/post, Bearer, retry, User-Agent + ├── operations/ # ⭐ КАЖДАЯ ОПЕРАЦИЯ — ОТДЕЛЬНЫЙ МОДУЛЬ + │ ├── __init__.py + │ ├── get_services.py # GET /services → список сервисов + │ ├── get_service_detail.py # GET /services/{id} → операции сервиса + │ ├── get_operation_params.py # GET /instanceOperations/default/{id} → параметры + │ ├── create_instance.py # POST /instances → создать инстанс + │ ├── run_operation.py # POST /instanceOperations → запустить операцию + │ ├── get_instance_state.py # GET /instances → статус инстанса + │ └── get_instances.py # GET /instances → список инстансов + ├── models/ + │ ├── __init__.py + │ ├── db.py # Подключение к БД + │ ├── test_config_repo.py # CRUD конфигураций тестов + │ └── test_result_repo.py # CRUD результатов тестов + ├── routes/ + │ ├── __init__.py + │ ├── main.py # Главная страница (blueprint) + │ ├── api_routes.py # REST API для фронта (blueprint) + │ └── config_routes.py # Конфигурация тестов (blueprint) + ├── static/ + │ ├── favicon.svg + │ ├── logo.svg + │ ├── style.css + │ └── app.js + └── templates/ + ├── base.html + ├── index.html + └── components/ + ├── card.html + ├── modal.html + └── table.html +``` + +## Правила операций + +- **Один файл = одна операция API** (не сервис, не «класс на все случаи») +- Каждый модуль — **чистая функция** (или класс с одним публичным методом) +- Зависимость только от `http_client` (через DI, не глобально) +- **Никаких перекрёстных импортов** между операциями +- Каждую операцию можно **протестировать изолированно** (мокнуть http_client) +- Вход: параметры + http_client → Выход: данные или ошибка + +## Пример сигнатуры + +```python +# app/operations/get_services.py +def get_services(client: HttpClient) -> list[dict]: + """Получить список всех сервисов.""" + ... + +# app/operations/create_instance.py +def create_instance(client: HttpClient, service_id: int, display_name: str, params: dict) -> str: + """Создать инстанс. Возвращает instanceUid.""" + ... +```