Dev.to WebDev πŸ›  Dev πŸ‘ 0 πŸ“– 1 min read

Let Course Progress Follow Evidence, Not Session Endings

I build Pianory, a browser-based piano practice app. AI helped draft this article; I checked every implementation claim against the current course source and focused spec file. A finished player session tells you that p

I build Pianory, a browser-based piano practice app. AI helped draft this article; I checked every implementation claim against the current course source and focused spec file.

A finished player session tells you that playback ended. It does not, by itself, tell you that a course step met its completion rule. In Pianory’s course domain model, progress is tied to the evidence each step asks for.

courseAttemptMeetsPolicy first requires a completed attempt with evidence. It then applies the step’s rule: a self-report needs the configured rating, pass count, and criteria, plus any configured delayed-review requirement; a quiz needs the minimum total and correct answers; measured evidence needs a passing observation with supported input, enough confidence, and the matching capability and benchmark version.

advanceCourseEnrollment also checks that the attempt matches the active enrollment, pinned course version, current step, and phase. An ordinary partial result increments the revision while keeping the learner on the same cursor. A stuck self-report can enter an explanation phase only when that step has a configured recovery branch. A skip is different: it can advance the cursor, while its immutable attempt remains labeled skipped.

There is a persistence boundary too. commitCourseEnrollment writes the progress snapshot and immutable attempt in one IndexedDB readwrite transaction; for signed-in accounts it also queues the sync operation in that transaction. Replaying the same attempt id with identical evidence is a no-op. Reusing it with different evidence conflicts.

The focused course-journey spec includes cases for quiz evidence, partial attempts, and explicit skips. This article describes source and spec behavior; I did not run the test suite today, and these rules do not establish a learner outcome or prove every remote sync scenario. Sources: src/lib/domain/course.ts, src/lib/domain/course-journey.ts, src/lib/client/storage/index.ts, and src/lib/domain/course-journey.spec.ts.

πŸ“° Read the original article on Dev.to WebDev

Originally published by Dev.to WebDev. Aggregated on AIWithGhost for educational purposes β€” full credit and traffic to the original publisher.