# Уточнение архитектуры — изоляция операций — 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.""" ... ```