feat: add sequential progression and video watch lesson completion

Gate student content by completion order, track per-video watch progress
with seek enforcement, and auto-complete lessons at the configured
threshold. Show ring progress in the lesson header, keep watch progress
on rewatch, and sync progression locks client-side so the next item
unlocks after completion.
This commit is contained in:
Rotimi Best
2026-06-11 14:48:34 +01:00
parent c8154409f5
commit 52d9bf18c3
94 changed files with 3499 additions and 564 deletions
@@ -90,7 +90,7 @@ const QUESTION_VALIDATION_RULES: Record<number, Array<(question: QuestionRuleInp
(question) => {
const settings = question.settings;
const template = String(settings?.template ?? '');
const blankCount = Math.max(0, template.split('___').length - 1);
const blankCount = (template.match(/_{3,}/g) ?? []).length;
if (blankCount < 1) {
return 'Word bank questions need at least one ___ blank in the template';
}
@@ -224,7 +224,9 @@ export const ZExerciseUpdate = z.object({
slug: ZSlug.optional(),
questions: z.array(ZExerciseUpdateQuestion).optional(),
sections: z.array(ZExerciseSection).optional(),
sectionDisplayMode: z.enum(['one_question', 'all_questions']).optional()
sectionDisplayMode: z.enum(['one_question', 'all_questions']).optional(),
completionPolicy: z.enum(['submitted', 'passed']).optional(),
passThreshold: z.number().int().min(0).max(100).optional()
});
export type TExerciseUpdate = z.infer<typeof ZExerciseUpdate>;