ну смотри
у тебя по сути может быть курс и юзер многие ко многим
таблица course_user (course_id, user_id)
и аналогично уроки к юзеру многие ко многим
таблица lesson_user (course_id, lesson_id, user_id, completed_at)
в таблице lesson_user поле completed_at - это дата завершения урока, если там null, значит урок еще НЕ завершен, а если дата - завершен
пример
$couse = $user->courses()->findOrFail(123)
$lessons = $user->lessons()->wherePivot('course_id', $course->id)->get();
проверка
$lesson = $lessons->findOrFail(123)
abort_unless($lesson->pivot->completed_at, 403)
таким образом, если этот урок не пройден, будет доступ запрещен
типа того