feat(root): wire ROOT 05-10/12/Capstone curriculum expansion
023_phase6b_curriculum.sql — additive on top of 022_course_content.sql: 13 new teaching modules (ROOT 08/09 move from PLANNED to PARTIAL; ROOT 05-07/10 gain a new front-door module sequenced ahead of the existing bare-lab bank; ROOT 12 gains an incident-response framing lesson + reflection; Capstone gains a readiness module). No existing row is deleted; a small number of existing rows have their sequence/ prerequisites updated so a new teaching module supersedes the bare-lab bank as the front door — never their scenario_id/activity_type/ completion_behavior, so no student's derived completion changes meaning. is_required (new module_activities column, defaults true — every Phase 6A activity unaffected) lets a module distinguish CORE teaching from GUIDED/INDEPENDENT-practice duplicates and ADVANCED/optional extras. course-progress.js's totals() now considers a module complete once every REQUIRED activity is done, not literally every activity — an incomplete optional one no longer blocks completion, though it still counts toward the displayed percentage. Co-Authored-By: Claude Sonnet 5 <[email protected]>
This commit is contained in:
@@ -55,16 +55,27 @@ function shapeActivity(activity, ctx, forInstructor) {
|
||||
scenario_id: activity.scenario_id,
|
||||
assessment_definition_id: activity.assessment_definition_id,
|
||||
completion_behavior: activity.completion_behavior,
|
||||
is_required: activity.is_required,
|
||||
complete: isActivityComplete(activity, ctx),
|
||||
body: content?.shared || null,
|
||||
...(forInstructor ? { instructor_notes: content?.instructorNotes || null } : {}),
|
||||
};
|
||||
}
|
||||
|
||||
// Phase 6B §18/§27 — an optional activity (independent-practice duplicates, advanced/CKS-exam-
|
||||
// style extras) counts toward the displayed total/percent but NOT toward whether the module
|
||||
// itself is "complete." Every Phase 6A activity has is_required=true (the column's default,
|
||||
// unaffected by this), so this is purely additive — nothing that was complete before becomes
|
||||
// incomplete now.
|
||||
function totals(items) {
|
||||
const total = items.length;
|
||||
const completed = items.filter((i) => i.complete).length;
|
||||
return { total, completed, pct: total ? Math.round((completed / total) * 100) : 0, complete: total > 0 && completed === total };
|
||||
const required = items.filter((i) => i.is_required !== false);
|
||||
const requiredComplete = required.filter((i) => i.complete).length;
|
||||
return {
|
||||
total, completed, pct: total ? Math.round((completed / total) * 100) : 0,
|
||||
complete: required.length > 0 && requiredComplete === required.length,
|
||||
};
|
||||
}
|
||||
|
||||
// A prerequisite with zero content (a PLANNED module/course with nothing built yet) can never
|
||||
|
||||
Reference in New Issue
Block a user