Перейти к основному содержимому

Модель данных LMS

Зачем нужно

Документ описывает доменную модель LMS на уровне сущностей, связей и обязательных полей. Физическая SQL-схема вынесена в database-schema.md, API-контракты — в api-contracts.md.

Слои модели

LMS состоит из основных учебных слоёв и рабочего слоя Learning Workspace:

СлойЧто хранитПримеры сущностей
Content structureчто существует как учебный материалcourse, version, node, block
Learning accessкто и на каких условиях проходитenrollment, teacher assignment
Learning Workspaceрабочий контур преподавателя поверх учебных и соседних доменовlearning group, participant, invite, assignment
Roadmapканоническую учебную траекториюroadmap program, module, topic, pathway
Live deliveryрасписание и факт учебного занятияgroup, session, attendance, room
Learning activityчто ученик сделалattempt, submission, workbook revision, chat message
Learning resultчто система посчиталаprogress snapshot, evidence, completion
Gamificationмотивационные начисленияxp, badge, streak

Эти слои нельзя смешивать. Например, content block не должен хранить персональный progress, а enrollment не должен хранить структуру курса.

Learning Workspace — рабочий слой, который связывает преподавателя, выбранную организацию и аудиторию назначений. Он не создаёт отдельный canonical student registry и не заменяет LMS enrollment/progress.

Course

lms_course — учебная программа внутри LMS.

Обязательные поля:

ПолеОписание
idстабильный идентификатор
slugчеловекочитаемый уникальный ключ
titleназвание
subject_keyпредмет или направление
statusdraft, review, published, archived
default_localeосновной язык контента
visibilityprivate, internal, public_preview
created_by_user_idавтор

Правила:

  • course является контейнером, а не конкретным снимком контента;
  • ученик проходит не “текущий курс”, а конкретную опубликованную версию;
  • storefront может показывать публичную проекцию course, но не владеет course.

Course version

lms_course_version — версия структуры и контента курса.

Поля:

ПолеОписание
course_idссылка на course
versionмонотонный номер версии
statusdraft, review, published, retired
published_atдата публикации
published_by_user_idкто опубликовал
source_version_idиз какой версии создан draft
content_hashhash структуры для воспроизводимости

Правила:

  • published version immutable;
  • draft version можно редактировать;
  • retirement запрещает новые enrollments, но не ломает текущие;
  • progress всегда хранит course_version_id.

Learning node

lms_node — узел дерева курса.

Типы:

  • module;
  • section;
  • lesson;
  • intensive_day;
  • checkpoint;
  • project_stage;
  • supplement.

Поля:

ПолеОписание
course_version_idверсия курса
parent_idродительский узел
typeтип узла
titleназвание
positionпорядок среди siblings
unlock_ruleправило открытия
completion_ruleправило завершения
estimated_minutesоценка длительности
roadmap_topic_refsreferences на roadmap topics внутри LMS

Правила:

  • дерево должно быть ацикличным;
  • один root node на course version допустим, но не обязателен, если course itself играет роль root;
  • published tree нельзя менять без новой version;
  • урок — это node типа lesson, а не отдельная таблица.

Content block

lms_content_block — отображаемый или интерактивный блок внутри lesson node.

Типы:

  • text;
  • video;
  • file;
  • image;
  • embed;
  • quiz;
  • task_bank_ref;
  • assignment;
  • workbook_prompt;
  • project_milestone;
  • interactive.

Поля:

ПолеОписание
node_idlesson или другой node
typeтип блока
bodyструктурированное содержимое
positionпорядок
requiredвлияет ли на completion
activity_kindнужно ли действие ученика
task_bank_problem_refссылка на task-bank, если применимо
max_scoreмаксимум баллов, если блок оценивается

Правила:

  • body хранится как JSON, но должен валидироваться схемой по типу блока;
  • task-bank answer key в LMS не хранится;
  • required block должен участвовать в completion rule;
  • attachment references должны указывать на storage object, а не хранить бинарные данные.

Roadmap

