Skip to content

feat(gradebook): add weighted view settings foundation (pr1 of 3)#8411

Open
LWS49 wants to merge 2 commits into
lws49/feat-gradebook-exportfrom
lws49/feat-gradebook-weights-pr1-foundation
Open

feat(gradebook): add weighted view settings foundation (pr1 of 3)#8411
LWS49 wants to merge 2 commits into
lws49/feat-gradebook-exportfrom
lws49/feat-gradebook-weights-pr1-foundation

Conversation

@LWS49
Copy link
Copy Markdown
Collaborator

@LWS49 LWS49 commented May 28, 2026

Summary

Lays the storage and admin-settings foundation for per-tab grade weighting in the gradebook. Adds a gradebook_weight integer column (0-100, default 0) to course_assessment_tabs with model-level validation (integer, 0-100, presence), a new Course::Settings::GradebookComponent with a weighted_view_enabled boolean (default false), two new CanCanCan abilities (manage_gradebook_weights, manage_gradebook_settings) scoped to manager/owner, and a Course Admin → Gradebook settings page where owners can enable or disable the weighted view. No observable change to the gradebook for existing courses — the setting defaults to false, and the weighted view surface (view toggle, Configure Weights button, weighted columns) lands in a later PR.

Design decisions

  • weighted_view_enabled defaults to false - zero UX impact on existing courses; staff who don't use weighting never encounter the feature. Matches Coursemology's existing per-component opt-in pattern.
  • Authorization uses :manage_gradebook_settings, not the generic :manage on the course - tab weighting is a course grading policy, so the settings page is intentionally narrower than full course management; TAs are excluded even though they read the gradebook.

Design Considerations

Course-level setting gates the entire feature

Decision: New weighted_view_enabled boolean course setting (default false). When disabled, no view toggle, no Configure Weights button, no weighted columns. The entire feature surface is hidden.

Why considered: Could have made the By-weight view always visible (toggle present, weighted columns blank when no weights configured). Setting toggle adds an extra step to enable.

For:

  • Zero UX change for existing courses and for staff who don't use weighting
  • Discoverable per-course opt-in matches Coursemology's existing component-setting pattern
  • Surfaces a deliberate decision: "is this course graded by weighted tabs?"

Against:

  • One more step to discover and turn on (course owner must enable in admin settings before any staff sees the feature)
  • Adds a new admin settings page (small but non-zero work)

Alternatives:

  • Always-on (view toggle visible in every course). Rejected — introduces UI elements every staff member must learn to ignore, even in courses that don't weight grades.
  • Per-staff preference. Rejected — weighting is a course-grading policy, not an individual viewer preference.

Rationale: I chose gating because the feature is meaningful only when a course has actually decided to grade by tab weights. Gating prevents UI clutter for the majority of courses that don't.

Phase 1 staff-only scope

Decision: Implement weighted view for staff gradebook only. Student-facing weighted view becomes a separate later spec.

Why considered: Both views share the same underlying weights and compute logic; combining them in one PR is technically feasible.

For:

  • Data shape diverges (staff = all students × all assessments; student = one student × all assessments)
  • Permissions diverge (staff already gated; student-self needs a new ability and likely a new controller)
  • Information architecture diverges (staff wants cross-student comparison; student wants own breakdown and projections)
  • Different empty states and copy

Against:

  • Ships value to staff before students see anything; perceived as one-sided
  • Two PRs for the same feature concept

Alternatives:

  • Combined PR shipping staff and student together. Rejected — bigger surface, more places to get stuck, no shared rationale for delaying the staff-side ship.
  • Student-first PR. Rejected — staff need to configure weights before students can see them; staff-side is the prerequisite.

Rationale: I chose staff-first because tab weights are configured by staff; staff are the primary persona for Phase 1. Once weights are live and stable, exposing them to students is additive rather than dependent.

Regression prevention

Covers: migration (gradebook_weight integer, not-null, default 0, reversible), tab validation (0-100 range, integer, presence, default value), settings model (default false, persistence, string "1"/"0" coercion), abilities (manager/owner granted both new abilities; TA and student denied), admin controller (edit returns weightedViewEnabled: false for manager; TA denied on both edit and update; PATCH persists setting and returns updated value; existing tab gradebook_weight values survive toggling the setting in both directions).

Manual: enabled setting as course owner and confirmed persistence across page refresh; disabled and re-enabled confirming tab weights survived the round-trip; confirmed TA is denied on the settings page; confirmed a tab's gradebook_weight was unchanged after toggling weighted_view_enabled off and back on.

Backward compatibility: weighted_view_enabled defaults to false — no change to the gradebook page or any other UI for existing courses.

image

@LWS49 LWS49 changed the base branch from master to lws49/feat-gradebook-export May 28, 2026 09:27
@LWS49 LWS49 changed the title Lws49/feat gradebook weights pr1 foundation feat(gradebook): add weighted view settings foundation May 28, 2026
@LWS49 LWS49 force-pushed the lws49/feat-gradebook-weights-pr1-foundation branch 2 times, most recently from 8718f51 to f91df1d Compare May 28, 2026 11:14
@LWS49 LWS49 force-pushed the lws49/feat-gradebook-export branch 2 times, most recently from 865ba2b to 6bd0a13 Compare May 29, 2026 06:14
@LWS49 LWS49 changed the title feat(gradebook): add weighted view settings foundation feat(gradebook): add weighted view settings foundation (pr1 of 3) May 29, 2026
Introduces a course-wide gradebook showing per-student grades across all assessments. Instructors can toggle which assessment columns are visible via a hierarchical column picker (grouped by category/tab), then export the current view to CSV.

Backend adds GradebookController#index (JSON), ability guard, and model methods on Assessment and Submission for fetching grade data.

Table lib gains reusable ColumnPickerTemplate, MuiColumnPickerPrompt, ColumnPickerTreeGroup, and toolbar integration used by the gradebook.
@LWS49 LWS49 force-pushed the lws49/feat-gradebook-export branch from 6bd0a13 to cd70de2 Compare May 29, 2026 06:51
@LWS49 LWS49 force-pushed the lws49/feat-gradebook-weights-pr1-foundation branch 2 times, most recently from f8d517b to 298ef61 Compare May 29, 2026 08:55
- Add gradebook_weight (0-100 integer) column to course_assessment_tabs
- Add manage_gradebook_weights/settings abilities (manager/owner only)
- Add Course Admin -> Gradebook settings page to toggle the setting
@LWS49 LWS49 force-pushed the lws49/feat-gradebook-weights-pr1-foundation branch from 298ef61 to f572984 Compare May 29, 2026 09:02
@LWS49 LWS49 marked this pull request as ready for review May 29, 2026 09:03
@LWS49 LWS49 force-pushed the lws49/feat-gradebook-export branch from cd70de2 to 64927b1 Compare May 29, 2026 09:08
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