lct-50: таймеры ДДС — 30 с до открытия карточки, 3 минуты до первой записи
This commit is contained in:
parent
8ff51a8955
commit
51ef99c472
18 changed files with 169 additions and 169 deletions
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"dds_several_cards": {
|
||||
"score_auto": 53.3,
|
||||
"score_auto": 65.3,
|
||||
"card_status": "processed",
|
||||
"metrics": [
|
||||
[
|
||||
|
|
@ -13,7 +13,7 @@
|
|||
],
|
||||
[
|
||||
"dds_ack",
|
||||
"Карточка 1: Служба 101: первичная отметка за 30 с",
|
||||
"Карточка 1: Служба 101: открытие карточки за 30 с",
|
||||
"0.0 с",
|
||||
true,
|
||||
1.0,
|
||||
|
|
@ -61,11 +61,11 @@
|
|||
],
|
||||
[
|
||||
"dds_work_time",
|
||||
"Карточка 1: Отработка карточки ДДС",
|
||||
"карточка не завершена; 0 с (на 180 с быстрее норматива)",
|
||||
false,
|
||||
"Карточка 1: Первая запись по карточке ДДС",
|
||||
"0 с (на 180 с быстрее норматива)",
|
||||
true,
|
||||
1.5,
|
||||
0.0
|
||||
1.0
|
||||
],
|
||||
[
|
||||
"dds_primary",
|
||||
|
|
@ -77,7 +77,7 @@
|
|||
],
|
||||
[
|
||||
"dds_ack",
|
||||
"Карточка 2: СМП: первичная отметка за 30 с",
|
||||
"Карточка 2: СМП: открытие карточки за 30 с",
|
||||
"0.0 с",
|
||||
true,
|
||||
1.0,
|
||||
|
|
@ -125,11 +125,11 @@
|
|||
],
|
||||
[
|
||||
"dds_work_time",
|
||||
"Карточка 2: Отработка карточки ДДС",
|
||||
"карточка не завершена; 0 с (на 180 с быстрее норматива)",
|
||||
false,
|
||||
"Карточка 2: Первая запись по карточке ДДС",
|
||||
"0 с (на 180 с быстрее норматива)",
|
||||
true,
|
||||
1.5,
|
||||
0.0
|
||||
1.0
|
||||
],
|
||||
[
|
||||
"dds_primary",
|
||||
|
|
@ -141,7 +141,7 @@
|
|||
],
|
||||
[
|
||||
"dds_ack",
|
||||
"Карточка 3: Служба 101: первичная отметка за 30 с",
|
||||
"Карточка 3: Служба 101: открытие карточки за 30 с",
|
||||
"0.0 с",
|
||||
true,
|
||||
1.0,
|
||||
|
|
@ -189,11 +189,11 @@
|
|||
],
|
||||
[
|
||||
"dds_work_time",
|
||||
"Карточка 3: Отработка карточки ДДС",
|
||||
"карточка не завершена; 0 с (на 180 с быстрее норматива)",
|
||||
false,
|
||||
"Карточка 3: Первая запись по карточке ДДС",
|
||||
"0 с (на 180 с быстрее норматива)",
|
||||
true,
|
||||
1.5,
|
||||
0.0
|
||||
1.0
|
||||
]
|
||||
],
|
||||
"findings": [
|
||||
|
|
@ -207,11 +207,6 @@
|
|||
"Карточка 1: Служба 101: ход реагирования не доведён до конца",
|
||||
"не отмечены: Прибытие, Проведение работ"
|
||||
],
|
||||
[
|
||||
"E3",
|
||||
"Карточка 1: ДДС: норматив времени отработки карточки не выполнен",
|
||||
"карточка не завершена; 0 с (на 180 с быстрее норматива)"
|
||||
],
|
||||
[
|
||||
"D2",
|
||||
"Карточка 2: СМП: «Принята» без назначения бригады и хода реагирования",
|
||||
|
|
@ -222,11 +217,6 @@
|
|||
"Карточка 2: СМП: ход реагирования не доведён до конца",
|
||||
"не отмечены: Начало реагирования, Прибытие, Проведение работ"
|
||||
],
|
||||
[
|
||||
"E3",
|
||||
"Карточка 2: ДДС: норматив времени отработки карточки не выполнен",
|
||||
"карточка не завершена; 0 с (на 180 с быстрее норматива)"
|
||||
],
|
||||
[
|
||||
"D5",
|
||||
"Карточка 3: Служба 101: комментарии к статусам не разделяют основание и сведения",
|
||||
|
|
@ -236,17 +226,12 @@
|
|||
"D6",
|
||||
"Карточка 3: Служба 101: ход реагирования не доведён до конца",
|
||||
"не отмечены: Прибытие, Проведение работ"
|
||||
],
|
||||
[
|
||||
"E3",
|
||||
"Карточка 3: ДДС: норматив времени отработки карточки не выполнен",
|
||||
"карточка не завершена; 0 с (на 180 с быстрее норматива)"
|
||||
]
|
||||
],
|
||||
"cards": [
|
||||
[
|
||||
"fire-apartment-l2",
|
||||
56.0,
|
||||
68.0,
|
||||
"Принято, бригада направлена",
|
||||
[
|
||||
"card.ack",
|
||||
|
|
@ -259,7 +244,7 @@
|
|||
],
|
||||
[
|
||||
"t20-2-stroke",
|
||||
48.0,
|
||||
60.0,
|
||||
"",
|
||||
[
|
||||
"card.ack",
|
||||
|
|
@ -268,7 +253,7 @@
|
|||
],
|
||||
[
|
||||
"t01-1-fire-container",
|
||||
56.0,
|
||||
68.0,
|
||||
"",
|
||||
[
|
||||
"card.ack",
|
||||
|
|
@ -281,7 +266,7 @@
|
|||
]
|
||||
},
|
||||
"dds_early_finish": {
|
||||
"score_auto": 35.3,
|
||||
"score_auto": 44.1,
|
||||
"card_status": "processed",
|
||||
"metrics": [
|
||||
[
|
||||
|
|
@ -294,7 +279,7 @@
|
|||
],
|
||||
[
|
||||
"dds_ack",
|
||||
"Карточка 1: СМП: первичная отметка за 30 с",
|
||||
"Карточка 1: СМП: открытие карточки за 30 с",
|
||||
"0.0 с",
|
||||
true,
|
||||
1.0,
|
||||
|
|
@ -342,11 +327,11 @@
|
|||
],
|
||||
[
|
||||
"dds_work_time",
|
||||
"Карточка 1: Отработка карточки ДДС",
|
||||
"карточка не завершена; 0 с (на 180 с быстрее норматива)",
|
||||
false,
|
||||
"Карточка 1: Первая запись по карточке ДДС",
|
||||
"0 с (на 180 с быстрее норматива)",
|
||||
true,
|
||||
1.5,
|
||||
0.0
|
||||
1.0
|
||||
],
|
||||
[
|
||||
"dds_primary",
|
||||
|
|
@ -358,16 +343,16 @@
|
|||
],
|
||||
[
|
||||
"dds_ack",
|
||||
"Карточка 2: Служба 101: первичная отметка за 30 с",
|
||||
"не отмечено",
|
||||
"Карточка 2: Служба 101: открытие карточки за 30 с",
|
||||
"карточка не открыта",
|
||||
false,
|
||||
1.0,
|
||||
null
|
||||
],
|
||||
[
|
||||
"dds_work_time",
|
||||
"Карточка 2: Отработка карточки ДДС",
|
||||
"карточка не завершена; время обработки не зафиксировано",
|
||||
"Карточка 2: Первая запись по карточке ДДС",
|
||||
"первая запись не добавлена; карточка не открыта",
|
||||
false,
|
||||
1.5,
|
||||
0.0
|
||||
|
|
@ -385,25 +370,25 @@
|
|||
"не отмечены: Начало реагирования, Прибытие, Проведение работ"
|
||||
],
|
||||
[
|
||||
"E3",
|
||||
"Карточка 1: ДДС: норматив времени отработки карточки не выполнен",
|
||||
"карточка не завершена; 0 с (на 180 с быстрее норматива)"
|
||||
"D1",
|
||||
"Карточка 2: Служба 101: карточка не открыта",
|
||||
"карточка не открыта до конца занятия"
|
||||
],
|
||||
[
|
||||
"D1",
|
||||
"Карточка 2: Служба 101: статус реагирования не проставлен",
|
||||
"карточка осталась без отметки"
|
||||
"карточка осталась без первичного статуса"
|
||||
],
|
||||
[
|
||||
"E3",
|
||||
"Карточка 2: ДДС: норматив времени отработки карточки не выполнен",
|
||||
"карточка не завершена; время обработки не зафиксировано"
|
||||
"Карточка 2: ДДС: первая запись по карточке позже норматива",
|
||||
"первая запись не добавлена; карточка не открыта"
|
||||
]
|
||||
],
|
||||
"cards": [
|
||||
[
|
||||
"t20-2-stroke",
|
||||
48.0,
|
||||
60.0,
|
||||
"",
|
||||
[
|
||||
"card.ack",
|
||||
|
|
@ -419,7 +404,7 @@
|
|||
]
|
||||
},
|
||||
"handoff_112_to_dds": {
|
||||
"score_auto": 47.8,
|
||||
"score_auto": 56.5,
|
||||
"card_status": "processed",
|
||||
"metrics": [
|
||||
[
|
||||
|
|
@ -480,7 +465,7 @@
|
|||
],
|
||||
[
|
||||
"dds_ack",
|
||||
"Карточка 1: Служба 101: первичная отметка за 30 с",
|
||||
"Карточка 1: Служба 101: открытие карточки за 30 с",
|
||||
"0.0 с",
|
||||
true,
|
||||
1.0,
|
||||
|
|
@ -528,11 +513,11 @@
|
|||
],
|
||||
[
|
||||
"dds_work_time",
|
||||
"Карточка 1: Отработка карточки ДДС",
|
||||
"карточка не завершена; 0 с (на 180 с быстрее норматива)",
|
||||
false,
|
||||
"Карточка 1: Первая запись по карточке ДДС",
|
||||
"0 с (на 180 с быстрее норматива)",
|
||||
true,
|
||||
1.5,
|
||||
0.0
|
||||
1.0
|
||||
],
|
||||
[
|
||||
"dds_primary",
|
||||
|
|
@ -544,7 +529,7 @@
|
|||
],
|
||||
[
|
||||
"dds_ack",
|
||||
"Карточка 2: Служба 101: первичная отметка за 30 с",
|
||||
"Карточка 2: Служба 101: открытие карточки за 30 с",
|
||||
"0.0 с",
|
||||
true,
|
||||
1.0,
|
||||
|
|
@ -592,11 +577,11 @@
|
|||
],
|
||||
[
|
||||
"dds_work_time",
|
||||
"Карточка 2: Отработка карточки ДДС",
|
||||
"карточка не завершена; 0 с (на 180 с быстрее норматива)",
|
||||
false,
|
||||
"Карточка 2: Первая запись по карточке ДДС",
|
||||
"0 с (на 180 с быстрее норматива)",
|
||||
true,
|
||||
1.5,
|
||||
0.0
|
||||
1.0
|
||||
]
|
||||
],
|
||||
"findings": [
|
||||
|
|
@ -630,11 +615,6 @@
|
|||
"Карточка 1: Служба 101: ход реагирования не доведён до конца",
|
||||
"не отмечены: Прибытие, Проведение работ"
|
||||
],
|
||||
[
|
||||
"E3",
|
||||
"Карточка 1: ДДС: норматив времени отработки карточки не выполнен",
|
||||
"карточка не завершена; 0 с (на 180 с быстрее норматива)"
|
||||
],
|
||||
[
|
||||
"D2",
|
||||
"Карточка 2: Служба 101: «Принята» без назначения бригады и хода реагирования",
|
||||
|
|
@ -644,17 +624,12 @@
|
|||
"D6",
|
||||
"Карточка 2: Служба 101: ход реагирования не доведён до конца",
|
||||
"не отмечены: Начало реагирования, Прибытие, Проведение работ"
|
||||
],
|
||||
[
|
||||
"E3",
|
||||
"Карточка 2: ДДС: норматив времени отработки карточки не выполнен",
|
||||
"карточка не завершена; 0 с (на 180 с быстрее норматива)"
|
||||
]
|
||||
],
|
||||
"cards": [
|
||||
[
|
||||
"fire-apartment-l2",
|
||||
56.0,
|
||||
68.0,
|
||||
"",
|
||||
[
|
||||
"card.ack",
|
||||
|
|
@ -666,7 +641,7 @@
|
|||
],
|
||||
[
|
||||
"t01-1-fire-container",
|
||||
48.0,
|
||||
60.0,
|
||||
"",
|
||||
[
|
||||
"card.ack",
|
||||
|
|
@ -745,7 +720,7 @@
|
|||
],
|
||||
[
|
||||
"dds_ack",
|
||||
"Служба 101: первичная отметка за 30 с",
|
||||
"Служба 101: открытие карточки за 30 с",
|
||||
"0.0 с",
|
||||
true,
|
||||
1.0,
|
||||
|
|
|
|||
|
|
@ -56,8 +56,9 @@ def fire():
|
|||
|
||||
def accept_with_crew(state: SessionState, card) -> None:
|
||||
service = state.card_services(card)[0]
|
||||
card.on_event("dds.open") # карточка открыта: 30 с остановлены
|
||||
card.set_service_status(service, ServiceStatus.ACCEPTED, "Принято в работу")
|
||||
card.on_event("card.ack")
|
||||
card.on_event("dds.record")
|
||||
card.crew_selected = state.crew_options(card)[0]
|
||||
card.crew_assignments[service] = card.crew_selected
|
||||
card.dds_log.append(("crew.select", now_utc(), card.crew_selected))
|
||||
|
|
|
|||
|
|
@ -443,11 +443,13 @@ def test_instructor_criteria_change_timer_and_success_threshold(client, monkeypa
|
|||
reply_metric = next(item for item in score["metrics"] if item["key"] == "dds_reply")
|
||||
assert reply_metric["passed"]
|
||||
assert not any(item["key"] == "dds_grammar" for item in score["metrics"])
|
||||
# 3 минуты — до первой записи, а она сделана сразу: незавершённая
|
||||
# работа по времени не штрафуется (ответ заказчика, П.5).
|
||||
assert (
|
||||
next(item for item in score["metrics"] if item["key"] == "dds_work_time")[
|
||||
"passed"
|
||||
]
|
||||
is False
|
||||
is True
|
||||
)
|
||||
report = client.get(f"/api/sessions/{session_id}/report").json()
|
||||
assert report["criteria"] == {
|
||||
|
|
@ -500,9 +502,8 @@ def test_dds_statuses_do_not_require_phone_reports(client):
|
|||
finding["code"] == "D2" and "бригады" in finding["summary"]
|
||||
for finding in score["findings"]
|
||||
)
|
||||
assert any(
|
||||
finding["code"] == "E3" and "времени отработки" in finding["summary"]
|
||||
for finding in score["findings"]
|
||||
assert not any(finding["code"] == "E3" for finding in score["findings"]), (
|
||||
"первая запись сделана сразу: дальше работы по времени не нормируются"
|
||||
)
|
||||
finding_codes = {finding["code"] for finding in score["findings"]}
|
||||
penalty_codes = {
|
||||
|
|
@ -703,22 +704,26 @@ def test_complete_dds_workflow_scores_100_with_assignment_without_call(client):
|
|||
control.__exit__(None, None, None)
|
||||
|
||||
|
||||
def test_dds_card_over_three_minutes_has_e3_finding_and_actual_deviation(client):
|
||||
def test_late_first_record_has_e3_and_long_work_after_it_does_not(client):
|
||||
"""П.5: 3 минуты — на открытие и первую запись; дальше работы идут часы."""
|
||||
session_id, control = start(
|
||||
client, criteria={"dds_card_work_time_limit_seconds": 60}
|
||||
)
|
||||
try:
|
||||
state = hub.get(session_id)
|
||||
with client.websocket_connect(f"/ws/station/{session_id}") as station:
|
||||
read_until(station, "card.received")
|
||||
received = read_until(station, "card.received")
|
||||
snapshot = read_until(station, "station.state")["snapshot"]
|
||||
service = snapshot["services"][0]
|
||||
station.send_json({"type": "card.open", "card_id": received["card"]["card_id"]})
|
||||
read_until(station, "station.state")
|
||||
assert state.desk.active.timers.measured_ms(TimerCode.DDS_ACK) is not None
|
||||
state.desk.active.timers.timers[TimerCode.DDS_WORK].started_at = time.monotonic() - 61
|
||||
station.send_json(
|
||||
{"type": "card.status", "service": service, "status": "accepted",
|
||||
"comment": "Основание: доклад старшего.\nСведения: карточка принята."}
|
||||
)
|
||||
snapshot = read_until(station, "station.state")["snapshot"]
|
||||
state.desk.active.timers.timers[TimerCode.DDS_WORK].started_at = time.monotonic() - 61
|
||||
crew = next(
|
||||
option
|
||||
for option in snapshot["crew_options"]
|
||||
|
|
@ -740,8 +745,8 @@ def test_dds_card_over_three_minutes_has_e3_finding_and_actual_deviation(client)
|
|||
)
|
||||
assert not metric["passed"]
|
||||
assert "61 с" in metric["fact"] and "+1 с" in metric["fact"]
|
||||
finding = next(item for item in score["findings"] if item["code"] == "E3")
|
||||
assert "времени отработки карточки" in finding["summary"]
|
||||
findings = [item for item in score["findings"] if item["code"] == "E3"]
|
||||
assert len(findings) == 1 and "первая запись" in findings[0]["summary"]
|
||||
finally:
|
||||
control.__exit__(None, None, None)
|
||||
|
||||
|
|
@ -916,7 +921,9 @@ def test_concurrent_dds_cards_keep_independent_state_and_timers(client):
|
|||
item["key"] == "dds_grammar"
|
||||
for item in state.score["metrics"]
|
||||
)
|
||||
assert any(item["code"] == "E3" for item in state.score["findings"])
|
||||
assert not any(item["code"] == "E3" for item in state.score["findings"]), (
|
||||
"обе карточки получили первую запись сразу"
|
||||
)
|
||||
report = client.get(f"/api/sessions/{session_id}/report").json()
|
||||
assert report["scenario_id"] == "fire-apartment-l2"
|
||||
assert len(report["card_results"]) == 2
|
||||
|
|
|
|||
|
|
@ -143,8 +143,9 @@ def test_concurrent_dds_queue_round_trips_with_each_timer_and_status():
|
|||
first_card = state.desk.active
|
||||
first_id = first_card.card_id
|
||||
first_service = state.card_services(first_card)[0]
|
||||
first_card.on_event("dds.open") # карточка открыта: 30 с остановлены
|
||||
first_card.set_service_status(first_service, ServiceStatus.ACCEPTED, "Принято в работу")
|
||||
first_card.on_event("card.ack")
|
||||
first_card.on_event("dds.record")
|
||||
second_id = state.desk.ordered()[1].card_id
|
||||
assert state.desk.open(second_id)
|
||||
|
||||
|
|
|
|||
|
|
@ -62,19 +62,21 @@ def test_card_fill_time_metric_texts(elapsed_ms, completed, fact, passed):
|
|||
(605_000, True, "605 с (+425 с сверх норматива)", False),
|
||||
(25_000, True, "25 с (на 155 с быстрее норматива)", True),
|
||||
(180_000, True, "180 с (точно в норматив)", True),
|
||||
(None, False, "карточка не завершена; время обработки не зафиксировано", False),
|
||||
(25_000, False, "карточка не завершена; 25 с (на 155 с быстрее норматива)", False),
|
||||
(None, False, "первая запись не добавлена; карточка не открыта", False),
|
||||
(25_000, False, "первая запись не добавлена; 25 с (на 155 с быстрее норматива)", False),
|
||||
],
|
||||
)
|
||||
def test_dds_work_time_metric_texts(elapsed_ms, completed, fact, passed):
|
||||
metric, finding = time_metric(DDS_WORK_TIME, elapsed_ms, 180_000, completed=completed)
|
||||
|
||||
assert metric.key == "dds_work_time"
|
||||
assert metric.title == "Отработка карточки ДДС"
|
||||
assert metric.title == "Первая запись по карточке ДДС"
|
||||
assert metric.fact == fact
|
||||
assert metric.norm == "завершить за 180 с"
|
||||
assert metric.norm == "открыть карточку и добавить первую запись (статус и текст) за 180 с"
|
||||
assert metric.passed is passed
|
||||
assert (finding is None) is passed
|
||||
if finding is not None:
|
||||
assert finding.summary == "ДДС: норматив времени отработки карточки не выполнен"
|
||||
assert (finding.fact, finding.norm) == (fact, "завершить за 180 с")
|
||||
assert finding.summary == "ДДС: первая запись по карточке позже норматива"
|
||||
assert (finding.fact, finding.norm) == (
|
||||
fact, "открыть карточку и добавить первую запись (статус и текст) за 180 с"
|
||||
)
|
||||
|
|
|
|||
Loading…
Reference in a new issue