b005226e2c
Adds achievement coverage for every feature shipped since the original
seed: exam-prep (math9), textbooks, classroom/board, biochemistry,
live-quiz, flashcards, hangman/crossword, pet, plus a new 'social' group
for class & leaderboard wins and 'consistency' extensions (streak_100,
goal_30, early_bird, night_owl).
74 achievements now (was 36), grouped into 7 sections:
onboarding (3) → volume (8) → mastery (16) → consistency (7) →
exam (9) → exploration (21) → social (10)
A new top-level group 'exam' slots between consistency and exploration
in the profile UI.
What's wired in service.checkPhase3Achievements (called from
checkAchievements):
• streak_100 — extends the existing streak track
• goal_30 — 30 days with daily_goals fully met (SUM check)
• early_bird / night_owl — strftime('%H', xp_log.created_at)
• exam_first / 25 / 100 — exam_attempts where is_correct=1
• exam_variant_clear / 5_variants — perfect mock-variant sessions
• exam_topic_master — ≥10 attempts at ≥90% on a single subtopic
• exam_mock_done / pass / perfect — exam_mock_sessions.score
• tb_first_para — textbook_progress
• fc_first_deck / 100_cards / 1000_cards — flashcard_reviews
• bc_first_molecule / 5_challenges / 20_challenges — bio_user_*
• game_win_5 / 25 — xp_log reason IN (hangman_win, crossword_win)
• pet_streak_7 / 30 — users.pet_petting_streak
• lq_first / 3_quizzes — live_answers grouped by session
• cr_first_join / 5 / 25_lessons — classroom_attendance
• class_5_members / 25 — teacher's biggest class
• parent_link — parent_links presence
• lb_top10 / lb_top1 — weekly XP rank among students
What's deferred (catalog entry only, no trigger yet):
• tb_chapter_done / tb_book_done / tb_3_books — need to parse
textbook_progress.paragraphs_read JSON against textbook structure
Every block is wrapped in its own try/catch so a missing table on a
legacy install can't take down the whole achievement sweep.
Verified end-to-end: admin user picked up 7 new unlocks on first
checkAchievements call after seed.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
69 lines
9.9 KiB
SQL
69 lines
9.9 KiB
SQL
-- ═══════════════════════════════════════════════════════════════
|
|
-- 031: Phase 3 — new achievement catalog
|
|
--
|
|
-- Adds 38 achievements covering features that landed since the original
|
|
-- 36 were seeded: exam-prep (exam9), textbooks, classroom/board,
|
|
-- biochemistry, live-quiz, flashcards, hangman/crossword, plus a new
|
|
-- 'social' group for class & leaderboard wins and a few stretch goals
|
|
-- in 'consistency' (streak_100, goal_30, early-bird / night-owl).
|
|
--
|
|
-- Inserts use INSERT OR IGNORE so re-runs are safe; backend
|
|
-- seedAchievements() will keep title/icon/desc/sort_order in sync on
|
|
-- every boot via UPDATE.
|
|
--
|
|
-- A new top-level group 'exam' slots between 'consistency' (400) and
|
|
-- 'exploration' (500). Group display metadata is hard-coded in both
|
|
-- backend (gamification/_shared.ACHIEVEMENT_GROUPS) and frontend
|
|
-- (profile.html ACH_GROUPS); keep them in sync.
|
|
-- ═══════════════════════════════════════════════════════════════
|
|
|
|
INSERT OR IGNORE INTO achievements
|
|
(slug, title, icon, category, description, group_slug, track, tier, sort_order)
|
|
VALUES
|
|
-- ── consistency extensions ─────────────────────────────────
|
|
('streak_100', 'Сто дней подряд', 'flame', 'streak', 'Невероятная серия — 100 дней активности подряд', 'consistency', 'streak', 4, 440),
|
|
('goal_30', 'Цель: 30 дней', 'target', 'streak', '30 дней подряд выполнять цель дня', 'consistency', 'goal_streak', 1, 450),
|
|
('early_bird', 'Ранняя пташка', 'sunrise', 'streak', 'Активность до 9 утра', 'consistency', 'time', 1, 460),
|
|
('night_owl', 'Ночная сова', 'moon', 'streak', 'Активность после 23:00', 'consistency', 'time', 2, 470),
|
|
|
|
-- ── exam-prep (math9) ──────────────────────────────────────
|
|
('exam_first', 'Старт экзамена', 'flag', 'exam', 'Решена первая задача экзамена 9 класса', 'exam', 'exam_attempts', 1, 700),
|
|
('exam_25_attempts', '25 задач экзамена', 'list-checks', 'exam', '25 решённых попыток в банке экзамена', 'exam', 'exam_attempts', 2, 710),
|
|
('exam_100_attempts', '100 задач экзамена', 'check-square', 'exam', '100 решённых попыток в банке экзамена', 'exam', 'exam_attempts', 3, 720),
|
|
('exam_variant_clear', 'Чистый вариант', 'crown', 'exam', 'Все 10 задач варианта решены верно', 'exam', 'variants', 1, 730),
|
|
('exam_5_variants', '5 вариантов', 'layers', 'exam', '5 разных вариантов закрыто целиком', 'exam', 'variants', 2, 740),
|
|
('exam_topic_master', 'Мастер темы', 'target', 'exam', '≥90% точности на одной из подтем (≥10 попыток)', 'exam', 'topic', 1, 750),
|
|
('exam_mock_done', 'Первый пробник', 'timer', 'exam', 'Завершён первый пробный экзамен', 'exam', 'mock', 1, 760),
|
|
('exam_mock_pass', 'Пробник сдан', 'badge-check', 'exam', 'Балл ≥ 7 на пробном экзамене', 'exam', 'mock', 2, 770),
|
|
('exam_mock_perfect', 'Пробник на 10', 'trophy', 'exam', 'Идеальные 10 баллов на пробном экзамене', 'exam', 'mock', 3, 780),
|
|
|
|
-- ── mastery extensions (textbooks + flashcards) ────────────
|
|
('tb_first_para', 'Открыл параграф', 'book-marked', 'theory', 'Прочитан первый параграф учебника', 'mastery', 'tb_progress', 1, 800),
|
|
('tb_chapter_done','Глава закрыта', 'book-check', 'theory', 'Все параграфы одной главы пройдены', 'mastery', 'tb_progress', 2, 810),
|
|
('tb_book_done', 'Учебник целиком', 'book-up', 'theory', 'Все параграфы учебника пройдены', 'mastery', 'tb_progress', 3, 820),
|
|
('tb_3_books', 'Полка из трёх', 'library-big', 'theory', '3 учебника закрыто полностью', 'mastery', 'tb_progress', 4, 830),
|
|
('fc_first_deck', 'Первая колода', 'layers', 'theory', 'Все карточки одной колоды разок повторены', 'mastery', 'flashcards', 1, 840),
|
|
('fc_100_cards', '100 карточек', 'rotate-cw', 'theory', '100 повторов карточек в сумме', 'mastery', 'flashcards', 2, 850),
|
|
('fc_1000_cards', '1000 карточек', 'sparkles', 'theory', '1000 повторов карточек в сумме', 'mastery', 'flashcards', 3, 860),
|
|
|
|
-- ── exploration extensions (biochem / games / pet) ─────────
|
|
('bc_first_molecule', 'Первая молекула', 'flask-round', 'lab', 'Собрана первая молекула в био-конструкторе', 'exploration', 'biochem', 1, 870),
|
|
('bc_5_challenges', '5 био-задач', 'beaker', 'lab', '5 биохимических задач решено', 'exploration', 'biochem', 2, 880),
|
|
('bc_20_challenges', '20 био-задач', 'atom', 'lab', '20 биохимических задач решено', 'exploration', 'biochem', 3, 890),
|
|
('game_win_5', '5 побед в играх', 'gamepad-2', 'volume','5 побед в Виселице или Кроссворде суммарно', 'exploration', 'minigames', 1, 900),
|
|
('game_win_25', '25 побед в играх', 'gamepad', 'volume','25 побед в Виселице или Кроссворде суммарно', 'exploration', 'minigames', 2, 910),
|
|
('pet_streak_7', 'Заботливый', 'heart', 'volume','7 дней подряд гладить питомца', 'exploration', 'pet', 1, 920),
|
|
('pet_streak_30', 'Лучший друг', 'paw-print', 'volume','30 дней подряд гладить питомца', 'exploration', 'pet', 2, 930),
|
|
|
|
-- ── social (NEW group) ─────────────────────────────────────
|
|
('lb_top10', 'Топ-10 недели', 'trending-up', 'volume', 'Попасть в топ-10 лидерборда недели', 'social', 'leaderboard', 1, 1000),
|
|
('lb_top1', 'Первое место', 'medal', 'volume', '№1 в лидерборде недели', 'social', 'leaderboard', 2, 1010),
|
|
('lq_first', 'Первый live-quiz', 'radio', 'volume', 'Принять участие в первом live-квизе', 'social', 'live_quiz', 1, 1020),
|
|
('lq_3_quizzes', '3 live-квиза', 'megaphone', 'volume', 'Принять участие в 3 live-квизах', 'social', 'live_quiz', 2, 1030),
|
|
('cr_first_join', 'Первое подключение','door-open', 'volume', 'Первое подключение к уроку в classroom', 'social', 'classroom', 1, 1040),
|
|
('cr_5_lessons', '5 уроков', 'presentation', 'volume', 'Посещено 5 уроков classroom', 'social', 'classroom', 2, 1050),
|
|
('cr_25_lessons', '25 уроков', 'school', 'volume', 'Посещено 25 уроков classroom', 'social', 'classroom', 3, 1060),
|
|
('class_5_members', 'Учитель: 5 учеников','users', 'start', 'Учитель: класс из ≥5 учеников', 'social', 'teacher', 1, 1070),
|
|
('class_25_members', 'Учитель: 25 учеников','users-2', 'start', 'Учитель: класс из ≥25 учеников', 'social', 'teacher', 2, 1080),
|
|
('parent_link', 'Связан с родителем','user-plus', 'start', 'Связь с родителем установлена', 'social', 'family', 1, 1090);
|