Skip to content

Modifying Published Courses

Status: This is a complex area that needs more work to become predictable and well-documented. The current behavior has edge cases that may require manual intervention. Always consult with the development team before making significant changes.

This guide explains how course modifications affect enrolled members and what to expect.

Current Challenges

Before diving into specifics, understand these limitations:

  1. No automated tooling - There's no admin UI to safely restructure courses. Changes require understanding the data model.
  2. Many pre-calculated values - For performance, scores, quiz counts, completion times, and progress data are stored as cached values rather than calculated on-the-fly. When course structure changes, these cached values can become stale or incorrect.
  3. Completion state complexity - Lesson/LessonItem completion is tracked by IDs (and cached within CourseEnrollment). Deleting content can leave orphaned references.
  4. Score recalculation is manual - After structural changes, scores may need manual recalculation via Nova.
  5. Rankings affected unpredictably - Changes to quiz points affect rankings in ways that may seem unfair to members.
  6. No "preview" mechanism - You cannot preview how changes will affect existing enrollments.

How Course Schedules Work

When a course opens for enrollment, a CourseSchedule is created as a snapshot:

text
Course (template)
    └── CourseSchedule #1 (Jan 2025) ─── created from Course at that moment
    │       ├── LessonSchedules (snapshot of lessons)
    │       └── Enrollments (150 members)

    └── CourseSchedule #2 (Feb 2025) ─── created from Course after update
            ├── LessonSchedules (includes changes)
            └── Enrollments (new members)

Key principle: Changes to a Lessons List only affect future CourseSchedules. Existing CourseSchedules retain their original Lessons.

What Gets Affected by Changes

Scores

What you changeImpact on existing enrollments
Add new quizMembers can answer → earn more points than "maximum" for their schedule
Remove quizQuiz answer records remain but quiz is gone → confusing UI state
Change quiz pointsOld answers keep old score; recalculation needed for consistency
⚙️ Technical: The schedule_full_score problem

Each CourseSchedule caches the total possible points in schedule_full_score. This is NOT automatically updated when quizzes change, leading to percentage calculations that don't add up.

Completion States

What you changeImpact
Remove a Lesson from CourseExisting enrollments keep their LessonSchedule (safe)
Remove a LessonItem from LessonCompletion reference may point to deleted content
Add new LessonItem to completed LessonLesson shows as "complete" but has unanswered content
Add quiz to visited LessonItemLessonItem no longer counts as "complete"

UI implications: A member might see a Lesson marked "complete" that contains unanswered quizzes, or progress percentages that don't match reality.

⚙️ Technical: How completion is tracked

Completion is tracked in CourseEnrollmentProgress using arrays of IDs:

php
$completed_lessons = [lesson_id => timestamp, ...]
$completed_lesson_items = [lesson_item_id => timestamp, ...]
$visited_lesson_items = [lesson_item_id => timestamp, ...]

When content is deleted, these IDs become orphaned references pointing to non-existent records.

Rankings

Rankings compare all members across ALL CourseSchedules of a course (not per-schedule).

What you changeImpact
Add quizzesOld members can earn extra points → unfair advantage
Remove quizzesOld members keep points others can't earn → unfair advantage
Change point valuesDifferent schedules have different maximums

There's no good solution here without either:

  • Allowing score inflation (option A: members keep everything)
  • Causing member frustration (option B: recalculate/remove scores)

Safe vs Risky Modifications

Safe: Replace Entire Lessons

The safest approach for significant changes:

  1. Create new Lesson(s) with LessonItems and Quizzes
  2. Remove old Lesson(s) from the Course (soft-delete)

Result:

  • Existing enrollments keep their LessonSchedules pointing to deleted lessons
  • Members retain all scores and completion status
  • Future schedules get the new structure
⚙️ Technical: Why this works

LessonSchedules use withoutGlobalScopes([SoftDeletingScope::class]) to access soft-deleted lessons. This means the relationship still resolves even after the lesson is "deleted".

