
❌ This issue is not open for contribution. Visit Contributing guidelines to learn about the contributing process and how to find suitable issues.

Target branch: develop
Observed behavior
Pre/post-test notifications carry a synthetic quiz_id hash (see get_synthetic_content_id), not a real Exam id. Three coach-frontend paths assume otherwise:
classSummary/actions.js: updateWithNotifications reloads the full class summary on !examMap[quiz_id]. A synthetic id never matches, so every pre/post-test notification triggers a full reload, every poll, forever.
coachNotifications/getters.js: reshapeNotification drops the notification (return null) when classSummary.exams[quiz_id] misses. Pre/post-test activity never appears in the coach's activity feed.
gettersUtils.js: notificationLink() routes Quiz notifications to Exam-only pages. Not reachable today (the getter above already drops these first) — but fixing the drop without also fixing this routes clicks into a 404.
Expected behavior
All three paths should branch on notification.course_session_id (present on all notifications — confirmed serialized in ClassroomNotificationsSerializer) before falling back to exam-specific logic:
classSummary/actions.js: when notification.course_session_id is truthy, skip the !examMap[notification.quiz_id] check entirely (don't factor it into reloadSummary). All other checks in updateWithNotifications (learnerMap, lessonMap, contentNodeMap) are unaffected.
coachNotifications/getters.js: when classSummary.exams[notification.quiz_id] misses but notification.course_session_id is truthy, render the notification with a generic label (e.g. "Course activity") instead of returning null. No new title data is fetched.
gettersUtils.js: when notification.course_session_id is truthy, notificationLink() returns { name: PageNames.COURSE_SUMMARY, params: { classId: notification.collection.id, courseSessionId: notification.course_session_id } } instead of matching against pageNameToNotificationPropsMap.
User-facing consequences
Coaches can't see pre/post-test activity on the Coach Home activity feed, and classSummary silently reloads on every poll, which is a waste. Future fixes to feed visibility without updating the routing as well would cause errors.
Steps to reproduce
- Assign a course to a classroom and activate a pre/post-test for a unit (as coach).
- As a learner, start and complete the pre/post-test.
- As coach, open Coach Home and watch the activity feed / network tab.
- Observe: the classSummary API reloads on every notification poll for this activity (visible in network tab), and the pre/post-test completion never appears in the activity feed, even though the notification exists (confirmed via DB/store inspection).
Claim 3 (broken routing) isn't independently reproducible today — it only manifests once someone fixes claim 2 without also fixing routing, so no repro steps for it here.
Context
Application version: kolibri/0.20.0a2 (develop branch), same codebase as PR #15260.
Related: #15189, #15228, PR #15260 (this issue is item #5 from that PR's review, deferred as out of scope — fixing it means making shared coach-notification infrastructure course-aware, not something scoped to that PR's files).
Acceptance Criteria
AI usage
Drafted by Claude (Claude Code) from a code-review finding surfaced by an automated PR review bot (@rtibblesbot) on PR #15260. Claude independently verified all three claims by reading the cited source directly before drafting, including checking data availability (classSummary state has no course/unit title data — confirmed via direct code inspection) and the exact routing target (PageNames.COURSE_SUMMARY, notification.collection.id, serializer fields) before finalizing Expected Behavior and Acceptance Criteria. I edited/confirmed each section.
❌ This issue is not open for contribution. Visit Contributing guidelines to learn about the contributing process and how to find suitable issues.
Target branch: develop
Observed behavior
Pre/post-test notifications carry a synthetic
quiz_idhash (seeget_synthetic_content_id), not a realExamid. Three coach-frontend paths assume otherwise:classSummary/actions.js:updateWithNotificationsreloads the full class summary on!examMap[quiz_id]. A synthetic id never matches, so every pre/post-test notification triggers a full reload, every poll, forever.coachNotifications/getters.js:reshapeNotificationdrops the notification (return null) whenclassSummary.exams[quiz_id]misses. Pre/post-test activity never appears in the coach's activity feed.gettersUtils.js:notificationLink()routesQuiznotifications to Exam-only pages. Not reachable today (the getter above already drops these first) — but fixing the drop without also fixing this routes clicks into a 404.Expected behavior
All three paths should branch on
notification.course_session_id(present on all notifications — confirmed serialized inClassroomNotificationsSerializer) before falling back to exam-specific logic:classSummary/actions.js: whennotification.course_session_idis truthy, skip the!examMap[notification.quiz_id]check entirely (don't factor it intoreloadSummary). All other checks inupdateWithNotifications(learnerMap,lessonMap,contentNodeMap) are unaffected.coachNotifications/getters.js: whenclassSummary.exams[notification.quiz_id]misses butnotification.course_session_idis truthy, render the notification with a generic label (e.g. "Course activity") instead of returningnull. No new title data is fetched.gettersUtils.js: whennotification.course_session_idis truthy,notificationLink()returns{ name: PageNames.COURSE_SUMMARY, params: { classId: notification.collection.id, courseSessionId: notification.course_session_id } }instead of matching againstpageNameToNotificationPropsMap.User-facing consequences
Coaches can't see pre/post-test activity on the Coach Home activity feed, and classSummary silently reloads on every poll, which is a waste. Future fixes to feed visibility without updating the routing as well would cause errors.
Steps to reproduce
Claim 3 (broken routing) isn't independently reproducible today — it only manifests once someone fixes claim 2 without also fixing routing, so no repro steps for it here.
Context
Application version: kolibri/0.20.0a2 (develop branch), same codebase as PR #15260.
Related: #15189, #15228, PR #15260 (this issue is item #5 from that PR's review, deferred as out of scope — fixing it means making shared coach-notification infrastructure course-aware, not something scoped to that PR's files).
Acceptance Criteria
classSummary/actions.js'supdateWithNotifications:reloadSummaryis never settruevia the exam-map check for a notification withcourse_session_idset; other checks in that function are unaffected.coachNotifications/getters.js'sreshapeNotification: a notification withcourse_session_idset and noclassSummary.examsmatch renders with a generic label instead of returningnull.gettersUtils.js'snotificationLink(): a notification withcourse_session_idset routes toPageNames.COURSE_SUMMARYwith{ classId: notification.collection.id, courseSessionId: notification.course_session_id }.course_session_id.course_session_id-present notifications, plus regression coverage for the existing exam/lesson/resource paths.AI usage
Drafted by Claude (Claude Code) from a code-review finding surfaced by an automated PR review bot (
@rtibblesbot) on PR #15260. Claude independently verified all three claims by reading the cited source directly before drafting, including checking data availability (classSummarystate has no course/unit title data — confirmed via direct code inspection) and the exact routing target (PageNames.COURSE_SUMMARY,notification.collection.id, serializer fields) before finalizing Expected Behavior and Acceptance Criteria. I edited/confirmed each section.