Roadmap находится внутри LMS по ADR-029. Он отвечает за канонические учебные траектории, темы, pathways и topic-level completion.

roadmap_program

Учебная программа или направление дорожной карты.

Поля: slug, title, subject_key, level_key, status, published_version, owner_user_id, supports_tracks.

Типовая годовая программа может содержать около 32 тем, но это стандарт, а не инвариант. Пилоты, интенсивы, вводные программы и новые направления могут иметь меньше или больше тем.

roadmap_module

Крупный блок внутри program. Поля: program_id, title, position, completion_rule, status.

roadmap_topic

Каноническая учебная тема. Не равна LMS lesson и не равна task-bank problem.

Поля: program_id, module_id, code, title, difficulty, prerequisite_topic_refs, status.

prerequisite_topic_refs описывает учебные зависимости внутри roadmap. entry_requirements не заменяют эти зависимости: это non-blocking projection/editorial structure для комфортного входа в продукт, запуск или модуль.

topic_pathway

Вариант прохождения темы для формата, уровня или цели.

Поля: topic_id, format_key, target_level_key, recommended_lms_refs, recommended_task_refs, product_refs, product_run_refs, group_refs, session_refs, track_ref, availability_state, roadmap_layer, completion_contribution, is_recommended, status.

roadmap_layer принимает значения core, supplemental, free_entry, gap_closing, event, competition, enrichment, diagnostic, individual.

completion_contribution определяет, может ли pathway давать evidence для topic_completion: none, evidence_only, partial, full_if_rule_allows.

product_refs и product_run_refs являются external references на CRM. Они не делают CRM владельцем темы или completion.

mini_group_track

Траектория мини-группы или кружка, связывающая roadmap topics, sessions и LMS content.

Поля: title, program_id, format_key, starts_at, ends_at, status, default_schedule_rule_id, topic_sequence, module_sequence, display_priority.

Треки являются универсальным механизмом программы и формата, а не только олимпиадной математики. UI может показывать максимум два основных трека, но модель не ограничивает количество треков.

topic_progress

Персональный агрегат прогресса по теме.

Поля: student_profile_id, topic_id, status, mastery_score, evidence_summary, calculated_at.

topic_completion

Факт завершения темы по правилам roadmap.

Поля: topic_progress_id, completed_at, rule_version, evidence_refs, approved_by_user_id, source, override_reason, audit_ref.

Manual override completion разрешён только с audit. Attendance, lesson completion, homework, task-bank result, diagnostic или competition result могут быть evidence, но не создают completion без rule.

topic_enrichment

Методическое расширение темы: публичное описание, подсказки, рекомендуемые задачи и материалы.

Learning Workspace

Learning Workspace задаёт общий преподавательский контур “мои ученики/мои группы”.

learning_group

Рабочая группа преподавателя в выбранной организации.

Поля: organization_id, owner_teacher_user_id, title, description, status, created_by_user_id, archived_at.

Правила:

  • learning_group не равна live group из расписания;
  • organization_id — external ref на identity organization, а не локальная организация LMS;
  • одна Learning Group может использоваться LMS, олимпиадами, тренажёрами и task-bank assignments;
  • архивация группы не удаляет LMS progress, attempts или competition results.

learning_group_participant

Участник рабочей группы.

Поля: group_id, student_profile_id, status, source, added_by_user_id, joined_at, removed_at.

Правила:

  • participant хранит ссылку на student_profile_id, а не отдельную карточку ученика;
  • участие в группе не создаёт lms_enrollment;
  • участие в группе не даёт право читать progress без teacher assignment;
  • один student profile может входить в несколько Learning Groups.

learning_group_invite

Приглашение ученика, родителя или семьи.

Поля: group_id, target_type, student_profile_id, identity_invite_ref, status, expires_at, accepted_at.

Правила:

  • raw token, email/phone и claim flow принадлежат identity/notifications;
  • accept invite активирует participant только после identity validation;
  • parent invite не открывает родителю доступ ко всей группе.

learning_group_assignment

