Skip to content

Feat | Score rules#35

Open
TheGeniusOfEternity wants to merge 31 commits intoryukzak:masterfrom
TheGeniusOfEternity:feat/tasks-deadlines-and-penalties
Open

Feat | Score rules#35
TheGeniusOfEternity wants to merge 31 commits intoryukzak:masterfrom
TheGeniusOfEternity:feat/tasks-deadlines-and-penalties

Conversation

@TheGeniusOfEternity
Copy link
Copy Markdown

@TheGeniusOfEternity TheGeniusOfEternity commented Apr 15, 2026

By this pull request new extra points system is introduced - Score Rules. There is new mechanics, score rules, which allows admin to assign bonuses & penalties for specific tasks on specific conditions with specific amount of points.

Resolves #34 , where detailed info might be found

@TheGeniusOfEternity
Copy link
Copy Markdown
Author

TheGeniusOfEternity commented Apr 21, 2026

Updated User Profile page, added score rules section:

Снимок экрана — 2026-04-21 в 16 51 14

How it works:

  1. Rule - name of the rule
  2. Tasks - names of tasks, related to this rule
  3. Condition - how to get/avoid effect of the score rule. There some types:
    • after: ANY TASK of related must be submitted after the specified date to make effect be applied (i.e. if you submit lab1 after the 29.3.2026, you get penalty effect by -2 points)
    • before: ANY TASK of related must be submitted before the specified date to make effect be applied (i.e. if you submit lab4 before the date, you get bonus effect by +1 point)
    • after + before: ANY TASK of related must be submitted before specified date1 and after specified date2 to make effect be applied (i.e. if you submit lab1 after the 15.3.2026 and before the 29.3.2026, you get penalty effect by -1 point)
    • less than <value> + before: works like before, but with extra condition of__amount__ of submitted tasks (i.e. if you submit only lab3.acc32 and lab3.f32 (less than 4) by the end of the semester, you get penalty effect by -2 points)
  4. Status:
    • applied - displayed if rules's condition can't be changed and equals true. Green for before rules and red for after rules
    • not applied - displayed if rules's condition can't be changed and equals false. Gray for all conditions types
    • active - displayed if rule's condition can be changed.
  5. Bonus/Penalty (Effect) - amount of points that would be added if the rule is applied. Color duplicates status

Also above the table there is total effect - sum of applied points from score rules

@TheGeniusOfEternity
Copy link
Copy Markdown
Author

Updated Users page - added Bonus/Penalty column
Снимок экрана — 2026-04-21 в 17 52 49

How it works:
For every student total effect from all applied score rules is collected and added to the table. The column is also included into CSV file on export

@TheGeniusOfEternity TheGeniusOfEternity changed the title Feat | Tasks deadlines and penalties Feat | Score rules Apr 21, 2026
@TheGeniusOfEternity TheGeniusOfEternity marked this pull request as ready for review April 21, 2026 15:01
Copy link
Copy Markdown
Owner

@ryukzak ryukzak left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And also we need a tests.

Comment thread src/config/config.go Outdated
Comment thread docker-compose.yaml Outdated
Comment thread src/handlers/user.go
Comment thread src/storage/db.go Outdated
Copy link
Copy Markdown
Owner

@ryukzak ryukzak left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR Review: Score Rules

Critical Issues

1. Duplicate logic: CalculateScoreEffects and CalculateTotalEffect are identical

config.go has two methods that do the exact same thing. Only CalculateTotalEffect is used. CalculateScoreEffects should be removed.

2. Duplicate rule evaluation logic between config.go and scorerule.go

Config.RuleApplies() in config.go duplicates the logic in Evaluator.EvaluateForStudent() in scorerule.go. The config method is only called via CalculateTotalEffect (used in users.go for the user list/CSV). This means the same rule can produce different results from two different code paths — a divergence bug waiting to happen.

Recommendation: Remove RuleApplies and CalculateScoreEffects/CalculateTotalEffect from config.go. Use the Evaluator everywhere.

3. N+1 query problem in user list

In UserListHandler, for each student, getCheckedTime is called per rule per task, and each call does DB.ListTaskRecords. For a class of 30 students with 6 rules × 4 tasks, that's potentially 720 DB reads on every page load. Consider batching — load all records for a student once, then filter in memory.

Same pattern repeats in UserInfoHandler and UserListCSVHandler.

4. time.Now() called in business logic makes testing impossible

RuleApplies and EvaluateForStudent both call time.Now() internally. This makes the rule evaluation non-deterministic and untestable. Pass now as a parameter instead.


Medium Issues

5. Error silently swallowed in evaluator

In scorerule.go:39-41, when getCheckedTime returns an error, the task is silently skipped. In config.go, same pattern but with a comment "Error equals task was not checked" — which is misleading since actual DB errors are also swallowed.

6. Unused fields added in the diff

  • TaskViewModel.CompletedCount is added to task.go but completedCount is always 0 — never assigned.
  • TaskViewModel.CurrentTime is added but never used in task.html.
  • User.RuleApplies is set but only accessed in the template via $.RuleApplies — yet the template already has .Status on ScoreRuleWithStatus, making RuleApplies redundant.

7. hasTask check is redundant

In user.go, the loop checks if a score rule's task IDs exist in AppConfig.Tasks. But LoadConfig already validates this — it returns an error if a rule references a non-existent task. This check is dead code.

8. GetCompletedTasksCountInGroup in db.go is unused

The new method added to storage/db.go is never called anywhere.


Minor / Style

9. Template formatting changes are noisy — The PR mixes feature work with whitespace reformatting ({{ define vs {{define, etc.) across multiple templates. These should be in a separate commit.

10. Template indentation is broken in user.html — The score rules table progressively loses indentation towards the bottom. Closing </table>, </div>, </section> are not at the correct indent level.

11. docker-compose.yaml hardcodes JWT secretSLAP_JWT_SECRET=test in the main compose file; consider docker-compose.override.yaml or .env instead.

12. Double --- separator in GUIDE.md — produces a redundant horizontal rule.


No Tests

The PR adds significant business logic (rule evaluation with multiple condition branches) but includes zero tests — no unit tests for RuleApplies/EvaluateForStudent, no hurl integration tests.


Summary

Category Count
Critical 4
Medium 4
Minor 4

Key asks before merge:

  1. Remove duplicate logic — single code path for rule evaluation
  2. Add unit tests for rule evaluation (especially edge cases around time.Now())
  3. Add hurl tests for the score rules UI
  4. Fix the N+1 query pattern or add a TODO acknowledging it
  5. Remove dead code (CalculateScoreEffects, CompletedCount, GetCompletedTasksCountInGroup)

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.

configure tasks's deadlines, bonuses & penalties via score rules

2 participants