397777089e
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
37 lines
2.2 KiB
JavaScript
37 lines
2.2 KiB
JavaScript
#!/usr/bin/env node
|
|
/**
|
|
* question-slots — трекинг заданных вопросов разговорной фазы как СЛОТОВ с id
|
|
* (условие R7 spec 2026-06-05): механическая проверка «нет повисших вопросов»
|
|
* работает только если вопрос помечается слотом (задан/отвечен), а не вольным
|
|
* текстом. Чистый модуль, иммутабельные операции ($0, без LLM).
|
|
*/
|
|
|
|
function isNonEmptyString(v) { return typeof v === 'string' && v.trim().length > 0; }
|
|
|
|
/** Добавить заданный вопрос (новый слот answered:false). id — непустой уникальный. */
|
|
export function addQuestion(slots, { id, text } = {}) {
|
|
const list = Array.isArray(slots) ? slots : [];
|
|
if (!isNonEmptyString(id)) throw new Error('question id: непустая строка обязательна');
|
|
if (!isNonEmptyString(text)) throw new Error('question text: непустая строка обязательна');
|
|
if (list.some((s) => s.id === id)) throw new Error(`question id дублируется: ${id}`);
|
|
return [...list, { id, text, answered: false, answer: null }];
|
|
}
|
|
|
|
/** Пометить вопрос отвеченным (непустой ответ). Неизвестный id → ошибка. */
|
|
export function answerQuestion(slots, id, answer) {
|
|
const list = Array.isArray(slots) ? slots : [];
|
|
if (!list.some((s) => s.id === id)) throw new Error(`неизвестный question id: ${id}`);
|
|
if (!isNonEmptyString(answer)) throw new Error('answer: непустая строка обязательна');
|
|
return list.map((s) => (s.id === id ? { ...s, answered: true, answer } : s));
|
|
}
|
|
|
|
/** Повисшие вопросы — заданные, но не отвеченные. */
|
|
export function hangingQuestions(slots) {
|
|
return (Array.isArray(slots) ? slots : []).filter((s) => !s.answered);
|
|
}
|
|
|
|
/** Ни один заданный вопрос не повис (пустой список → true, вопросов нет). */
|
|
export function allAnswered(slots) {
|
|
return hangingQuestions(slots).length === 0;
|
|
}
|