Files
alrahma_sunday_school_api/docs/STRONG_GRADING_IMPLEMENTATION_NOTES.md
T
2026-06-11 03:22:12 -04:00

2.8 KiB

Strong Grading Implementation Notes

Safety rule

This patch is additive and backward-compatible. Existing historical semester scores remain displayed from stored semester_scores values and are labeled as legacy by metadata. The new strong-grading machinery is present, but strong-mode finalization only activates when strong_grading_enabled is enabled through configuration.

What changed

Legacy display protection

semester_scores now supports:

  • calculation_mode
  • calculation_policy_version
  • snapshot_id

Existing rows are backfilled as:

  • calculation_mode = legacy
  • calculation_policy_version = legacy_v1

No historical score is recalculated by this migration.

Score safety columns

The score tables now support:

  • max_points
  • status
  • excused_reason
  • locked_at
  • locked_by

Existing numeric score rows are marked scored. Existing blank rows are marked pending, not missing, so old data is not punished by the new policy.

Validation

A central ScoreValueValidator rejects impossible scores before storage. The default max remains 100 to preserve old behavior until item-level max points are configured.

Attendance grace

Attendance now names the one-absence grace policy explicitly instead of hiding it in (total_days + 1 - absences) / total_days. The result is intentionally equivalent.

Strong-mode lock validation

GradingLockService now checks the policy mode before locking. In legacy mode, behavior remains compatible. In strong mode, pending scores and invalid score ranges block locking.

Snapshot infrastructure

semester_score_snapshots and SemesterScoreSnapshotService were added. Strong-mode finalized scores can store calculation inputs and outputs for auditability.

Display resolver

GradeCalculationDisplayResolver resolves whether a row should be shown as Legacy Calculation or Strong Calculation.

Configuration gates

Strong mode is off by default.

Suggested configuration values:

strong_grading_enabled = false
strong_grading_class_sections = *

When enabled:

strong_grading_enabled = true
strong_grading_class_sections = 12,15,20

or all sections:

strong_grading_class_sections = *

What is intentionally not done yet

This patch does not globally replace the legacy PTAP formula. That would change grade math. The legacy formula remains the default until strong grading is intentionally activated for a class section.

This patch does not silently recalculate historical records. That would be reckless, so naturally we avoided it.

Verification

PHP syntax checks passed for the modified and new PHP files.

PHPUnit could not run in this sandbox because the PHP runtime is missing required extensions: dom, mbstring, xml, and xmlwriter.