Files
Maxim Dolgolyov 26c0ac0e58 docs(assistant): дизайн-документ «Квантик-ассистент» (правиловый, без кода)
План сквозного ассистента поверх существующего питомца: контекстные подсказки,
проактивные напоминания из реальных данных, поздравления, онбординг-тур.
Архитектура (assistant.js через sidebar.js, правиловый движок, анти-назойливость),
каталог правил, фазы Ф0–Ф4, открытые вопросы.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 15:59:56 +03:00

18 KiB
Raw Permalink Blame History

Квантик-ассистент — дизайн-документ

Статус: дизайн (код не пишем). Движок подсказок: правиловый/эвристический (без LLM). Цель: превратить существующего питомца «Квантик» в сквозного ассистента, который помогает работать в системе, подсказывает и проактивно напоминает.


1. Цель и принципы

Маленький плавающий компаньон (тот же Квантик) присутствует на всех страницах и:

  1. Подсказывает по контексту страницы — что тут можно, неочевидные фичи.
  2. Проактивно напоминает — из реальных данных (домашка, карточки, урок, серия, квесты).
  3. Радуется успехам — левелап, ачивка, серия, тест на 100%.
  4. Ведёт новичка — короткий тур по разделам при первом входе.
  5. Отвечает «как сделать X» — поиск по справке/FAQ (LLM — за рамками, точка расширения).

Принципы:

  • Единая личность — имя/цвет/настроение из /api/pet, лицо — pet-sprite.js. Никакого второго персонажа.
  • Не назойливый — один пузырь за раз, дневной лимит, кулдауны, «понял / не показывать», тихий режим, выключаемость.
  • Детерминированный — правила и шаблоны на реальных данных, предсказуемо и офлайн.
  • Без эмоджи в коде — только inline SVG .ic (правило проекта). Тексты подсказок — тоже без эмоджи.
  • Лёгкий — не грузит страницы, ленивая инициализация, минимум сетевых запросов.

Не-цели (сейчас): свободный диалог/LLM; голос; геймификация поверх (ачивки за общение — позже, Ф4).


2. Что уже есть (фундамент)

  • Питомец «Квантик»: 8 уровней по XP, настроение (_mood от серии/дней без входа), аксессуары (_accessories: hat/glasses/crown/star), монеты, поглаживание/кормёжка, дневные квесты (_quests), недельный XP, лента активности, прогноз настроения (_moodForecast), цвета, магазин фонов.
  • GET /api/pet (petController.getPet) уже отдаёт: petName, petLevel, petColor, mood, daysSinceLogin, accessories, xp, level, streakCurrent, streakBest, coins, quests[], moodForecast, recentActivity[], weeklyXP[], xpForNextLevel. → почти весь контекст для подсказок берётся отсюда.
  • pet-sprite.jswindow.PetSprite.render(level, mood, accessories, colorKey, streak) → SVG. Переиспользуем как «лицо» ассистента (мини-версия в пузыре).
  • Показ: страница /pet + виджет на /dashboard.
  • Онбординга/туров/подсказок в системе нет — строим с нуля, конфликтов не будет.
  • Точка инъекции: глобальные скрипты подключаются на каждой app-странице (api.js, sidebar.js, search.js, notifications.js, mobile.js). sidebar.js есть везде → он догружает assistant.js одной строкой, HTML страниц не трогаем.
  • Питомец — фича за requireFeature('pet') (см. server.js).

3. Архитектура

sidebar.js (на каждой странице)
   └─ догружает /js/assistant.js (если фича включена и не отключено юзером)
        ├─ Assistant.boot()
        │    ├─ собирает ctx (page + данные)
        │    ├─ прогоняет реестр правил → выбирает 1 подсказку по приоритету/кулдауну
        │    └─ рисует компаньона + пузырь (лицо = PetSprite.render)
        ├─ assistant-rules.js — реестр правил (данные, не логика)
        └─ состояние/капы — localStorage (+ опц. сервер в Ф1+)

3.1. Компоненты (файлы — создаём в фазах, не сейчас)

  • frontend/js/assistant.js — движок + UI (стили инжектит сам, как board-clip.js).
  • frontend/js/assistant-rules.js — каталог правил (отдельно, чтобы правила правились без движка).
  • js/sidebar.js — +строка ленивой загрузки ассистента.
  • frontend/profile.html — настройки (вкл/выкл, частота, сброс подсказок).
  • (Ф1) backend/src/routes/assistant.js + controllers/assistantController.jsGET /api/assistant/context.
  • (Ф1, опц.) миграция: серверная отметка «видел подсказку» для кросс-девайс (иначе только localStorage).

3.2. Движок: контекст и правила

Контекст ctx (собирается при загрузке страницы):

{
  path, page,            // page — нормализованный id ('textbook','classroom','exam-prep',...)
  role,                  // student | teacher | admin
  isFirstVisit,          // нет ни одной отметки о показе
  pet,                   // кэш /api/pet (мин. TTL, чтобы не дёргать на каждой странице)
  data: {                // лениво/из /api/assistant/context (Ф1)
    homeworkDue: [{title, deadline, status}],
    dueCards: <int>,     // карточек к повторению
    activeLesson: {courseId, title, pct} | null,
    weakTopics: [...],
    quests: [...]        // из /api/pet
  },
  events: [...],         // свежие левелап/ачивка (детект по дельте)
  now
}

Форма правила:

{
  id: 'textbook-clip',
  scope: 'page' | 'proactive' | 'celebration',
  when: (ctx) => boolean,        // условие показа
  priority: 50,                  // больше = важнее (celebration > proactive > page)
  cooldownDays: 7,               // не чаще раза в N дней
  maxShows: 3,                   // пожизненный лимит показов
  suppressOn: ['exam-run','board-draw'], // не мешать в фокусных режимах
  text: (ctx) => 'Можно вырезать кусок страницы в «Мои материалы».',
  action: (ctx) => ({ label: 'Показать', url: null, run: fn }) | null,
  petMood: 'happy'               // настроение лица (опц.)
}

Алгоритм выбора: отфильтровать when && !suppressed && подходит по кулдауну/лимиту, отсортировать по scope-весу + priority, взять одно. Показ — по триггеру (см. 3.3).

3.3. Анти-назойливость (критично)

  • 1 пузырь на экране за раз.
  • Триггеры показа: page-подсказка — через 6–8 с на странице или по наведению на компаньона; proactive — раз в сессию на категорию; celebration — сразу по событию.
  • Дневной лимит проактивных подсказок (по умолчанию 3).
  • Кулдаун на правило + пожизненный maxShows.
  • Кнопки в пузыре: «Понятно» (скрыть), «Не показывать» (навсегда для этого правила).
  • Тихий режим и глобальный выключатель в профиле.
  • Не мешать в фокусе: скрывать на странице запущенного теста, во время рисования на доске, на онлайн-уроке (suppressOn).
  • prefers-reduced-motion — без анимаций/конфетти.

3.4. Хранение состояния

  • localStorage: asst_off (вкл/выкл), asst_freq, asst_seen:{ruleId}={count,lastTs}, asst_mute_until, asst_pet_level/asst_ach_seen (для детекта событий).
  • (Опц., Ф1) сервер: таблица assistant_seen(user_id, rule_id, count, last_at) для кросс-девайс — иначе подсказки повторятся на другом устройстве. Решить в Открытых вопросах.

4. Каталог правил (черновик)

4.1. Контекстные (scope: page) — «что тут можно»

id страница текст (суть) действие
textbook-clip /textbook Вырежи кусок страницы картинкой в «Мои материалы» подсветить кнопку «Вырезать область»
textbook-deeplink /textbook Можно делиться ссылкой прямо на параграф
board-tools /classroom, /board Лассо, фигуры, формулы KaTeX, линейка — попробуй панель
exam-modes /exam-prep Режимы: экзамен / тренировка / случайный
lab-sims /lab Симуляции запускаются прямо тут, без установки
flashcards-katex /flashcards Формулы вводятся через KaTeX-палитру
materials-folders /my-materials Раскладывай материалы по папкам и аннотируй фото
dashboard-widgets /dashboard Виджеты дашборда можно настроить под себя

4.2. Проактивные (scope: proactive) — из реальных данных

id условие текст действие
hw-due-soon есть домашка с дедлайном < 24ч и не сдана Домашка «X» — дедлайн скоро → /homework
hw-overdue есть просроченная несданная Просрочена домашка «X» → /homework
cards-due dueCards > 0 К повторению N карточек → /flashcards
lesson-continue есть незаконченный урок Продолжи «X» (N%) → /course?id=...
streak-risk streakCurrent ≥ 1 и сегодня нет активности (вечер) Серия N дней под угрозой — закрепи → /exam-prep
quest-nudge есть незакрытый дневной квест Добей квест: «X» → соответствующий раздел
weak-topic низкий средний по теме Подтяни тему «X» → тест/учебник по теме

4.3. Поздравления (scope: celebration) — по событию

id триггер реакция
levelup pet.level вырос с прошлой проверки Квантик ecstatic + «Уровень N!»
achievement новая ачивка поздравление + название
streak-milestone серия достигла 3/7/14/30 поздравление + аксессуар-намёк
test-perfect тест на 100% (из recentActivity) поздравление

Эмоджи в существующих квестах (⭐📝🔥 в petController._quests) заменить на inline SVG .ic при интеграции — для соответствия правилу проекта.


5. Источники данных (всё уже в системе)

Нужно Откуда
настроение/серия/квесты/прогноз/уровень GET /api/pet
домашка + дедлайны assignments (как на дашборде: asgn-row urgent/over)
карточки к повторению flashcards SRS (LS.fc*)
незаконченный урок /api/courses (doneCount/lessonCount) / lesson_progress
слабые темы analytics по test_sessions
левелап/ачивки дельта /api/pet (level, xp) + список ачивок

Рекомендация (Ф1): один эндпоинт GET /api/assistant/context собирает компактный бандл (homeworkDue, dueCards, activeLesson, weakTopics), чтобы не дёргать 4 API с клиента.


6. UI / UX

  • Компаньон: мини-Квантик (≈48–56px) в правом-нижнем углу (на мобиле — выше mob-bar, не перекрывая). Лёгкое «дыхание»; при наличии подсказки — мягкий пульс/бейдж.
  • Пузырь: speech-bubble над компаньоном: текст (1–2 строки) + опц. кнопка действия + «Понятно» + «Не показывать». Закрытие: кнопка, клик вне, Esc.
  • Состояния: idle / has-hint / bubble-open / celebrating (конфетти + ecstatic) / hidden.
  • Стиль: дизайн-система ls.css (переменные --violet/--text/--text-3), inline SVG .ic, тёмная тема, без эмоджи. Тон: дружелюбный, на «ты», кратко.
  • A11y: aria-live="polite" на пузыре, фокус/Esc, уважение prefers-reduced-motion.
  • Перетаскивание/сворачивание компаньона (запоминать позицию) — опц., Ф2.

7. Настройки и приватность

  • Профиль: переключатель «Ассистент Квантик», частота (обычная/низкая), «Сбросить подсказки».
  • Фича-флаг: reuse pet или новый assistant (решить — см. Открытые вопросы).
  • Роли: ученики — основной сценарий; учителям — отдельный набор подсказок (Ф4); по умолчанию для admin, возможно, выключен.
  • Никакой персональной телеметрии наружу; состояние — локально (+опц. своя таблица).

8. Фазы

  • Ф0 — каркас: assistant.js + assistant-rules.js, плавающий Квантик (лицо из pet-sprite), пузырь, dismissal/кулдауны/лимиты, вкл/выкл, инъекция через sidebar.js, 56 правил §4.1.
  • Ф1 — проактив: GET /api/assistant/context + правила §4.2 + поздравления §4.3 (детект событий).
  • Ф2 — онбординг-тур новичка по разделам + все контекстные подсказки + «не показывать снова» + (опц.) перетаскивание/сворачивание.
  • Ф3 — «Спроси Квантика»: окно с поиском по справке/FAQ (использует search.js). Точка расширения под LLM — за рамками этого плана.
  • Ф4 — персонализация: частота/тон, режим для учителей, ачивки за взаимодействие, на страницах учебника (серверный inject) тоже.

9. Затрагиваемые файлы (при будущей реализации)

    • frontend/js/assistant.js, frontend/js/assistant-rules.js
  • ~ js/sidebar.js (одна строка-загрузчик)
  • ~ frontend/profile.html (настройки)
  • (Ф1) + backend/src/routes/assistant.js, backend/src/controllers/assistantController.js, mount в server.js (+ возможный фича-флаг assistant)
  • (Ф1, опц.) + миграция assistant_seen
  • ~ petController._quests — заменить эмоджи на .ic при интеграции

10. Открытые вопросы (обсудить перед Ф0)

  1. Фича-флаг: переиспользуем pet или заводим отдельный assistant? (ассистент шире питомца).
  2. Кому по умолчанию вкл: всем ученикам? учителям? admin — выкл?
  3. Кросс-девайс «видел»: localStorage достаточно, или нужна серверная таблица assistant_seen?
  4. Учебник (серверный рендер): включать ассистента и там (через inject) сразу или в Ф4?
  5. Тон/частота по умолчанию: насколько активно напоминать (консервативно vs заметно)?
  6. «Спроси Квантика» (Ф3): только справка/FAQ, или сразу закладываем место под локальную модель?

11. Риски

  • Назойливость — главный риск; смягчается лимитами/кулдаунами/тихим режимом (§3.3).
  • Перекрытие UI (особенно мобайл, существующие FAB вроде «Вырезать область», flashcard-fab.js) — согласовать z-index и позиции, не накладываться.
  • Лишние запросы — кэш /api/pet, один бандл-эндпоинт, ленивая инициализация.
  • Рассинхрон личности — всегда брать имя/цвет/настроение из одного источника (/api/pet).