fix inventory
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
# 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:
|
||||
|
||||
```text
|
||||
strong_grading_enabled = false
|
||||
strong_grading_class_sections = *
|
||||
```
|
||||
|
||||
When enabled:
|
||||
|
||||
```text
|
||||
strong_grading_enabled = true
|
||||
strong_grading_class_sections = 12,15,20
|
||||
```
|
||||
|
||||
or all sections:
|
||||
|
||||
```text
|
||||
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`.
|
||||
Reference in New Issue
Block a user