feat: статусы реагирования на АРМ ДДС и ошибки диспетчера D1–D6 (lct-33)
ТЗ называет обучаемого оператором ДДС, а его работа в системе-112 состоит из одного действия: получить карточку и правильно проставить статус реагирования с комментарием. Памятка заказчика посвящена этому целиком. Наш АРМ умел два статуса из девяти. - domain/statuses.py: девять статусов реагирования с автоматом переходов, семь статусов карточки, обязательные комментарии к отказам. Формулировки из памятки дословно — диспетчер должен узнать слова своего боевого АРМ. - Автомат на сервере: фронт рисует только пришедшее в available. Отвергнутая отметка не попадает в журнал и возвращается текстом для курсанта. - scoring/dispatcher.py: D1, D2, D3, D4, D6 детерминированно. D3 (отказ от профильного происшествия) проверяется по списку оповещения из ЕКП — без классификатора его было бы не на чем посчитать. D5 оставлен судье. - Отметки D идут в отчёт рядом с E: в живой цепочке 112 → ДДС участвуют обе роли. - Экран ДДС: таблица служб со статусами, поле комментария у отказов, журнал отметок, статус карточки красным в трёх случаях из семи. Сквозной тест повис на ожидании station.state и вскрыл продуктовый дефект: снимок уходил только в ответ на действие диспетчера, то есть список оповещения он видел лишь после того, как что-то нажмёт. Теперь station.state отправляется сразу за card.received. Упрощения записаны в карточке: статусы «Проверена» и «Не завершено» не считаются — первый требует главного специалиста, второй 48 часов. 148 тестов зелёных (23 новых), make typecheck чистый.
This commit is contained in:
parent
842a333d16
commit
d4f0d0a0f8
14 changed files with 953 additions and 9 deletions
|
|
@ -12,18 +12,32 @@ from pydantic import BaseModel
|
|||
|
||||
|
||||
class ErrorCode(StrEnum):
|
||||
"""E — ошибки приёма вызова, D — ошибки диспетчера ДДС.
|
||||
|
||||
Две роли, две таксономии. D1–D6 взяты из памятки заказчика дословно:
|
||||
она перечисляет типовые нарушения с реальными примерами, и преподаватель
|
||||
узнаёт их формулировки (docs/spec/DATASET.md).
|
||||
"""
|
||||
|
||||
E1 = "E1"
|
||||
E2 = "E2"
|
||||
E3 = "E3"
|
||||
E4 = "E4"
|
||||
E5 = "E5"
|
||||
E6 = "E6"
|
||||
D1 = "D1"
|
||||
D2 = "D2"
|
||||
D3 = "D3"
|
||||
D4 = "D4"
|
||||
D5 = "D5"
|
||||
D6 = "D6"
|
||||
|
||||
|
||||
class FindingSource(StrEnum):
|
||||
"""Кто выставил отметку. `judge` — единственный недетерминированный источник."""
|
||||
|
||||
SLOTS = "slots"
|
||||
DISPATCHER = "dispatcher"
|
||||
GROUND_TRUTH = "ground_truth"
|
||||
TIMERS = "timers"
|
||||
KIO = "kio"
|
||||
|
|
@ -76,6 +90,42 @@ ERRORS: dict[ErrorCode, ErrorSpec] = {
|
|||
detail="Карточка ушла в ДДС непригодной, снятие с контроля до подтверждения",
|
||||
source=FindingSource.CHAIN,
|
||||
),
|
||||
ErrorCode.D1: ErrorSpec(
|
||||
code=ErrorCode.D1,
|
||||
title="Статус реагирования не проставлен",
|
||||
detail="Карточка осталась без первичного статуса и ушла в «Не оповещено»",
|
||||
source=FindingSource.DISPATCHER,
|
||||
),
|
||||
ErrorCode.D2: ErrorSpec(
|
||||
code=ErrorCode.D2,
|
||||
title="Статус не соответствует факту",
|
||||
detail="«Принята» там, где работы проводиться не будут, и наоборот",
|
||||
source=FindingSource.DISPATCHER,
|
||||
),
|
||||
ErrorCode.D3: ErrorSpec(
|
||||
code=ErrorCode.D3,
|
||||
title="Отказ от профильного происшествия",
|
||||
detail="Служба есть в списке оповещения, значит происшествие её — отказ неправомерен",
|
||||
source=FindingSource.DISPATCHER,
|
||||
),
|
||||
ErrorCode.D4: ErrorSpec(
|
||||
code=ErrorCode.D4,
|
||||
title="Нет комментария к отказу",
|
||||
detail="«Не принята» и «Отказ от выполнения работ» без причины",
|
||||
source=FindingSource.DISPATCHER,
|
||||
),
|
||||
ErrorCode.D5: ErrorSpec(
|
||||
code=ErrorCode.D5,
|
||||
title="Неполный комментарий",
|
||||
detail="Не указано, куда передана информация и что сделал диспетчер",
|
||||
source=FindingSource.JUDGE,
|
||||
),
|
||||
ErrorCode.D6: ErrorSpec(
|
||||
code=ErrorCode.D6,
|
||||
title="Нет статусов хода работ",
|
||||
detail="Реагирование шло, но начало, прибытие и завершение не отмечены",
|
||||
source=FindingSource.DISPATCHER,
|
||||
),
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue