// Разбор после звонка — главный учебный момент занятия. // // Ни одной отметки без обоснования: у каждой есть код, факт и норматив. // По каждому пропущенному пункту видно, каким был эталонный вопрос // (docs/product/DEBRIEF.md). import type { SessionReport } from "@/shared/types/generated"; import { Radar } from "./Radar"; export function Debrief({ report, big = false }: { report: SessionReport; big?: boolean }) { const questions = new Map(report.reference_questions.map((item) => [item.checklist_id, item.question])); const diff = report.self_assessment_diff; // Поля со значениями по умолчанию приходят из контракта необязательными. const unnoticed = diff?.unnoticed ?? []; const noticed = diff?.noticed ?? []; const overcautious = diff?.overcautious ?? []; const notes = report.notes ?? []; return (

Разбор · оценка {report.score_final.toFixed(0)} из 100 {report.overridden_by && ` · скорректировано (${report.overridden_by}), автооценка ${report.score_auto.toFixed(0)}`}

Скачать отчёт: CSV {" · "}PDF

{report.passed ? "Зачёт" : "Не зачтено"}: нарушено {report.failed_metrics} метрик, допустимо {report.criteria.allowed_errors}. Лимит решения ДДС — {` ${report.criteria.decision_time_limit_seconds} с`}; грамматика {report.criteria.require_correct_grammar ? " входит" : " не входит"} в оценку.

{Object.keys(report.criteria.score_weights ?? {}).length > 0 &&

Преподаватель переопределил веса: {Object.entries(report.criteria.score_weights ?? {}) .map(([key, weight]) => `${key} — ${weight}`).join("; ")}.

}

Нормативы и факты

{report.metrics.map((metric) => ( ))}
{metric.title} {metric.fact} · норматив {metric.norm} {` · вес ${metric.weight ?? 1}`} {metric.ref && ({metric.ref})}

Отметки

{report.findings.map((finding, index) => ( ))} {report.findings.length === 0 && }
{finding.code} {finding.summary}
{finding.fact}{finding.norm && ` · ${finding.norm}`}
ошибок не найдено

Компетенции

{report.missed_checklist.length > 0 && ( <>

Пропущенные вопросы

{report.missed_checklist.map((id) => ( ))}
{id} эталонный вопрос: «{questions.get(id)}»
)} {diff && ( <>

Самооценка

{report.self_assessment?.comment && ( )}
Не заметил, что пропустил {unnoticed.map((id) => questions.get(id) ?? id).join("; ") || "—"}
Заметил сам {noticed.map((id) => questions.get(id) ?? id).join("; ") || "—"}
Отметил зря — спрашивал {overcautious.map((id) => questions.get(id) ?? id).join("; ") || "—"}
Комментарий курсанта{report.self_assessment.comment}
)} {report.hints_used.length > 0 && ( <>

Использованные подсказки

{report.hints_used.map((hint, index) => ( ))}
{hint.checklist_id}{hint.question}
)}

Транскрипт

{report.transcript.map((line) => { const marks = report.findings.filter((finding) => finding.transcript_ref === line.ref); const note = notes.find((item) => item.transcript_ref === line.ref); return ( ); })}
{line.speaker === "caller" ? "звонящий" : "оператор"} {line.text} {marks.map((mark, index) => (
{mark.code}: {mark.summary}
))} {note &&
пометка преподавателя: {note.text}
}
); }