diff --git a/site/api/auth.py b/site/api/auth.py index aff1052..ca98666 100644 --- a/site/api/auth.py +++ b/site/api/auth.py @@ -102,15 +102,6 @@ def get_client(): return HttpClient(_cached_detect(token), token) -def get_real_client(): - """Алиас get_client() — историческая совместимость. - - Раньше get_real_client() всегда ходил в реальный API (для сервисов). - Теперь в эмуляции сервисы тоже из полигона → обе функции идентичны. - Оставлено чтобы не ломать все места вызова.""" - return get_client() - - def get_client_id(): """Извлечь ClientID из payload JWT-токена (base64url, без проверки подписи). diff --git a/site/api/http_client.py b/site/api/http_client.py index f63308d..89b120f 100644 --- a/site/api/http_client.py +++ b/site/api/http_client.py @@ -52,12 +52,11 @@ def detect_endpoint(token): def stand_name(endpoint): - """Определить имя стенда по URL. + """Определить имя стенда по URL — точное совпадение endpoint. - Ищет подстроку 'dev' или 'test' в URL. - Если не найдено — '?' (неизвестный стенд).""" - for name in ("dev", "test"): - if name in (endpoint or ""): + Возвращает 'dev'/'test' или '?' если не совпало.""" + for name, url in (("dev", STANDS[0]), ("test", STANDS[1])): + if (endpoint or "").rstrip("/") == url.rstrip("/"): return name return "?" diff --git a/site/app.py b/site/app.py index eaf65dc..ffcc9f0 100644 --- a/site/app.py +++ b/site/app.py @@ -32,7 +32,7 @@ from routes.api_scenario_defs import bp_defs as api_scenario_defs_bp # Версия — показывается в топбаре UI. Меняется при КАЖДОМ изменении кода. # Нужна для фильтрации истории (пользователь видит только записи своей версии). -VERSION = "1.2.42" +VERSION = "1.2.43" # Flask-приложение с Jinja2-шаблонами из папки templates/ app = Flask(__name__, template_folder="templates", static_folder="static") diff --git a/site/db/init_db.py b/site/db/init_db.py index 339c92c..be7fe35 100644 --- a/site/db/init_db.py +++ b/site/db/init_db.py @@ -84,6 +84,10 @@ ALTER TABLE runs ADD COLUMN IF NOT EXISTS app_version VARCHAR(16); ALTER TABLE runs ADD COLUMN IF NOT EXISTS scenario_run_id INTEGER; ALTER TABLE runs ADD COLUMN IF NOT EXISTS step_number INTEGER; ALTER TABLE runs ADD COLUMN IF NOT EXISTS instance_meta JSONB; + +-- Уникальный индекс на op_uid для предотвращения гонок в save_run +CREATE UNIQUE INDEX IF NOT EXISTS idx_runs_op_uid + ON runs (op_uid) WHERE op_uid IS NOT NULL; """ # ── DDL для scenario_runs (запуски сценариев) ── diff --git a/site/routes/api_test.py b/site/routes/api_test.py index f7d9f6e..b728d30 100644 --- a/site/routes/api_test.py +++ b/site/routes/api_test.py @@ -31,7 +31,7 @@ import json import fcntl from api.http_client import HttpClient, detect_endpoint, stand_name -from api.auth import get_token, get_client, get_real_client, get_client_id, get_stand, get_token_info +from api.auth import get_token, get_client, get_client_id, get_stand, get_token_info from api.utils import find_uid, uid_from_location from operations.get_services import get_services, get_service_detail from operations.get_instances import get_instances @@ -70,6 +70,7 @@ def _log(msg): f.seek(0) f.truncate() f.write(rest) + f.flush() # сбросить буфер перед снятием лока fcntl.flock(f, fcntl.LOCK_UN) except Exception: pass # молча — не ронять запрос из-за лога @@ -395,6 +396,8 @@ def api_log(): @bp.route("/api/history") def api_history(): """Последние 50 записей истории тестов (фильтр по client_id + stand).""" + conn = None + cur = None try: from db.pool import get_conn, put_conn conn = get_conn() @@ -414,20 +417,16 @@ def api_history(): rows = cur.fetchall() cols = [d[0] for d in cur.description] result = [dict(zip(cols, r)) for r in rows] - # Конвертировать datetime в строку for r in result: if r["created_at"]: r["created_at"] = r["created_at"].isoformat() - cur.close() - put_conn(conn) return jsonify(result) except Exception as e: - try: - cur.close() - except Exception: - pass - try: - put_conn(conn) - except Exception: - pass return jsonify({"error": str(e)}), 500 + finally: + if cur: + try: cur.close() + except Exception: pass + if conn: + try: put_conn(conn) + except Exception: pass diff --git a/site/routes/main.py b/site/routes/main.py index 267192a..49fd4a9 100644 --- a/site/routes/main.py +++ b/site/routes/main.py @@ -11,7 +11,7 @@ GET /api/operations/ — операции и autotest-инста from flask import Blueprint, current_app, render_template, request, make_response, jsonify, redirect from api.http_client import HttpClient, detect_endpoint, create_client, stand_name -from api.auth import get_token, get_client_id, get_token_info, get_token_masked, get_client, get_real_client, get_stand, get_mode, get_polygon_stand +from api.auth import get_token, get_client_id, get_token_info, get_token_masked, get_client, get_stand, get_mode, get_polygon_stand from operations.get_instances import get_organization, get_instances from operations.get_services import get_services, get_service_detail from operations.service_list import load_service_ids