diff --git a/app.py b/app.py index 46751ed..c32067a 100644 --- a/app.py +++ b/app.py @@ -29,7 +29,7 @@ from ui_builder import install_ui_builder from khl_site.khl_data_center import APP as khl_site_app BASE_DIR = Path(__file__).resolve().parent -BUILD_VERSION = "2026.09.15.3" +BUILD_VERSION = "2026.09.15.4" # compatibility: BUILD_VERSION = "2026.08.26.1" # compatibility: BUILD_VERSION = "2026.08.25.1" # compatibility: BUILD_VERSION = "2026.08.24.15" diff --git a/hockey_data/mapping_context.py b/hockey_data/mapping_context.py index ae5f57b..4102d6d 100644 --- a/hockey_data/mapping_context.py +++ b/hockey_data/mapping_context.py @@ -53,6 +53,10 @@ DEFAULT_CONTEXT_VARIABLES: tuple[dict[str, Any], ...] = ( {"key": "device_id", "label": "Активный Agent", "category": "Система", "entity_type": "device", "scope": "session", "source_type": "system"}, {"key": "assignment_id", "label": "Текущее назначение Agent", "category": "Система", "entity_type": "assignment", "scope": "session", "source_type": "system"}, {"key": "active_tab", "label": "Активная вкладка интерфейса", "category": "Система", "entity_type": "tab", "scope": "session", "source_type": "selection"}, + {"key": "period_key", "label": "Текущий период — ключ", "category": "Система · Период", "entity_type": "period", "scope": "match", "source_type": "system", "value_type": "text", "description": "Технический ключ текущего периода: 1, 2, 3, ot, ot1, ot2, so, finished."}, + {"key": "period_number", "label": "Текущий период — номер", "category": "Система · Период", "entity_type": "period", "scope": "match", "source_type": "system", "value_type": "number", "description": "Для 1–3 возвращает номер периода; для otN — номер овертайма; для ot/so/finished — 0."}, + {"key": "period_is_ot", "label": "Текущий период — овертайм (1/0)", "category": "Система · Период", "entity_type": "period", "scope": "match", "source_type": "system", "value_type": "text", "description": "1, если текущий период — OT/OT1/OT2…; иначе 0."}, + {"key": "period_is_regular", "label": "Текущий период — основной (1/0)", "category": "Система · Период", "entity_type": "period", "scope": "match", "source_type": "system", "value_type": "text", "description": "1 для основных периодов 1, 2, 3; иначе 0."}, {"key": "selected_team_id", "label": "Выбранная команда", "category": "Выделенные", "entity_type": "team", "scope": "match", "source_type": "selection"}, {"key": "selected_player_id", "label": "Выбранный игрок", "category": "Выделенные", "entity_type": "player", "scope": "match", "source_type": "selection"}, @@ -632,6 +636,24 @@ class MappingDataService: context.setdefault("score_external_home", str(score_control["external_home"])) context.setdefault("score_external_away", str(score_control["external_away"])) context.setdefault("score_manual", "1" if score_control["manual"] else "0") + + # BUILD136: expose the current game period as first-class SQL bind + # parameters. Mapping already has dotted values such as period.key, + # but SQL bind names cannot contain dots. These values follow the + # authoritative GameControlState and therefore change immediately when + # the operator switches the period in the match header. + current_period = HockeyDataService._normalise_control_period( + str(getattr(control, "current_period", "1") or "1") + ) + overtime_number = HockeyDataService._overtime_number(current_period) + context.setdefault("period_key", current_period) + context.setdefault( + "period_number", + str(overtime_number if overtime_number else (int(current_period) if current_period in {"1", "2", "3"} else 0)), + ) + context.setdefault("period_is_ot", "1" if current_period == "ot" or overtime_number > 0 else "0") + context.setdefault("period_is_regular", "1" if current_period in {"1", "2", "3"} else "0") + if control is not None: runtime_values = HockeyDataService._runtime_values_from_row(control) player_panel_labels: dict[str, str] = {}