3.7 KiB
3.7 KiB
Уточнение архитектуры — изоляция операций — 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 → Выход: данные или ошибка
Пример сигнатуры
# 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."""
...