feat(assistant): контент по всем разделам, FAQ x5, поиск по платформе, умный проактив
Контент: контекстные подсказки на ВСЕ разделы (PAGE_HINTS), «Совет дня» (ротация), FAQ расширен ~10 -> ~50 записей по всем фичам. «Спроси Квантика» теперь ищет и по платформе (LS.globalSearch) рядом с FAQ. Умный проактив: weakSubject (слабый предмет по тестам, /api/assistant/context) -> «потренируемся» и daily-plan (план на сегодня из квестов и карточек к повторению). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -11,36 +11,57 @@ const db = require('../db/db');
|
||||
/* Корпус справки для «Спроси Квантика» (поиск по ключевым словам в ask()).
|
||||
* Это же место — контекст для будущей локальной модели (см. ask). Правьте свободно. */
|
||||
const FAQ = [
|
||||
{ id: 'clip-textbook', q: 'Как сохранить кусок учебника?',
|
||||
a: 'На странице учебника нажми «Вырезать область» (внизу), выдели фрагмент — он сохранится картинкой в «Мои материалы».',
|
||||
url: '/my-materials', keywords: ['учебник', 'вырезать', 'область', 'скриншот', 'фрагмент', 'сохранить', 'картинк', 'материал'] },
|
||||
{ id: 'materials-folders', q: 'Как разложить материалы по папкам?',
|
||||
a: 'В «Мои материалы» нажми «+ папка», затем у карточки выбери папку. Можно фильтровать по папкам и типам.',
|
||||
url: '/my-materials', keywords: ['папк', 'материал', 'коллекци', 'разложить', 'сортиров', 'фильтр'] },
|
||||
{ id: 'materials-annotate', q: 'Как рисовать поверх фото?',
|
||||
a: 'Открой материал-картинку и нажми кнопку с карандашом-линейкой — откроется редактор. Сохранение обновит ту же карточку.',
|
||||
url: '/my-materials', keywords: ['рисовать', 'аннотир', 'поверх', 'фото', 'карандаш', 'разметк', 'редактир'] },
|
||||
{ id: 'flashcards', q: 'Как работают флешкарты?',
|
||||
a: 'Создай колоду, добавь карточки (вопрос/ответ, можно картинку и формулы KaTeX). Система сама напомнит, что пора повторить.',
|
||||
url: '/flashcards', keywords: ['флешкарт', 'карточк', 'колод', 'повтор', 'память', 'katex', 'формул'] },
|
||||
{ id: 'exam-modes', q: 'Чем отличаются режимы экзамена?',
|
||||
a: 'Экзамен — как на ЦТ/ЦЭ, на время. Тренировка — с разбором после каждого ответа. Случайный — быстрый набор вопросов.',
|
||||
url: '/exam-prep', keywords: ['экзамен', 'режим', 'тренировк', 'случайн', 'цт', 'цэ', 'тест'] },
|
||||
{ id: 'board-tools', q: 'Что умеет доска?',
|
||||
a: 'Карандаш, маркер, лазер, фигуры, соединители, стикеры, текст, формулы KaTeX, таблицы, линейка и транспортир. «Выделение» двигает и поворачивает объекты.',
|
||||
url: '/board', keywords: ['доск', 'инструмент', 'рисов', 'фигур', 'линейк', 'маркер', 'whiteboard'] },
|
||||
{ id: 'pet', q: 'Зачем нужен питомец и XP?',
|
||||
a: 'Квантик растёт от твоей активности: за тесты, уроки и карточки идут XP и монеты. Серия за ежедневные занятия поднимает настроение и даёт бонусы.',
|
||||
url: '/pet', keywords: ['питомец', 'квантик', 'xp', 'опыт', 'монет', 'серия', 'streak', 'настроение', 'уровень'] },
|
||||
{ id: 'homework', q: 'Где мои домашние задания?',
|
||||
a: 'Все задания и дедлайны — в разделе «Домашние задания». Там же можно загрузить выполненную работу.',
|
||||
url: '/homework', keywords: ['домашк', 'домашн', 'задани', 'дедлайн', 'сдать', 'загрузить', 'работ'] },
|
||||
{ id: 'quick-lesson', q: 'Как создать один урок без курса?',
|
||||
a: 'В «Теории» нажми «Быстрый урок» — урок создастся в скрытом личном контейнере, его не видно в общем каталоге.',
|
||||
url: '/theory', keywords: ['урок', 'быстрый', 'без курса', 'создать', 'теори'] },
|
||||
{ id: 'lab', q: 'Как открыть симуляции?',
|
||||
a: 'В «Лаборатории» симуляции запускаются прямо в браузере — установка не нужна. Выбери предмет и опыт.',
|
||||
url: '/lab', keywords: ['лаборатори', 'симуляци', 'опыт', 'эксперимент', 'физик', 'хими'] },
|
||||
// ── Учебники / чтение ──
|
||||
{ id: 'clip-textbook', q: 'Как сохранить кусок учебника?', a: 'На странице учебника нажми «Вырезать область» (внизу), выдели фрагмент — он сохранится картинкой в «Мои материалы».', url: '/my-materials', keywords: ['учебник','вырезать','область','скриншот','фрагмент','сохранить','картинк'] },
|
||||
{ id: 'textbook-link', q: 'Как поделиться ссылкой на параграф?', a: 'Открой нужный параграф учебника и скопируй адрес из строки браузера — ссылка ведёт прямо на этот раздел.', url: '/textbooks', keywords: ['учебник','ссылк','параграф','поделит','раздел','deep'] },
|
||||
{ id: 'textbooks-where', q: 'Где учебники?', a: 'Раздел «Учебники» в меню. Внутри — главы и параграфы с теорией, формулами и задачами.', url: '/textbooks', keywords: ['учебник','теори','глава','параграф','книг'] },
|
||||
{ id: 'read-progress', q: 'Считается ли прогресс чтения?', a: 'Да — прочитанные параграфы отмечаются, прогресс по учебнику виден в самом учебнике и влияет на питомца.', url: '/textbooks', keywords: ['прогресс','чтени','прочит','отмет'] },
|
||||
// ── Тесты / экзамен ──
|
||||
{ id: 'exam-modes', q: 'Чем отличаются режимы экзамена?', a: 'Экзамен — как на ЦТ/ЦЭ, на время. Тренировка — с разбором после каждого ответа. Случайный — быстрый набор вопросов.', url: '/exam-prep/math9', keywords: ['экзамен','режим','тренировк','случайн','цт','цэ','тест'] },
|
||||
{ id: 'exam-start', q: 'Как начать тест?', a: 'Зайди в «Подготовка к экзамену», выбери тему и режим. Можно быстро стартовать тест и с дашборда.', url: '/exam-prep/math9', keywords: ['тест','начать','старт','экзамен','реши'] },
|
||||
{ id: 'exam-review', q: 'Как разобрать ошибки после теста?', a: 'После завершения теста доступен разбор: правильные ответы и решения по каждому заданию. В режиме тренировки разбор идёт сразу.', url: '/exam-prep/math9', keywords: ['ошибк','разбор','решени','ответ','проверк'] },
|
||||
{ id: 'results-where', q: 'Где мои результаты?', a: 'Последние результаты — на дашборде, история и проценты по предметам — там же в виджетах.', url: '/dashboard', keywords: ['результат','оценк','процент','истори','статистик'] },
|
||||
// ── Флешкарты ──
|
||||
{ id: 'flashcards', q: 'Как работают флешкарты?', a: 'Создай колоду, добавь карточки (вопрос/ответ, можно картинку и формулы KaTeX). Система сама напомнит, что пора повторить.', url: '/flashcards', keywords: ['флешкарт','карточк','колод','повтор','память'] },
|
||||
{ id: 'flashcards-katex', q: 'Как вставить формулу в карточку?', a: 'В редакторе карточки есть палитра KaTeX — выбирай символы или пиши LaTeX, превью покажет результат.', url: '/flashcards', keywords: ['формул','katex','latex','карточк','математ'] },
|
||||
{ id: 'flashcards-img', q: 'Можно ли картинку на карточке?', a: 'Да — при создании карточки загрузи изображение, оно отрендерится на лицевой или оборотной стороне.', url: '/flashcards', keywords: ['картинк','изображен','карточк','фото'] },
|
||||
{ id: 'flashcards-fab', q: 'Что за кнопка «Запомнить» в углу?', a: 'Это быстрый способ создать карточку из любого места платформы — плавающая кнопка справа внизу.', url: '/flashcards', keywords: ['запомнить','кнопк','быстр','карточк','fab'] },
|
||||
// ── Мои материалы ──
|
||||
{ id: 'materials-where', q: 'Что такое «Мои материалы»?', a: 'Личное хранилище: вырезки из учебника, страницы доски, заметки и рисунки. Хранятся у тебя, даже если урок удалят.', url: '/my-materials', keywords: ['материал','хранилищ','заметк','доск','вырезк'] },
|
||||
{ id: 'materials-folders', q: 'Как разложить материалы по папкам?', a: 'В «Мои материалы» нажми «+ папка», затем у карточки выбери папку. Можно фильтровать по папкам и типам.', url: '/my-materials', keywords: ['папк','материал','коллекци','разложить','сортиров','фильтр'] },
|
||||
{ id: 'materials-annotate', q: 'Как рисовать поверх фото?', a: 'Открой материал-картинку и нажми кнопку с карандашом-линейкой — откроется редактор. Сохранение обновит ту же карточку.', url: '/my-materials', keywords: ['рисовать','аннотир','поверх','фото','карандаш','разметк'] },
|
||||
{ id: 'materials-note', q: 'Как создать заметку?', a: 'В «Мои материалы» кнопка «Заметка» вверху. Заметку потом можно превратить во флешкарту.', url: '/my-materials', keywords: ['заметк','создать','текст','note'] },
|
||||
{ id: 'materials-view', q: 'Почему картинка открывается в окне?', a: 'Клик по материалу-картинке открывает её в просмотрщике на странице. Там же «Скачать» и «В новой вкладке».', url: '/my-materials', keywords: ['картинк','открыт','просмотр','окно','лайтбокс'] },
|
||||
// ── Доска / онлайн-урок ──
|
||||
{ id: 'board-tools', q: 'Что умеет доска?', a: 'Карандаш, маркер, лазер, фигуры, соединители, стикеры, текст, формулы KaTeX, таблицы, линейка и транспортир. «Выделение» двигает и поворачивает объекты.', url: '/board', keywords: ['доск','инструмент','рисов','фигур','линейк','маркер','whiteboard'] },
|
||||
{ id: 'board-save', q: 'Как сохранить доску себе?', a: 'На уроке или в архиве нажми «К себе» — страница доски сохранится в «Мои материалы». Можно сохранить и выделенную область.', url: '/my-materials', keywords: ['доск','сохранить','к себе','область','материал'] },
|
||||
{ id: 'classroom-join', q: 'Как попасть на онлайн-урок?', a: 'Когда учитель начинает урок, в меню «Онлайн-урок» появится приглашение — нажми, чтобы войти.', url: '/classroom', keywords: ['онлайн','урок','classroom','подключ','войти','вызов'] },
|
||||
{ id: 'classroom-materials', q: 'Сохранятся ли заметки с онлайн-урока?', a: 'Да — доску и заметки можно сохранить в «Мои материалы», они переживут окончание сессии.', url: '/my-materials', keywords: ['онлайн','урок','заметк','сохран','материал'] },
|
||||
// ── Теория / уроки ──
|
||||
{ id: 'theory', q: 'Что в разделе «Теория»?', a: 'Курсы и уроки с теорией и заданиями. Прогресс по урокам отслеживается.', url: '/theory', keywords: ['теори','курс','урок','обучен'] },
|
||||
{ id: 'quick-lesson', q: 'Как создать один урок без курса?', a: 'В «Теории» нажми «Быстрый урок» — урок создастся в скрытом личном контейнере, его не видно в общем каталоге.', url: '/theory', keywords: ['урок','быстрый','без курса','создать','теори'] },
|
||||
{ id: 'continue-lesson', q: 'Как продолжить с того же места?', a: 'На дашборде есть «Продолжить» с последним незаконченным уроком. Я тоже подскажу, когда есть что продолжить.', url: '/dashboard', keywords: ['продолж','урок','место','незаконч'] },
|
||||
// ── Лаборатория / игры ──
|
||||
{ id: 'lab', q: 'Как открыть симуляции?', a: 'В «Лаборатории» симуляции запускаются прямо в браузере — установка не нужна. Выбери предмет и опыт.', url: '/lab', keywords: ['лаборатори','симуляци','опыт','эксперимент','физик','хими'] },
|
||||
{ id: 'optics', q: 'Есть ли конструктор оптики?', a: 'Да — в оптической скамье есть режим «Конструктор»: собирай системы из линз, зеркал и призм.', url: '/lab', keywords: ['оптик','линз','призм','конструктор','скамья'] },
|
||||
{ id: 'games', q: 'Какие есть игры?', a: 'Кроссворд и «Виселица» по терминам предметов — закрепляют слова и понятия, дают XP.', url: '/crossword', keywords: ['игр','кроссворд','виселиц','термин','слов'] },
|
||||
// ── Питомец / геймификация ──
|
||||
{ id: 'pet', q: 'Зачем нужен питомец и XP?', a: 'Квантик растёт от твоей активности: за тесты, уроки и карточки идут XP и монеты. Серия за ежедневные занятия поднимает настроение и даёт бонусы.', url: '/pet', keywords: ['питомец','квантик','xp','опыт','монет','серия','streak','уровень'] },
|
||||
{ id: 'streak', q: 'Что такое серия (streak)?', a: 'Серия — сколько дней подряд ты занимаешься. Чем длиннее, тем счастливее питомец и больше бонусов. Пропуск дня обнуляет серию.', url: '/pet', keywords: ['серия','streak','подряд','дни','бонус'] },
|
||||
{ id: 'coins', q: 'Где потратить монеты?', a: 'В магазине на странице питомца — например, на фоны для Квантика.', url: '/pet', keywords: ['монет','магазин','купить','фон','награда'] },
|
||||
{ id: 'achievements', q: 'Где достижения?', a: 'В профиле есть вкладка «Достижения» — ачивки за активность, серии и результаты.', url: '/profile', keywords: ['достижени','ачивк','награда','бейдж'] },
|
||||
// ── Домашка / классы ──
|
||||
{ id: 'homework', q: 'Где мои домашние задания?', a: 'Все задания и дедлайны — в разделе «Домашние задания». Там же можно загрузить выполненную работу.', url: '/homework', keywords: ['домашк','домашн','задани','дедлайн','сдать','загрузить'] },
|
||||
{ id: 'join-class', q: 'Как вступить в класс?', a: 'Кнопка «Вступить в класс» в меню — введи код от учителя, и задания класса появятся у тебя.', url: '/dashboard', keywords: ['класс','вступить','код','присоедин'] },
|
||||
// ── Профиль / настройки / поиск ──
|
||||
{ id: 'search', q: 'Как искать по платформе?', a: 'Нажми «Поиск» в меню или Ctrl+K — найдёшь уроки, курсы, файлы и вопросы. Спроси меня — я тоже поищу.', url: null, keywords: ['поиск','найти','search','ctrl'] },
|
||||
{ id: 'theme', q: 'Как включить тёмную тему?', a: 'В профиле → «Настройки» → «Внешний вид». Там же звуки и анимации.', url: '/profile', keywords: ['тема','тёмн','dark','внешний','настройк'] },
|
||||
{ id: 'sounds', q: 'Как отключить звуки?', a: 'Профиль → «Настройки» → «Звуки системы»: общий выключатель, громкость и категории.', url: '/profile', keywords: ['звук','выключ','громкост','sound'] },
|
||||
{ id: 'parent', q: 'Как дать доступ родителю?', a: 'В профиле есть «Доступ для родителей» — создай ссылку, по ней родитель видит твой прогресс.', url: '/profile', keywords: ['родител','доступ','ссылк','контрол'] },
|
||||
{ id: 'bookmarks', q: 'Где мои закладки?', a: 'В профиле вкладка «Закладки» — сохранённые параграфы и страницы.', url: '/profile', keywords: ['закладк','сохран','избранн'] },
|
||||
// ── Сам помощник ──
|
||||
{ id: 'assistant-off', q: 'Как выключить помощника?', a: 'Профиль → «Настройки» → «Помощник Квантик». Можно выключить совсем или скрыть конкретные подсказки кнопкой «Не показывать».', url: '/profile', keywords: ['помощник','выключ','ассистент','подсказк','квантик','скрыть'] },
|
||||
{ id: 'assistant-tour', q: 'Как пройти тур заново?', a: 'Нажми на меня и выбери «Тур по системе» — проведу по разделам ещё раз.', url: null, keywords: ['тур','онбординг','обзор','заново'] },
|
||||
];
|
||||
|
||||
/* ── Источники проактивных подсказок (всё уже есть в БД) ──────────────── */
|
||||
@@ -101,6 +122,21 @@ function activeLesson(uid, role) {
|
||||
} catch (e) { return null; }
|
||||
}
|
||||
|
||||
function weakSubject(uid) {
|
||||
// Предмет с наименьшим средним по завершённым тестам (минимум 2 теста).
|
||||
try {
|
||||
const row = db.prepare(`
|
||||
SELECT s.slug AS slug, s.name AS name,
|
||||
ROUND(AVG(ts.score * 100.0 / ts.total)) AS avg, COUNT(*) AS n
|
||||
FROM test_sessions ts JOIN subjects s ON s.id = ts.subject_id
|
||||
WHERE ts.user_id = ? AND ts.status = 'completed' AND ts.total > 0
|
||||
GROUP BY ts.subject_id HAVING n >= 2
|
||||
ORDER BY avg ASC LIMIT 1
|
||||
`).get(uid);
|
||||
return (row && row.avg != null && row.avg < 70) ? { slug: row.slug, name: row.name, avg: row.avg } : null;
|
||||
} catch (e) { return null; }
|
||||
}
|
||||
|
||||
/* ── GET /api/assistant/context ───────────────────────────────────────── */
|
||||
function getContext(req, res) {
|
||||
const uid = req.user.id;
|
||||
@@ -118,6 +154,7 @@ function getContext(req, res) {
|
||||
dueCards: dueCardsCount(uid),
|
||||
homework: pendingHomework(uid),
|
||||
activeLesson: activeLesson(uid, req.user.role),
|
||||
weakSubject: weakSubject(uid),
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user