Skip to content

Fix grade average: allow large grade matrices and decouple bonus from the final grade#12

Merged
veniplex merged 1 commit into
mainfrom
claude/materials-file-upload-features-dpmieb
Jul 13, 2026
Merged

Fix grade average: allow large grade matrices and decouple bonus from the final grade#12
veniplex merged 1 commit into
mainfrom
claude/materials-file-upload-features-dpmieb

Conversation

@veniplex

Copy link
Copy Markdown
Owner

Fixes a dashboard grade-average discrepancy. Two root causes:

1. Grade matrix (Notenmatrix) could not be saved

The percent→grade scale is stored in a jsonb column with no size limit, but the server action validated it with gradeScaleSchema.max(30). A user with a 32-row matrix got a validation error on save. Because the matrix never saved, the app fell back to the 10-row default scale, so module grades were derived from the wrong scale — which is what threw off the ECTS-weighted dashboard average.

  • Raise the row limit from 30 → 200 (src/app/[locale]/(app)/studies/actions.ts). A percent→grade table can legitimately be fine-grained (up to ~one row per percentage point). Grade-value range stays 1–6 (German scale). No schema/migration change — the column is already jsonb.

2. Bonus must not change the final grade

A per-module assignment bonus (percent_points / grade_steps) was raising the grade derived from the achieved percentage. The final grade a user enters via percentage + matrix should be final and not shifted by a bonus.

  • moduleFinalGrade now derives the grade purely from achieved percentage → grade scale (src/lib/grades.ts). The bonus is still computed and returned for informational display, but no longer alters the grade or the reported percentage.
  • Removed the misleading inline "· bonus applied" label next to the percentage in the assessment card. The bonus progress panel (assignment completion) stays as information.

Verification

  • vitest grade tests updated to assert the bonus no longer changes the grade, plus a new test proving the same module yields the same grade with or without a configured bonus. Full suite green (77 passing), tsc --noEmit and eslint clean.
  • End-to-end against a local Postgres: the old .max(30) rejects a 32-row scale, the new .max(200) accepts it, and a 32-row scale round-trips through the grade_scale jsonb column.

🤖 Generated with Claude Code

https://claude.ai/code/session_01LWLUNyHYuCpouMEUo3P456


Generated by Claude Code

…al grade

- Raise the grade-scale row limit from 30 to 200 so fine-grained
  percent→grade matrices (e.g. 32 rows) can be saved. The jsonb column has
  no limit; the cap was purely an over-strict validation that rejected the
  save with an error.
- Compute a module's final grade purely from the achieved percentage via the
  grade scale. A configured assignment bonus is still computed and shown for
  information, but no longer shifts the final grade (neither percent points
  nor grade steps). This keeps the grade the user derives from percentage +
  matrix stable, and makes the ECTS-weighted dashboard average match a manual
  calculation.
- Drop the now-misleading inline "bonus applied" label next to the percentage.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LWLUNyHYuCpouMEUo3P456
@veniplex veniplex added the release-candidate Creates a new release and deployment of docker image, once merged. label Jul 13, 2026
@veniplex
veniplex merged commit f8029e9 into main Jul 13, 2026
1 of 2 checks passed
@veniplex
veniplex deleted the claude/materials-file-upload-features-dpmieb branch July 13, 2026 19:52
github-actions Bot added a commit that referenced this pull request Jul 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

release-candidate Creates a new release and deployment of docker image, once merged.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants