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

Домен: roadmap / program

Roadmap — это публичная дорожная карта учебных программ. По умолчанию она находится на /program.

Главная задача roadmap: провести пользователя от предмета и уровня сложности к конкретной программе, модулям и темам.

Основные файлы

ЗонаФайлы
Route registrationapp/Providers/Frontend/ModernRoadmapProvider.php
Controllerapp/Http/Controllers/ModernRoadmapController.php
Stateapp/Domains/ModernRoadmap/State.php
Storage/cacheapp/Domains/ModernRoadmap/Storage.php
Defaultsapp/Domains/ModernRoadmap/DefaultSlugHelper.php
Step availabilityapp/Domains/ModernRoadmap/PageAvailableHelper.php
Selectorsapp/Domains/ModernRoadmap/SelectorBuilders/*
Module buildersapp/Domains/ModernRoadmap/Builders/*
Livewire shellapp/Livewire/ModernRoadmap/UnauthorizedRoadmapSpa.php
Main viewresources/views/pages/modern-roadmap.blade.php
Component viewsresources/views/livewire/modern-roadmap/*
Program modelsapp/Models/Education/Program/*
Roadmap configsapp/Models/Landing/Roadmap/Config/*
Mini-group roadmapapp/Models/Landing/Roadmap/MiniGroup/*

URL-структура

Roadmap routes:

/program
/program/{subject_slug}
/program/{subject_slug}/{level_slug}
/program/{subject_slug}/{level_slug}/{mode}
/program/{subject_slug}/{level_slug}/{mode}/{mode_variant}

Шаги:

  1. subject_slug — предмет.
  2. level_slug — уровень сложности.
  3. mode — режим отображения программы.
  4. mode_variant — вариант режима, например трек.

State

State — это расширенная коллекция с фиксированными ключами:

  • selectedSubject;
  • selectedDifficultyLevel;
  • selectedMode;
  • selectedModeVariant.

State умеет выбирать каждый следующий уровень. Если передан _, он подставляет дефолтное или первое доступное значение через DefaultSlugHelper.

Пример логики:

  • выбрать предмет;
  • если level не указан, выбрать дефолтный level;
  • если mode не указан, выбрать первый mode;
  • если mode variant не указан, выбрать первый variant.

Storage

Storage — локальный cache вокруг selector builders. Он не хранит данные между запросами глобально, но предотвращает повторную сборку одинаковых selector-ов внутри одного state lifecycle.

Storage отдаёт:

  • subjects;
  • difficulty levels для выбранного subject;
  • modes для выбранного subject + level;
  • mode variants для выбранного subject + level + mode.

Defaults

DefaultSlugHelper выбирает дефолты:

  • subject с roadmapConfig.unauthorized_roadmap_default = true и hidden = false, иначе первый не скрытый subject;
  • level с roadmapConfig.unauthorized_roadmap_default = true и hidden = false внутри subject, иначе первый не скрытый level;
  • первый доступный mode;
  • первый доступный mode variant.

Практический вывод: если /program редиректит не туда, проверяйте roadmap config у subject/level.

Доступность промежуточных страниц

PageAvailableHelper решает, показывать ли страницу выбора subject/level/mode/variant.

Сейчас флаги $enabled в helper-методах выставлены в false. Поэтому логика обычно схлопывает промежуточные страницы и редиректит пользователя на дефолтный путь.

Это важная продуктовая особенность: отсутствие страницы выбора может быть не багом routing, а текущей настройкой helper-а.

Modes и builders

ModulesResolver выбирает стратегию по mode:

ModeBuilder
defaultDefaultBuildStrategy
mini-groupsMiniGroupsBuildStrategy
coursesCoursesBuildStrategy

Если subject, level или mode не выбраны, resolver возвращает пустой массив.

Если mode требует variant, но variant отсутствует, resolver тоже возвращает пустой массив.

Предметная модель roadmap

Основные модели:

МодельЧто означает
SubjectПредмет, например математика
SubsubjectПодпредмет
DifficultyLevelУровень сложности/класс/уровень программы
TopicModuleМодуль тем
TopicТема
MiniGroupProgramПрограмма мини-группы для subject + level + track
MiniGroupModuleМодуль внутри программы мини-группы
MiniGroupModuleTopicPivot между модулем и темой с позицией
SubjectRoadmapConfigНастройки subject для roadmap
DifficultyLevelRoadmapConfigНастройки level для roadmap

Subject

Subject:

  • хранит name, cipher, slug, position, label_forms;
  • сортируется глобальным scope по position;
  • при создании автоматически создаёт roadmapConfig;
  • при удалении удаляет roadmapConfig;
  • связан с Subsubject, DifficultyLevel, темами через deep relation.

DifficultyLevel

DifficultyLevel:

  • принадлежит subject;
  • связан с grades;
  • связан с products;
  • связан с topics и topic modules;
  • связан с mini-group programs;
  • при создании создаёт roadmap config;
  • при сохранении синхронизирует дерево top/sub levels по subject.

Важная логика: syncSubsForSubjectId() и findSubs() строят связи difficulty_levels_tree между top-level и sub-level уровнями по пересечению grades.

MiniGroupProgram

MiniGroupProgram задаёт программу для:

  • subject;
  • difficulty level;
  • track.

Computed name строится как предмет, уровень, N трек.

Через relations можно получить modules, topics и pivot-записи тем.

Как добавить программу в roadmap

Минимальный порядок:

  1. Убедиться, что есть Subject со slug.
  2. Убедиться, что есть DifficultyLevel для этого subject со slug.
  3. Проверить roadmapConfig: не скрыты ли subject/level.
  4. Для mini-groups создать MiniGroupProgram с subject, level и track.
  5. Добавить modules через relation manager.
  6. Добавить topics и позиции.
  7. Проверить, что selector builder возвращает нужный mode и variant.
  8. Открыть /program/{subject}/{level}/{mode}/{variant}.

Типичные причины пустой roadmap

  • Subject скрыт в roadmap config.
  • Difficulty level скрыт в roadmap config.
  • Для выбранного subject/level нет modes.
  • Для mode mini-groups или courses нет variant.
  • Для выбранного variant нет modules.
  • Темы не связаны с modules.
  • URL содержит slug, которого нет в subjects или difficulty_levels.
  • Промежуточная страница недоступна и controller редиректит на default path.

Админские точки управления

Что менятьГде
ПредметыSubjectResource
Уровни сложностиDifficultyLevelResource или relation manager subject
ТемыTopicResource
Модули темrelation managers уровня/программы
Программы мини-группMiniGroupProgramResource
Roadmap config subjectSubjectResource
Roadmap config levelDifficultyLevelResource