каркас: домен, генерация типов фронта, стенд и карточки задач
Контракт в коде: КИО по нормативу, 43 события WS по шести союзам направлений,
таймеры ГОСТ, таксономия E1–E6, шесть компетенций радара. make types гоняет
их через JSON Schema в generated.ts, тест ловит забытую регенерацию.
Стенд: docker compose postgres + backend, health отвечает, база досягаема
из контейнера бэкенда. Makefile не врёт — нереализованные цели падают
и называют карточку, которая их закроет.
frontend/.npmrc: под WSL2 npm install зависает на дефолтных 15 сокетах.
2026-09-15 19:35:03 +03:00
|
|
|
|
"""Классификаторы ДДС, типы происшествий, уровни сложности.
|
|
|
|
|
|
|
|
|
|
|
|
Норматив: docs/spec/NORMATIVES.md#классификаторы-ддс
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
from enum import StrEnum
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class DDSCode(StrEnum):
|
|
|
|
|
|
"""Дежурно-диспетчерская служба, в которую уходит карточка."""
|
|
|
|
|
|
|
|
|
|
|
|
FIRE = "01"
|
|
|
|
|
|
POLICE = "02"
|
|
|
|
|
|
MEDICAL = "03"
|
|
|
|
|
|
OTHER = "04"
|
|
|
|
|
|
GKH = "gkh"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class IncidentType(StrEnum):
|
|
|
|
|
|
"""Тип происшествия. Совпадает с полем `type` сценария."""
|
|
|
|
|
|
|
|
|
|
|
|
FIRE = "fire"
|
|
|
|
|
|
MEDICAL = "medical"
|
|
|
|
|
|
POLICE = "police"
|
|
|
|
|
|
OTHER = "other"
|
|
|
|
|
|
GKH = "gkh"
|
|
|
|
|
|
ERA_GLONASS = "era_glonass"
|
|
|
|
|
|
|
|
|
|
|
|
|
feat: исход вызова — не каждый звонок заканчивается карточкой (lct-36)
Весь продукт стоял на допущении «звонок → карточка → выезд». В билетах
заказчика оно нарушается намеренно: «поругался с продавцом Мегафон» — справка,
а вызов из Волгоградской области передаётся в систему-112 другого субъекта.
Курсант, заведший карточку на такой вызов, занял расчёт зря, и прежняя оценка
этого не видела — наоборот, награждала за полноту заполнения.
- Outcome в домене, поле outcome в сценарии, событие call.resolve у курсанта
и две кнопки на АРМ. Отдельное действие, а не «положил трубку»: система
должна отличить осознанное решение от брошенного вызова.
- Метрика outcome (E2, вес 3 — лишний выезд дороже неточного признака).
- Там, где карточка не заводится, метрики карточки не считаются вовсе.
Полнота опроса считается: передать вызов не значит не опрашивать.
- call.resolve останавливает норматив опроса, как и передача карточки.
Попутно (lct-34): библиотека стала вложенной — scenarios/tickets/, поля
ticket и position, чек-листы для медицины, полиции и ЖКХ. Перенесён билет 1
целиком: три вызова, три классификатора, третий — из другого региона.
Найдено по ходу: модификаторы списка оповещения не были подключены ни к чему.
В классификаторе скорая добавляется к массовой драке признаком «пострадавшие»,
но взять его было неоткуда. Теперь модификаторы берутся из карточки —
victims_count, life_threat, evacuation_needed, fire.gasified, — и список
оповещения пересобирается при правке любого из этих полей.
161 тест зелёный (13 новых), make typecheck чистый.
2026-09-20 08:33:30 +03:00
|
|
|
|
class Outcome(StrEnum):
|
|
|
|
|
|
"""Чем заканчивается вызов.
|
|
|
|
|
|
|
|
|
|
|
|
Весь продукт по умолчанию считает, что звонок → карточка → выезд. В билетах
|
|
|
|
|
|
заказчика это не всегда так: «поругался с продавцом „Мегафон“» — справка,
|
|
|
|
|
|
а вызов из Волгоградской области передаётся в систему-112 другого субъекта
|
|
|
|
|
|
(docs/spec/TICKETS.md). Курсант, заведший карточку на такой вызов, ошибся,
|
|
|
|
|
|
и система обязана это увидеть.
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
CARD = "card" # заполнить КИО и передать в ДДС
|
|
|
|
|
|
CONSULTATION = "consultation" # справка, карточка не заводится
|
|
|
|
|
|
TRANSFER_REGION = "transfer_region" # передать в систему-112 другого субъекта
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
OUTCOME_LABELS: dict[Outcome, str] = {
|
|
|
|
|
|
Outcome.CARD: "Карточка и передача в ДДС",
|
|
|
|
|
|
Outcome.CONSULTATION: "Справочно-консультационная помощь",
|
|
|
|
|
|
Outcome.TRANSFER_REGION: "Передача в систему-112 другого региона",
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
каркас: домен, генерация типов фронта, стенд и карточки задач
Контракт в коде: КИО по нормативу, 43 события WS по шести союзам направлений,
таймеры ГОСТ, таксономия E1–E6, шесть компетенций радара. make types гоняет
их через JSON Schema в generated.ts, тест ловит забытую регенерацию.
Стенд: docker compose postgres + backend, health отвечает, база досягаема
из контейнера бэкенда. Makefile не врёт — нереализованные цели падают
и называют карточку, которая их закроет.
frontend/.npmrc: под WSL2 npm install зависает на дефолтных 15 сокетах.
2026-09-15 19:35:03 +03:00
|
|
|
|
class Level(StrEnum):
|
|
|
|
|
|
"""Уровень сложности сценария."""
|
|
|
|
|
|
|
|
|
|
|
|
L1 = "L1"
|
|
|
|
|
|
L2 = "L2"
|
|
|
|
|
|
L3 = "L3"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
DDS_LABELS: dict[DDSCode, str] = {
|
|
|
|
|
|
DDSCode.FIRE: "01 — МЧС",
|
|
|
|
|
|
DDSCode.POLICE: "02 — полиция",
|
|
|
|
|
|
DDSCode.MEDICAL: "03 — скорая помощь",
|
|
|
|
|
|
DDSCode.OTHER: "04 — прочие службы",
|
|
|
|
|
|
DDSCode.GKH: "ЖКХ",
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
INCIDENT_LABELS: dict[IncidentType, str] = {
|
|
|
|
|
|
IncidentType.FIRE: "Пожар",
|
|
|
|
|
|
IncidentType.MEDICAL: "Медицинский вызов",
|
|
|
|
|
|
IncidentType.POLICE: "Правонарушение",
|
|
|
|
|
|
IncidentType.OTHER: "Прочее",
|
|
|
|
|
|
IncidentType.GKH: "Авария ЖКХ",
|
|
|
|
|
|
IncidentType.ERA_GLONASS: "ДТП, автовызов ЭРА-ГЛОНАСС",
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#: Штатное соответствие типа происшествия и службы. Используется как значение
|
|
|
|
|
|
#: по умолчанию при выводе ground_truth сценария; сценарий вправе переопределить.
|
|
|
|
|
|
DDS_BY_INCIDENT: dict[IncidentType, DDSCode] = {
|
|
|
|
|
|
IncidentType.FIRE: DDSCode.FIRE,
|
|
|
|
|
|
IncidentType.MEDICAL: DDSCode.MEDICAL,
|
|
|
|
|
|
IncidentType.POLICE: DDSCode.POLICE,
|
|
|
|
|
|
IncidentType.OTHER: DDSCode.OTHER,
|
|
|
|
|
|
IncidentType.GKH: DDSCode.GKH,
|
|
|
|
|
|
IncidentType.ERA_GLONASS: DDSCode.MEDICAL,
|
|
|
|
|
|
}
|