Назначение учебного действия группе или подмножеству участников.

Поля: group_id, created_by_user_id, target_domain, target_type, target_ref, participant_filter, status, due_at, cancelled_at.

Target examples:

  • lms_course;
  • lms_lesson;
  • trainer;
  • competition_training;
  • competition_debrief;
  • task_bank_set.

Правила:

  • assignment не является progress;
  • assignment на LMS course не заменяет enrollment;
  • assignment на task-bank set не переносит задачу в LMS;
  • assignment на олимпиадный тренажёр или разбор создаёт учебный контекст, а не competition attempt/result.

Enrollment

lms_enrollment — учебная связь ученика с course version.

Поля:

ПолеОписание
student_profile_idученик
course_idcourse
course_version_idверсия, которую проходит ученик
sourcemanual, crm_entitlement, competition, migration
source_refссылка на внешний источник
statuspending, active, paused, completed, revoked
started_atначало
completed_atзавершение
revoked_atотзыв доступа

Правила:

  • один ученик может иметь несколько enrollments на разные versions или cohorts, если это явно разрешено;
  • revoked запрещает новый доступ к lessons, но история остаётся видимой по правилам;
  • изменение course version для active enrollment требует migration record.

Teacher assignment

lms_teacher_assignment задаёт область видимости преподавателя.

Контексты:

  • course;
  • course version;
  • cohort;
  • group;
  • learning_group;
  • enrollment;
  • project;
  • workbook;
  • booking slot.

Поля:

ПолеОписание
teacher_user_idпользователь-преподаватель
scope_typeтип области
scope_idидентификатор области
roleteacher, checker, mentor, substitute
statusactive, paused, ended
starts_at, ends_atпериод действия

Преподавательский доступ всегда проверяется через assignment, а не только через глобальную роль.

Если scope_type = learning_group, assignment даёт доступ к рабочему списку группы. Доступ к progress, attempts, submissions и feedback всё равно проверяется по LMS enrollment/course/node scopes.

Activity attempt

lms_activity_attempt — попытка ученика выполнить activity.

Поля:

ПолеОписание
enrollment_idenrollment
node_idlesson или node
content_block_idactivity block
attempt_noномер попытки
statusstarted, submitted, checking, checked, accepted, returned, cancelled
answerответ ученика, если хранится в LMS
scoreрезультат
checker_sourcetask_bank, teacher, manual, external
submitted_at, checked_attimestamps

Правила:

  • попытка всегда принадлежит enrollment;
  • sensitive answer может храниться отдельно или шифроваться в зависимости от типа;
  • изменение score после проверки создаёт audit и новое событие.
  • тренировочная попытка по олимпиадному материалу является LMS/activity или task-bank attempt в учебном contextDomain lms; она не является competition_submission и не меняет competition_result.

Submission

lms_submission — отправленная работа ученика. Она может быть связана с attempt, workbook, project или homework block.

Поля:

ПолеОписание
enrollment_idenrollment
attempt_idпопытка, если есть
source_typeactivity, workbook, project, homework
source_idобъект-источник
statusdraft, submitted, in_review, returned, accepted, reopened
payloadструктурированная работа
submitted_atдата сдачи

Feedback

lms_feedback — обратная связь по submission или attempt.

Поля:

ПолеОписание
submission_idработа
author_user_idпреподаватель или system actor
author_typeteacher, auto_checker, support, system
status_decisionитоговое решение
scoreбаллы
commentкомментарий
rubricструктурированная оценка
visible_to_studentвидимость ученику

Progress snapshot

lms_progress_snapshot — агрегированное состояние прохождения enrollment и node.

Поля:

ПолеОписание
enrollment_idenrollment
course_version_idверсия курса
node_idcourse, module или lesson node
statusnot_started, in_progress, completed, needs_review
completion_percentпроцент
score_summaryагрегированный score
evidence_summaryкраткая структура evidence
last_activity_atпоследняя активность
completed_atзавершение
calculated_atкогда рассчитано