Safe: Add New Lessons

Adding lessons without removing existing ones:

  • New lessons appear in future CourseSchedules only
  • Existing Enrollments are unaffected
  • Rankings unaffected (new quizzes aren't accessible to old enrollments)

Risky: Modify Existing Lesson Content

Adding/removing LessonItems or Quizzes within existing lessons:

ChangeRisk LevelIssue
Add optional LessonItem (no quiz)LowMay confuse members with "new" content
Add LessonItem with quizMediumExisting members can earn extra points
Remove LessonItemHighOrphaned completion references
Remove QuizHighQuizAnswer orphaned; points may be invalid
Move Quiz between LessonItemsHighCompletion states become incorrect

Dangerous: Moving Quizzes Between Lessons

This breaks multiple things:

  • Completion tracking for both source and destination lessons
  • Quiz answer counts per lesson
  • Progress calculations

Do not do this. Create new lessons instead.

What to Expect After Changes

Immediately After

  • New CourseSchedules will use an updated structure
  • Existing enrollments appear unchanged

Over Time

  • Members may notice inconsistencies (completed lessons with unanswered quizzes)
  • Rankings may shift unexpectedly if new quizzes are accessible
  • Support tickets about "broken" course progress

Manual Intervention Needed

After structural changes, you may need to ask the dev team to:

  1. Recalculate scores for affected enrollments
  2. Fix full scores if quiz points changed
  3. Clear caches for progress data
⚙️ Technical: Recalculation tools
  • Nova action: RecalculateScheduleEnrollmentsScoresAction on CourseSchedule detail page
  • Field to update: CourseSchedule.schedule_full_score
  • Action class: RecalculateEnrollmentScoresAndStateAction

Before Making Changes

  1. Document the change - What lessons/items are affected?
  2. Check enrollment status - How many members are currently enrolled?
  3. Assess timing - Can this wait until current schedule closes?
  4. Consult dev team - For anything beyond simple additions

Making Changes

For major restructuring:

  1. Create new Lesson(s) with full content
  2. Test in a staging environment
  3. Remove old Lesson(s) from Course
  4. Verify next CourseSchedule looks correct
  5. Monitor for issues

For minor additions:

  1. Add content
  2. Consider if recalculation is needed
  3. Document the change for future reference

After Changes

  • Monitor support channels for confusion
  • Be prepared to run recalculations
  • Document any workarounds applied

Tools Available

Nova Admin Panel

  • Course Schedules - View and manage schedules
  • Recalculate Scores - Action on CourseSchedule detail page
  • View Timeline - See schedule structure
⚙️ Technical: Console Commands
bash
# Recalculate enrollment scores (run with dev team)
php artisan course:recalculate-enrollment-scores

# Check for score inconsistencies
php artisan course:check-frequent-score-recalculations

Future Improvements Needed

This system needs work to become more predictable:

  1. Admin tooling - UI to preview changes before applying
  2. Automated recalculation - Trigger score updates when structure changes
  3. Version control for courses - Track what content each enrollment saw
  4. Clear migration paths - Documented procedures for common scenarios
  5. Orphan cleanup - Handle references to deleted content gracefully
  6. Per-schedule rankings - Option to rank within schedule only

FAQ

Q: Can I just edit quiz text without affecting anything? A: Yes, text changes to questions/answers are safe. Changing the correct answer is not.

Q: A member is complaining about wrong progress. What do I do? A: Check Enrollment Scores/Completion Breakdown on Nova. Try recalculating their enrollment scores via Nova. If that doesn't help, escalate to dev team.

Q: Should we create a new course instead of modifying? A: Consider it if changes are extensive enough that it's "essentially a different course."

Q: Why can't we just update everything automatically? A: The system was designed for course schedules to be immutable snapshots. Retrofitting automatic updates would require significant architectural changes.