# Сборка курса ЦЭ/ЦТ на СУЩЕСТВУЮЩЕМ банке `questions` (основной путь) > ⚠️ ПИВОТ (2026-06-14): контент ЦЭ/ЦТ по математике **уже в базе** — таблица `questions` > (`subject_id=3`), **1753 задания** за 2011–2025 (включая ЦЭ-2024 = 117, набор 2025 = 1020), > размечены по темам (`topics`) и годам (`year`), залиты скриптами `backend/scripts/seed_math_ct*.js`. > Поэтому курс строим **поверх этого банка** через `tests`/`assignments`/`courses`, а НЕ через > exam-prep (`exam_tasks`). Миграция 077 (пустой exam-prep-скелет `ctmath`) оставлена как опция, > но это НЕ основной путь и в БД не применяется. > > Этот документ заменяет (по части «куда складывать») разделы маппинга в [PLAN.md](PLAN.md) §6 > и спецификацию оцифровки [DIGITIZATION_SPEC.md](DIGITIZATION_SPEC.md). Карта экзамена (§1 PLAN), > методика (§2), модульная программа (§3), уровни (§4), пилоты ([тригонометрия](PILOT_TRIGONOMETRY.md)/[стереометрия](PILOT_STEREOMETRY.md)) и инвентарь ([RESOURCES.md](RESOURCES.md)) — остаются в силе. --- ## 0. Состояние реализации **Сделано (скрипт `backend/scripts/seed_ctmath_course.js`, идемпотентный, применён на живой БД 2026-06-14):** - ✅ Добавлены 6 тем (`topics`, subject_id=3): Преобразование выражений (72), Модуль (73), Иррациональные уравнения (74), Показательные уравнения (75), Производная (76), Параметры (77). - ✅ Создан **DRAFT-курс** «ЦЭ/ЦТ — Математика» (`courses.id=13`, `is_published=0`, created_by=2) — ученикам НЕ виден до публикации. - ✅ 9 секций (`course_sections.id=27..35`) = блоки I–IX. **Сделано (скрипт `backend/scripts/seed_ctmath_diagnostic.js`, применён 2026-06-14):** - ✅ **Диагностический `test`** «Диагностика ЦЭ/ЦТ — Математика» (`tests.id=164`, 15 вопросов, лимит 40 мин, `show_answers=1`) — собран из РЕАЛЬНЫХ размеченных вопросов ЦТ-11 (в осн. 2024): 5 `single` (базовые, по 1 на тему Теория чисел/Арифметика/Квадратные/Тригонометрия/Промежутки) + 10 `fill-blank` (средние/сложные: Словесные/Прогрессии/Функции/Геометрия/Окружность/Стереометрия/Логарифмы/Неравенства/Уравнения/Показательные). Новых вопросов не авторили. Выдать классу/ученику: assignment с `test_id=164`. **Сделано (скрипт `backend/scripts/seed_ctmath_lessons_trig.js`, применён 2026-06-15):** - ✅ **Блок «Тригонометрия» — 3 урока** в секции 31 курса 13 (по [PILOT_TRIGONOMETRY.md](PILOT_TRIGONOMETRY.md)): «Тригонометрический круг и значения» (`lessons.id=41`, 18 блоков, А3 🟢), «Тождества и формулы» (`id=42`, 19 блоков, А8/В4 🟡), «Уравнения и отбор корней» (`id=43`, 15 блоков, В15 🔴). Блоки в формате рендера lesson.html (heading/text/formula/callout/sim `trigcircle`/flashcard/quiz/ matching/ordering/accordion/table); математика `$…$`/`$$…$$`; JSON валиден; идемпотентно. **Дальше (не сделано):** уроки остальных 8 блоков по пилотам (тиражирование, начать со стереометрии); assignment-практика `mode='topic'`; колоды формул (`flashcard_decks`); публикация курса; выдача диагностики классу (assignment `test_id=164`). См. §8. --- ## 0a. Решение: ЦТ как ОТДЕЛЬНЫЙ модуль exam-prep (2026-06-15) По решению пользователя ЦТ оформляется как **отдельный модуль** (как «Экзамен 9»): свой раздел `/exam-prep/ctmath` с дашбордом, тренажёром по темам, пробниками на таймер, детектором слабых тем. Это значит: применить трек+дерево тем (миграция **077**) и **перенести размеченные вопросы ЦТ-11 из банка `questions` в `exam_tasks`** (exam_key='ctmath'). Конвертер: **`backend/scripts/seed_ctmath_exam_tasks.js`** (dry по умолчанию, запись `--apply`). Правила сверены с exam-prep (агент-разведка): MC-метки кириллица `а,б,в,г,д`, `answer`=метка; open — числовой/дробь/пара (иначе → `long` self-check); математика `\( \)`→`$`, `\[ \]`→`$$` (exam-prep KaTeX знает только `$`/`$$`!); `subtopic`=slug из 077; `variant`=год; multi/multiple (radio несовместимо) — пропуск. **Dry-run (2026-06-15):** 733 размеч. вопроса → **723 к вставке** (525 mc + 191 open + 7 long; 10 multi пропущено; 7 не-числовых → long). Делимитеры/метки/ответы корректны (проверено на выборке). **Статус записи: ПРИМЕНЕНО (2026-06-15).** Миграцию 077 применил пользователь вручную (авто-режим блокирует продакшн-миграции); конвертер `--apply` — тоже запускал пользователь (объём 723 был заблокирован авто-режимом). Итог в БД: трек `ctmath` (enabled=1), дерево тем 41 (9+32), **723 задачи в `exam_tasks`** (525 mc + 191 open + 7 long), variants_count=15. Проверка: осиротевших subtopic 0, неконвертированных `\(` 0. Модуль доступен на **`/exam-prep/ctmath`** (учителю/админу сразу; ученику — после `content_access`). Постфикс (2026-06-15): варианты ответа у части mc были вшиты в текст («1) 44; 2) 22; …»), а opts — лишь цифры-указатели. Скрипт `fix_ctmath_inline_opts.js --apply` (запускал пользователь) вытащил список в нормальный `opts_json` и пересчитал answer — **исправлено 213 задач**; инлайн-списков в тексте осталось **3** (нестандартный формат, не сломаны). Битых opts 0. Известный мелкий дефект источника: 1 mc-задача `exam_tasks.id=1248` (var 2020) без верного варианта (дубль опций) — всегда «неверно»; фикс: перевести в `long` или проставить ответ. Плюс ~3 mc с неразобранным инлайн-списком — при желании вторая итерация парсера. После applied — осталось: `content_access` (exam/ctmath классу) + пункт сайдбара на `/exam-prep/ctmath`. > ⚠️ Гоча: рендер exam-prep — ТОЛЬКО `$…$`/`$$…$$` (НЕ `\(…\)`). Конвертер это учитывает. --- ## 1. Что уже есть (проверено чтением БД) | Таблица | Роль | Факт | |---|---|---| | `questions` | банк заданий | 1753 матем. (subject_id=3); `topic_id`, `year`, `difficulty` 1–3, `type`, `explanation`, `image`, `source_type` | | `options` | варианты ответов | `question_id`, `text`, `is_correct`, `order_index`, `match_pair` | | `topics` | темы (ПЛОСКИЕ) | 19 тем по математике (без иерархии): id+subject_id+name+order_index | | `tests` / `test_questions` | фикс. наборы | тест = упорядоченный список вопросов | | `test_sessions` / `user_answers` | прохождение + баллы | score = число верных | | `assignments` | выдача | режимы `exam/practice/topic/repeat/`**`ct`** | | `courses`/`course_sections`/`lessons`/`lesson_blocks` | теория | общий слой контента | | `flashcard_*` | карточки + SR | для формул | ### 1.1. Уточнение по инспекции (2026-06-14) — ВАЖНО Из 1753 матем. заданий: - **~733 — реальный банк ЦЭ/ЦТ-11** (2011–2024), **размечены по темам**. Часть A = `single`, **Часть B = `fill-blank`** (198 шт.), `short_answer` у них НЕТ. **Это база курса.** - **1020 — набор `year=2025`, `source_type='экзамен 9'` = «Экзамен 9 класс», БЕЗ тем** (`topic_id` пустой), все `difficulty=1`, типы `single`+`short_answer`. Это контент 9-класса (из него собраны тесты «Экзамен 9 — Вариант N»). **Для курса ЦЭ/ЦТ-11 — НЕ основа** (другой экзамен/класс; не размечен). **Типы заданий (`questions.type`)**: `single`, `multi`, `true_false`, `short_answer`, `matching`, `fill-blank`. **Сложность**: `difficulty` 1–3 (CHECK), 1=базовый/2=средний/3=продвинутый. (В [PLAN.md](PLAN.md) шкала 1–5 — привести к 1–3: А-часть и лёгкая В = 1, средняя В = 2, сложная В14–В20 = 3.) **Год**: `year` (2011…2025) — фильтр по году/варианту. ### Текущая таксономия тем (math, `subject_id=3`) `16 Арифметика и степени` · `17 Словесные задачи` · `18 Теория чисел` · `19 Тригонометрия` · `20 Квадратные уравнения` · `21 Прогрессии` · `22 Неравенства` · `23 Геометрия` · `24 Функции` · `25 Логарифмы` · `26 Показательные неравенства` · `27 Уравнения` · `28 Статистика и диаграммы` · `61 Стереометрия` · `62 Окружность и круг` · `63 Числовые промежутки` · `64 Подобные фигуры` · `67 Парабола` · `69 Тригонометрические уравнения` --- ## 2. Ключевой механизм: режимы `assignments` (выбор вопросов) Логика `assignmentController.startAssignment` (подтверждено по коду): - **`mode='ct'`** — собирает ЦТ-вариант: ~половина из `type IN ('single','true_false')` (Часть A) + остаток из `type IN ('multi','short_answer')` (Часть B), добор при нехватке. ⚠️ **Гоча:** реальный банк ЦТ-11 имеет Часть B типа **`fill-blank`**, который `mode='ct'` НЕ выбирает (он ждёт `short_answer`) → для ЦТ-11 Часть B соберётся только «добором». `mode='ct'` хорошо ложится на набор «Экзамен 9» (там Часть B = `short_answer`). **Для ЦТ-11 надёжнее `mode='topic'` или ручная сборка `test` (single + fill-blank).** - **`mode='topic'`** — `SELECT id FROM questions WHERE subject_id=3 AND topic_id=? ORDER BY RANDOM() LIMIT count`. **Тренажёр по теме модуля.** - **`mode='exam'|'practice'|'repeat'`** — случайные `count` по предмету (или теме). - **`test_id` задан** — берутся ИМЕННО вопросы теста в его порядке (перекрывает режим). **Так делается фиксированная диагностика.** Выдача: `class_id` (классу) или `user_id` (ученику); `count` 1–200; `deadline`; `max_attempts` 0–10. --- ## 3. Таксономия: довести темы под модульную карту Текущие 19 тем покрывают большинство модулей, но грубее карты §3 [PLAN.md](PLAN.md). Два варианта (рекомендуется А): **A. Принять текущую гранулярность + добавить недостающее (мин. усилий).** Добавить новые `topics` (для будущей разметки и точечной практики), существующие вопросы НЕ перетегировать массово: - `Преобразование выражений` (M3–M6) - `Модуль` (M10) - `Иррациональные уравнения` (M11) - `Показательные уравнения` (M12; сейчас есть только «Показательные неравенства») - `Производная` (M17) - `Параметры` (M30) **B. Полная иерархия** — перетегировать 1753 вопроса под все 32 подтемы. Дорого; не оправдано на старте. ### Маппинг модуль → тема банка (для практики `mode='topic'`) | Модуль(и) | topic | |---|---| | M1–M3 Числа | `18 Теория чисел`, `16 Арифметика и степени` | | M4–M6 Преобразования | `16` (+ новый `Преобразование выражений`) | | M7 Линейные/системы | `27 Уравнения`, `22 Неравенства`, `63 Числовые промежутки` | | M8 Квадратные | `20 Квадратные уравнения` | | M9 Рациональные | `27 Уравнения`, `22 Неравенства` | | M10 Модуль | новый `Модуль` | | M11 Иррациональные | новый `Иррациональные уравнения` | | M12 Показательные | новый `Показательные уравнения`, `26 Показательные неравенства` | | M13 Логарифмы | `25 Логарифмы` | | M15–M16 Функции/графики | `24 Функции`, `67 Парабола` | | M17 Производная | новый `Производная` | | M18–M19 Тригонометрия | `19 Тригонометрия` | | M20 Триг. уравнения | `69 Тригонометрические уравнения` | | M21 Прогрессии | `21 Прогрессии` | | M22 Текстовые | `17 Словесные задачи` | | M23–M24 Планиметрия | `23 Геометрия`, `64 Подобные фигуры` | | M25 Окружность | `62 Окружность и круг` | | M26–M29 Стереометрия | `61 Стереометрия` | | M30 Параметры | новый `Параметры` | | (стат.) | `28 Статистика и диаграммы` | > Реализация добавления тем — обычным `INSERT INTO topics(subject_id,name)` (как делают seed-скрипты через `getTopic`). Можно отдельной миграцией или скриптом. Перетегировать существующие вопросы под новые темы — опционально и точечно (по тексту/году). --- ## 4. Структура курса (теория) — `courses`/`sections`/`lessons` Создаётся через API (teacher/admin), наполняется по пилотам: 1. **`courses`**: `subject_slug='math'`, `title='ЦЭ/ЦТ — Математика'`, `is_published=1`, обложка. 2. **`course_sections`**: 9 секций = блоки I–IX из [PLAN.md](PLAN.md) §3. 3. **`lessons`** + **`lesson_blocks`** по шаблону пилотов (heading → теория/формулы → sim/диаграмма → callout «ошибки» → flashcards → quiz). Типы блоков: `text/formula/callout/quiz/sim/geogebra/flashcard/image/table/accordion/ordering/matching`. 4. В уроке кнопка «тренироваться» → assignment `mode='topic'` по теме модуля (или ссылка на практику банка). 5. Доступ ученикам/классам — `content_access`/`course_access` (миграция 052) + `class_courses`. > Связь урок↔§учебника — через ссылки в `lesson_blocks` (`text` с гиперссылкой на `/textbook/...`), т.к. в `questions`/`topics` нет поля textbook (в отличие от exam-prep). Учебники реальны (algebra-7..11, geometry-8..11) — см. [TOPICS_SEED.md](TOPICS_SEED.md). --- ## 5. Практика и пробники (на банке) - **Тренажёр модуля** → assignment `mode='topic'`, `topic_id` = тема модуля, `count` 10–25, `max_attempts=0`. - **Пробный вариант ЦТ** → assignment `mode='ct'`, `count=30` (без `topic_id` = по всем темам). Даёт Часть A + Часть B автоматически. Для «на время» — задать через связанный `test.time_limit` (или прохождение сессии; полноценный таймер-пробник как в exam-prep здесь проще через `test` с `time_limit`). - **Фиксированный набор** (диагностика, тематический срез) → `test` + `test_questions`, затем assignment с `test_id`. - Сложность регулируется выбором тем + `difficulty` (1–3) при ручной сборке `test`. --- ## 6. Входная диагностика (из реальных вопросов банка, БЕЗ авторинга) Собрать `test` «Диагностика ЦЭ/ЦТ» из ~14 существующих вопросов — по одному на ключевую тему, желательно `year=2024`: | # | topic (bank) | критерий выбора | уровень-зонд | |---|---|---|---| | 1 | 18 Теория чисел | `single`, diff 1 | 🟢 | | 2 | 20 Квадратные уравнения | `single`, diff 1 | 🟢 | | 3 | 19 Тригонометрия | `single`, diff 1 | 🟢 | | 4 | 16 Арифметика и степени | `single`, diff 1–2 | 🟢 | | 5 | 17 Словесные задачи | `short_answer`, diff 2 | 🟡 | | 6 | 21 Прогрессии | `short_answer`, diff 2 | 🟡 | | 7 | 24 Функции | diff 2 | 🟡 | | 8 | 19 Тригонометрия | `short_answer`, diff 2 (тождества) | 🟡 | | 9 | 23 Геометрия | `short_answer`, diff 2 | 🟡 | | 10 | 61 Стереометрия | diff 2 | 🟡 | | 11 | 25 Логарифмы | `short_answer`, diff 3 | 🔴 | | 12 | 69 Триг. уравнения | diff 3 | 🔴 | | 13 | 24 Функции / Производная | diff 3 | 🔴 | | 14 | 61 Стереометрия | diff 3 (углы/расстояния) | 🔴 | Реализация: выбрать конкретные `question.id` по критериям (`subject_id=3 AND topic_id=? AND difficulty=? [AND year=2024]`), создать `test` + `test_questions` в нужном порядке, выдать как assignment `test_id`. По результату — назначить трек (правила §4 [PLAN.md](PLAN.md)). **Никакого нового авторинга — берём готовые проверенные вопросы.** --- ## 7. Прогресс и аналитика - Есть: `test_sessions.score/total`, `user_answers.is_correct`, `lesson_progress.completed`. - **Нет** (в этой подсистеме): автодетектора слабых тем и per-topic mastery (это только в exam-prep). Варианты: - считать точность по теме join'ом `user_answers`+`questions.topic_id` (есть `assignmentQuestionStats` по вопросам — расширить до тем); - или (доработка) добавить агрегат «точность по теме» для рекомендаций «что подтянуть». - Формулы — `flashcard_decks` по блокам + `flashcard_deck_access` классу (SR встроен). --- ## 8. Порядок реализации (на банке `questions`) 1. **Таксономия**: добавить недостающие темы (§3, вариант A) — миграция/скрипт `INSERT INTO topics`. 2. **Курс-каркас**: `courses` + 9 `course_sections`. 3. **Диагностика**: собрать `test` из 14 реальных вопросов (§6), выдать. 4. **Уроки по приоритету** (стерео, тригонометрия — §8 PLAN): теория в `lesson_blocks` по пилотам + кнопка практики `mode='topic'`. 5. **Пробники**: assignment `mode='ct'` (вариант 30 заданий) + тематические `mode='topic'`. 6. **Карточки формул**: `flashcard_decks` по блокам. 7. (Опц.) **Аналитика по темам**: агрегат точности для рекомендаций. 8. (Опц.) Точечно дотегировать вопросы под новые темы (Производная, Иррациональные, Модуль, Показательные ур., Параметры). --- ## 9. Открытые вопросы | Вопрос | Заметка / дефолт | |---|---| | Что за набор `year=2025` (1020 вопросов)? | Уточнить происхождение (свежие ЦЭ/ЦТ-2025?); вероятно главный современный банк — проверить разметку по темам/типам | | Перетегировать ли под тонкие темы | По умолчанию — нет (вариант A); добавить только новые темы, дотегировать точечно | | Per-topic mastery / слабые темы | Пока считать join'ом; полноценный детектор — отдельная доработка | | Нужен ли отдельный признак «ЦТ/ЦЭ» | Уже есть `year` и `source_type`; при необходимости фильтровать по ним | | Таймер-пробник на 180 мин | Через `test.time_limit` (есть); полноценный mock как в exam-prep — опционально | | Судьба миграции 077 (exam-prep ctmath) | Оставлена (по решению), в БД не применяется; основной путь — этот документ |