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 чистый.
This commit is contained in:
parent
d4f0d0a0f8
commit
b8dc39fd7d
22 changed files with 628 additions and 9 deletions
|
|
@ -13,6 +13,7 @@ import { CALLER_RATE, Playback } from "@/shared/audio/playback";
|
|||
import { type CardState, applyPatch, edit, empty as emptyCard } from "@/features/kio-card/merge";
|
||||
import type { ChecklistItem } from "@/features/self-assessment/SelfAssessment";
|
||||
import type {
|
||||
Outcome,
|
||||
CallIncoming,
|
||||
DDSCode,
|
||||
ServerToTrainee,
|
||||
|
|
@ -186,12 +187,20 @@ export function useCall(sessionId: string | null) {
|
|||
channel.current?.send({ type: "dds.dispatch", service });
|
||||
}, []);
|
||||
|
||||
/** Закрыть вызов не карточкой: справкой или передачей в другой регион.
|
||||
* Отдельное действие, а не «положил трубку»: система должна отличить
|
||||
* осознанное решение от брошенного вызова (docs/spec/TICKETS.md). */
|
||||
const resolve = useCallback((outcome: Outcome, comment: string) => {
|
||||
channel.current?.send({ type: "call.resolve", outcome, comment });
|
||||
}, []);
|
||||
|
||||
const submitSelfAssessment = useCallback((missed: string[], comment: string) => {
|
||||
channel.current?.send({ type: "self_assessment.submit", missed, comment });
|
||||
setSelfAssessed(true);
|
||||
}, []);
|
||||
|
||||
return {
|
||||
resolve,
|
||||
status, phase, incoming, lines, timers, callerSpeaking, micOn, error, card,
|
||||
checklist, selfAssessed, scoreReady, report,
|
||||
answer, hangup, hint, patchKio, dispatch, submitSelfAssessment,
|
||||
|
|
|
|||
Loading…
Reference in a new issue