What Changed Modal

After a refresh completes, IC Insight shows the What Changed modal - a summary of exactly how your grades moved and which assignments drove the change.


Overview

The modal appears automatically when you close the progress dialog after a Network Refresh or Classic Refresh. It groups every refreshed course into three sections:

Section Criteria
Improved Overall grade increased by ≥ 0.005%
Declined Overall grade decreased by ≥ 0.005%
Unchanged Overall grade changed by < 0.005% (or no change at all)

Why 0.005%? It is used as an epsilon to prevent floating point errors during calculation.

Courses that failed to refresh appear in a separate Failed section with the error message.


Course Cards

Each improved or declined course shows:

  • Course name with a colored arrow (↑ green / ↓ red)
  • Old overall → new overall (e.g. 97.55% → 97.45%)
  • Net change (e.g. −0.10%)
  • A per-category breakdown (see below)

Unchanged courses display only the course name and current grade.


Per-Category Breakdown

For each course whose overall changed, every category that either moved in grade or gained a new/newly-graded assignment is listed. Each category row shows:

• Category Name    97.1% → 97.8%    +0.7%
  ▶ 1 new assignment
      Assignment Name                 30/30
  • Old avg → new avg are the dashboard-calculated rolling/cumulative averages - the same values shown on the course card.
  • Delta is colour-coded: green for positive, red for negative, grey for zero or new categories.
  • For new categories (categories that didn't exist before the refresh, e.g. when a new quarter begins), the delta column shows (new) instead of a percentage.

Expandable Assignment List

Clicking the ▶ N new assignment(s) toggle expands a list of assignments that are either brand-new or were previously ungraded and now have a score. Each row shows the assignment name and its score (earned/possible), or not yet graded if still ungraded.


How Grade Changes Are Detected

Overall change

Pre-refresh and post-refresh overall grades are both computed using the same dashboard logic (ICI_COMPUTE_COURSE_GRADE / recomputeOverall) - rolling or traditional depending on your settings. This ensures the numbers in the modal match what you see on the course cards.

New / newly-graded assignments

A lookup of every assignment from every quarter of the old snapshot is built before the refresh starts. After the refresh, each assignment in the most recent active quarter is compared against this lookup:

Condition Shown as
Assignment name not found in old snapshot New assignment
Assignment existed but had no score (earned = null) Newly graded assignment
Assignment was already graded before refresh Not shown

Assignment names are normalised for comparison (lowercased, punctuation stripped, extra whitespace collapsed), so minor formatting differences between the API and the DOM scraper (e.g. "Mental Health- Engagement" vs "Mental Health Engagement") are handled correctly.

New categories

If a category exists in the new snapshot but not in the old one (e.g. a course transitioned from one quarter to the next), it appears with - → X% (new) and all its assignments listed as new.


Quarter Transitions

The modal works correctly across any quarter transition - Q1→Q2, Q2→Q3, Q3→Q4, or any other combination. When the active quarter changes after a refresh:

  • Assignments that appeared in prior quarters are still in the old-snapshot lookup, so they are correctly identified as not new.
  • Categories that are brand-new in the current quarter appear with the (new) label.
  • Carry-over categories (same name, continuing from a prior quarter) show a grade delta as usual.

Data Flow

startRefresh()
  ├─ Capture preRefreshData from ICI_CURRENT_GRADES (before any API calls)
  │   └─ { overall, categories, rawQuarters } per course
  │
  ├─ Refresh each course (network or scrape)
  │
  ├─ After each course: call ICI_COMPUTE_COURSE_GRADE for post-refresh grades
  │   └─ { overall, categories }  -  same logic as dashboard rendering
  │
  └─ computeSnapshotDiff(preData, postData)
      └─ { oldOverall, newOverall, overallDelta, catChanges[] }

showChangeSummary(results)
  └─ Renders the What Changed modal from the collected diffs