Session 4: operations as isolated independent modules
This commit is contained in:
@@ -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."""
|
||||||
|
...
|
||||||
|
```
|
||||||
Reference in New Issue
Block a user