Fix practice completion roll-up for non-module scopes.

Resolve practice hierarchy using module, lesson, or course linkage and only run module-level cascade when module context exists.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Yared Yemane 2026-05-13 03:58:39 -07:00
parent 4ada908555
commit 8bba318372

View File

@ -32,7 +32,7 @@ func (s *Store) CompleteLessonForUser(ctx context.Context, userID, lessonID int6
return err return err
} }
if err := s.cascadeLMSCompletion(ctx, q, userID, mod.ID, crs.ID, crs.ProgramID); err != nil { if err := s.cascadeLMSCompletion(ctx, q, userID, &mod.ID, crs.ID, crs.ProgramID); err != nil {
return err return err
} }
@ -62,21 +62,43 @@ func (s *Store) CompletePracticeForUser(ctx context.Context, userID, questionSet
if err != nil { if err != nil {
return err return err
} }
if !scope.ModuleID.Valid { var (
return fmt.Errorf("practice %d is not linked to a module", questionSetID) moduleID *int64
courseID int64
)
switch {
case scope.ModuleID.Valid:
mid := scope.ModuleID.Int64
moduleID = &mid
mod, err := q.GetModuleByID(ctx, mid)
if err != nil {
return err
}
courseID = mod.CourseID
case scope.LessonID.Valid:
lesson, err := q.GetLessonByID(ctx, scope.LessonID.Int64)
if err != nil {
return err
}
mid := lesson.ModuleID
moduleID = &mid
mod, err := q.GetModuleByID(ctx, mid)
if err != nil {
return err
}
courseID = mod.CourseID
case scope.CourseID.Valid:
courseID = scope.CourseID.Int64
default:
return fmt.Errorf("practice %d is not linked to lesson/module/course", questionSetID)
} }
mod, err := q.GetModuleByID(ctx, scope.ModuleID.Int64) crs, err := q.GetCourseByID(ctx, courseID)
if err != nil { if err != nil {
return err return err
} }
crs, err := q.GetCourseByID(ctx, mod.CourseID) if err := s.cascadeLMSCompletion(ctx, q, userID, moduleID, crs.ID, crs.ProgramID); err != nil {
if err != nil {
return err
}
if err := s.cascadeLMSCompletion(ctx, q, userID, mod.ID, crs.ID, crs.ProgramID); err != nil {
return err return err
} }
@ -86,24 +108,25 @@ func (s *Store) CompletePracticeForUser(ctx context.Context, userID, questionSet
return nil return nil
} }
func (s *Store) cascadeLMSCompletion(ctx context.Context, q *dbgen.Queries, userID, moduleID, courseID, programID int64) error { func (s *Store) cascadeLMSCompletion(ctx context.Context, q *dbgen.Queries, userID int64, moduleID *int64, courseID, programID int64) error {
moduleLessonsTotal, err := q.CountLessonsInModule(ctx, moduleID) if moduleID != nil {
moduleLessonsTotal, err := q.CountLessonsInModule(ctx, *moduleID)
if err != nil { if err != nil {
return err return err
} }
moduleLessonsDone, err := q.CountUserCompletedLessonsInModule(ctx, dbgen.CountUserCompletedLessonsInModuleParams{ moduleLessonsDone, err := q.CountUserCompletedLessonsInModule(ctx, dbgen.CountUserCompletedLessonsInModuleParams{
ModuleID: moduleID, ModuleID: *moduleID,
UserID: userID, UserID: userID,
}) })
if err != nil { if err != nil {
return err return err
} }
modulePracticesTotal, err := q.CountPublishedPracticesInModule(ctx, toPgInt8(&moduleID)) modulePracticesTotal, err := q.CountPublishedPracticesInModule(ctx, toPgInt8(moduleID))
if err != nil { if err != nil {
return err return err
} }
modulePracticesDone, err := q.CountUserCompletedPublishedPracticesInModule(ctx, dbgen.CountUserCompletedPublishedPracticesInModuleParams{ modulePracticesDone, err := q.CountUserCompletedPublishedPracticesInModule(ctx, dbgen.CountUserCompletedPublishedPracticesInModuleParams{
ModuleID: toPgInt8(&moduleID), ModuleID: toPgInt8(moduleID),
UserID: userID, UserID: userID,
}) })
if err != nil { if err != nil {
@ -116,9 +139,10 @@ func (s *Store) cascadeLMSCompletion(ctx context.Context, q *dbgen.Queries, user
return nil return nil
} }
if err := q.InsertUserModuleProgress(ctx, dbgen.InsertUserModuleProgressParams{UserID: userID, ModuleID: moduleID}); err != nil { if err := q.InsertUserModuleProgress(ctx, dbgen.InsertUserModuleProgressParams{UserID: userID, ModuleID: *moduleID}); err != nil {
return err return err
} }
}
nMods, err := q.CountModulesInCourse(ctx, courseID) nMods, err := q.CountModulesInCourse(ctx, courseID)
if err != nil { if err != nil {