Progress snapshot можно пересчитать из событий и attempts, но он нужен для быстрых экранов.

Learning evidence

lms_learning_evidence — нормализованное доказательство активности.

Источники:

  • lesson opened;
  • content block viewed;
  • video watched;
  • quiz submitted;
  • task-bank result;
  • homework accepted;
  • teacher feedback;
  • booking attended, если attendance разрешён как evidence;
  • imported external progress.

Evidence не равно mastery. Roadmap-слой LMS может использовать evidence, но решение о mastery принимает topic_completion.

Live delivery and calendar

Live delivery находится внутри LMS по ADR-025 и ADR-030. CRM владеет правом доступа и списанием entitlement, LMS владеет учебным расписанием, посещаемостью и evidence занятия.

group

Учебная группа, мини-группа, кружок или поток.

Поля: title, format_key, roadmap_program_id, mini_group_track_id, status, starts_at, ends_at.

Это live delivery group для расписания и занятий. Она не равна learning_group из Learning Workspace, хотя может быть связана с ней через explicit reference или assignment.

schedule_rule

Правило расписания занятий: recurrence, timezone, длительность, преподавательский состав и room policy.

room

Физическая или виртуальная комната занятия.

Поля: type, title, location, capacity, meeting_provider, status.

session

Конкретное live-занятие.

Поля: group_id, starts_at, ends_at, room_id, teacher_user_id, status, source_schedule_rule_id.

attendance

Факт учебного присутствия.

Поля: session_id, student_profile_id, status, marked_by_user_id, marked_at, evidence_policy, entitlement_consumption_ref.

Связь занятия с roadmap topic.

Связь занятия с LMS lesson/node.

session_change

Аудируемое изменение занятия: перенос, замена преподавателя, смена комнаты, отмена.

makeup_assignment

Назначение отработки или компенсационного занятия.

Workbook

lms_workbook — персональное рабочее пространство ученика.

Сущности:

  • workbook;
  • workbook page;
  • workbook revision;
  • workbook attachment;
  • workbook comment.

Workbook связан с enrollment и может быть привязан к lesson, project или activity.

Course project

lms_project — долгоживущий учебный проект.

Сущности:

  • project;
  • milestone;
  • project submission;
  • project feedback;
  • project artifact.

Проект может влиять на course completion через completion rule.

Booking

lms_booking_slot и lms_booking используются только для учебной записи, если LMS владеет сценарием записи.

Если слот является частью расписания live-занятий, источник истины — LMS live delivery: session, attendance, schedule_rule, room.

Gamification

Геймификация находится внутри LMS по ADR-028. Она может использовать LMS activity, attendance, topic completion и task-bank result как evidence, но не заменяет completion.

xp

Текущий агрегат опыта пользователя по scope.

Поля: student_profile_id, scope_type, scope_id, amount, level, updated_at.

xp_event

Append-only начисление или списание опыта.

Поля: student_profile_id, amount, reason, source_type, source_id, idempotency_key.

badge

Описание достижения.

Поля: slug, title, description, scope_type, criteria, status.

badge_award

Факт выдачи badge пользователю.

Поля: badge_id, student_profile_id, source_type, source_id, awarded_at, revoked_at.

streak

Серия регулярной активности.

Поля: student_profile_id, scope_type, current_count, best_count, last_activity_at, status.

Chat

lms_chat_thread — учебный чат в контексте course, lesson, enrollment, project или booking.

Сущности:

  • chat thread;
  • participant;
  • message;
  • attachment;
  • read receipt;
  • moderation event.

Чат не является CRM/support коммуникацией и не должен использоваться для финансовых вопросов.

Audit

Аудируются:

  • публикация course version;
  • enrollment state transitions;
  • ручное изменение progress;
  • проверка submission;
  • override score;
  • выдача или отзыв teacher assignment;
  • изменения Learning Group, participants, invites и assignments;
  • модерация chat;
  • перенос booking;
  • импорт внешнего progress.

Audit должен хранить actor, action, target, old value, new value, reason и request id.