Skip to content

feat: persist a teacher-mediated Learning Path remediation loop - #393

Open
Ritwij07 wants to merge 3 commits into
vicharanashala:mainfrom
Ritwij07:feat/learning-path
Open

feat: persist a teacher-mediated Learning Path remediation loop#393
Ritwij07 wants to merge 3 commits into
vicharanashala:mainfrom
Ritwij07:feat/learning-path

Conversation

@Ritwij07

Copy link
Copy Markdown

No description provided.

Vasu and others added 3 commits August 29, 2026 12:44
The diagnostic already computes failedLevels, skillGaps, and a
one-shot reasoning.prerequisiteLearningPath on every EvaluationReport
— but all of it is a throwaway snapshot, recomputed from scratch each
time, with nowhere to record that a teacher has actually taught a gap
and the child has moved on. This closes that loop.

  failedLevels / skillGaps        (from an EvaluationReport)
    -> conceptIds                 (via CURRICULUM_MAPPING, S1.1..S7.18)
    -> resolvePrerequisites()     (competencyPrerequisites.ts edges)
    -> ordered LearningPathNode[] (foundations first, then the gaps)
    -> persisted on student.learningPath, edited in the panel

Backend:
- learningPathEngine.ts (new) — pure, dependency-free engine:
  buildLearningPath, applyNodeStatus, summarizeLearningPath,
  isLearningPathStatus. No express/db/IO — unit-testable in
  isolation. Nodes are keyed on the immutable conceptId tag, the same
  identity the existing prerequisiteLearningPath derivation uses, so
  the two never disagree.
- learningPathEngine.selftest.ts (new) — dependency-free assertion
  harness against the real curriculum graph: determinism,
  foundations-before-gaps ordering, no duplicate/overlapping nodes,
  foundation ordering by unblock-count then level, progress preserved
  across recompute, new gaps default to not_started, masteredAt
  set/cleared correctly, summary math, empty/skillGaps-fallback
  inputs, status validation. Wired as .
- routes/learningPath.ts (new) — four endpoints, mirroring
  routes/students.ts exactly for auth/scoping (getAuthUser +
  canAccessStudent, 401/403/404) and persisting through the same
  dbStore.updateStudent path the diagnostic handler already uses:
    GET   /api/students/:id/learning-path
    POST  /api/students/:id/learning-path/recompute
    PATCH /api/students/:id/learning-path/nodes/:conceptId
    GET   /api/students/:id/learning-path/nodes/:conceptId/practice
  Recompute is status-preserving: re-running a diagnostic never
  erases a teacher's recorded progress on a gap that still applies.
- db.ts —  +  on Student.
  Type-only import, erased at compile time, no runtime cycle.
- index.ts — registerLearningPathRoutes(app), same pattern as the
  other registerXRoutes calls.
- package.json — .

Frontend:
- LearningPathPanel.tsx (new) — student picker, foundations-before-
  gaps journey view, per-node status control (Not started / Teaching
  / Mastered) with live mastery %, recompute, and printable practice
  (Easier/Mastery/Remedial) per node via the existing
  generateQuestionsForLevel.
- types.ts — mirror LearningPath* types + learningPath? on Student.
- PanelViews.tsx — router entry for the learning_path panel.
- Layout.tsx — 'Learning Path' nav item under Assessment, for
  Teacher and Volunteer roles.

An all-pass diagnostic yields an honest empty path ('no current
gaps') rather than a fake one. Purely additive and backward-
compatible — learningPath is optional and absent until a teacher
first generates it; no migration, no change to existing reports or
placement logic; no new dependencies.

Verified: backend tsc --noEmit clean, npm test (17/17 self-test
assertions pass), frontend tsc --noEmit clean, both production
builds succeed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant