refactor: decouple — blueprint'ы + CSS/HTML разделение (по шаблону app-autotest)

This commit is contained in:
2026-07-31 22:16:22 +04:00
parent 6a0d5d00a2
commit 944238d224
16 changed files with 803 additions and 464 deletions
+98
View File
@@ -0,0 +1,98 @@
"""
routes/mock_routes.py — служебные эндпоинты /_mock/*.
Blueprint "mock" с префиксом /api/v1/svc/_mock.
POST /reset — полный сброс состояния (для тестов)
GET /state — отладочный дамп instances + operations
GET /services — отладочный список загруженных сервисов
POST /delay/<s> — изменить MOCK_OP_DELAY на лету (не перезапуская сервер)
"""
from flask import Blueprint, jsonify
import mock_state
from config.loader import SERVICES, DELAY as _DELAY
import config.loader as _cfg # для модификации модульной переменной DELAY
bp = Blueprint("mock", __name__, url_prefix="/api/v1/svc/_mock")
@bp.route("/reset", methods=["POST"])
def mock_reset():
"""POST /api/v1/svc/_mock/reset — полный сброс состояния.
Удаляет ВСЕ инстансы, операции и параметры из MockState.
Используется в тестах (autouse fixture) для изоляции тестов друг от друга.
"""
mock_state.state.reset()
return jsonify({"reset": "ok"})
@bp.route("/state", methods=["GET"])
def mock_state_view():
"""GET /api/v1/svc/_mock/state — отладочный дамп состояния.
Возвращает {instances: {uid: {instanceUid, displayName, status, serviceId}},
operations: {uid: {instanceOperationUid, instanceUid, operation,
dtFinish, isSuccessful}}}.
Полезно для отладки тестов: «какие инстансы сейчас живы?», «завершилась ли
операция?». НЕ для production-использования.
"""
st = mock_state.state
return jsonify({
"instances": {
uid: {
"instanceUid": inst["instanceUid"],
"displayName": inst["displayName"],
"status": inst["status"],
"serviceId": inst["serviceId"],
}
for uid, inst in st.instances.items()
},
"operations": {
uid: {
"instanceOperationUid": op["instanceOperationUid"],
"instanceUid": op["instanceUid"],
"operation": op["operation"],
"dtFinish": op["dtFinish"],
"isSuccessful": op["isSuccessful"],
}
for uid, op in st.operations.items()
},
})
@bp.route("/services", methods=["GET"])
def mock_services():
"""GET /api/v1/svc/_mock/services — отладочный список сервисов.
Возвращает {count: N, services: {svcId: {name, displayName, operations, params}}}.
Полезно чтобы быстро проверить что все 37+ сервисов загрузились,
не дёргая реальный /api/v1/svc/services.
"""
result = {}
for svc_id, svc_def in SERVICES.items():
result[str(svc_id)] = {
"name": svc_def.get("name", ""),
"displayName": svc_def.get("service_display_name", ""),
"operations": len(svc_def.get("operations", [])),
"params": len(svc_def.get("cfsParams", [])),
}
return jsonify({"count": len(result), "services": result})
@bp.route("/delay/<float:seconds>", methods=["POST"])
def mock_set_delay(seconds):
"""POST /api/v1/svc/_mock/delay/{s} — изменить задержку операции.
Меняет config.loader.DELAY «на лету», без перезапуска сервера.
Полезно в тестах: установить delay=0 для мгновенных операций,
или delay=5 чтобы проверить таймауты поллинга.
ВАЖНО: меняет модульную переменную config.loader.DELAY, которую читает
routes/run.py при каждом вызове /run.
"""
_cfg.DELAY = seconds
return jsonify({"delay": _cfg.DELAY})