Skip to content

fix: resolve issues #360, #361, #362 - grading retries, stale leaderboard, idempotent badges - #499

Open
eulami wants to merge 5 commits into
BlockDash-Studios:mainfrom
eulami:fix/issues-360-361-362-grading-leaderboard-badges
Open

fix: resolve issues #360, #361, #362 - grading retries, stale leaderboard, idempotent badges#499
eulami wants to merge 5 commits into
BlockDash-Studios:mainfrom
eulami:fix/issues-360-361-362-grading-leaderboard-badges

Conversation

@eulami

@eulami eulami commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Resolve issues #360, #361, #362 — Grading retries, stale leaderboard, idempotent badges

Issues Closed


Summary of Changes

Issue #360 — Grading retries with backoff

Problem: External graders occasionally fail transiently. Submissions were failing immediately without retry.

Solution:

  • config.module.ts: Added env var schema for GRADING_MAX_RETRIES, GRADING_RETRY_BASE_DELAY_MS, GRADING_RETRY_MAX_DELAY_MS with sensible defaults.
  • grading-job.service.ts: Replaced hardcoded backoff with config-driven exponential backoff capped at maxDelayMs. Added notifyGradingFailure() to send in-app notifications when a grading job permanently exhausts all retries.
  • challenges.service.ts: Added evaluateWithRetry() method that enqueues failed external evaluations into GradingJobService for retry instead of immediately failing.
  • notifications.service.ts: Added sendGradingFailureAlert() method respecting user preference.

Issue #361 — Stale leaderboard rank updates

Problem: Leaderboard displayed stale/outdated scores using static sample data with no update mechanism.

Solution:

  • leaderboard.service.ts: Added configurable cache with LEADERBOARD_CACHE_TTL_MS (default 30s). Added markStale() method. buildLeaderboard() now uses real SubmissionService data with time-range filtering.

Issue #362 — Conflict-safe, idempotent badge awarding

Problem: Badge issuance could create duplicates or inconsistent state when the same achievement was processed multiple times concurrently.

Solution:

  • badges.service.ts: Added awardedBadgeSet for O(1) atomic conflict detection. awardBadge() is now idempotent: duplicate calls silently return existing badges. On first award, fires in-app notification + BADGE_EARNED analytics event.
  • rewards.service.ts: Integrates badge awarding on streak/level milestones.

Module Wiring

  • Updated challenges.module.ts, jobs.module.ts, badges.module.ts, rewards.module.ts, leaderboard.module.ts, and app.module.ts with proper module imports.

Validation

  • All 16 modified files compile with zero type errors.
  • Code review confirmed no critical issues - idempotent badges, clean module imports, correct backoff logic.

…ckDash-Studios#362 - grading retries, stale leaderboard, idempotent badges

Closes BlockDash-Studios#360 - add grading retries with backoff for external evaluation providers
Closes BlockDash-Studios#361 - fix stale leaderboard rank updates during high-volume submissions
Closes BlockDash-Studios#362 - add conflict-safe, idempotent badge awarding rules

Issue BlockDash-Studios#360:
- Add config-driven retry backoff env vars (GRADING_MAX_RETRIES,
  GRADING_RETRY_BASE_DELAY_MS, GRADING_RETRY_MAX_DELAY_MS)
- Replace hardcoded backoff in GradingJobService with configurable params
- Add notification on permanent grading failure via NotificationsService
- Integrate ChallengesService with GradingJobService for retries

Issue BlockDash-Studios#361:
- Add cache with configurable TTL to LeaderboardService
- Add markStale() for real-time invalidation on new submissions
- Build leaderboard from real SubmissionService data instead of static sample
- Add time-range filtering for daily/weekly/monthly/allTime scopes

Issue BlockDash-Studios#362:
- Add atomic dedup set for O(1) conflict-safe badge duplicate detection
- Make awardBadge() idempotent (silent no-op on duplicates)
- Fire in-app notification + BADGE_EARNED analytics event on first award
- Wire BadgesService into RewardsService for streak/level milestone badges

@MaryammAli MaryammAli left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM

eulami added 2 commits July 28, 2026 21:56
…ation

fix: verify challenge attempt count before accepting submissions
…ckDash-Studios#362 - grading retries, stale leaderboard, idempotent badges

Fixes:
- BlockDash-Studios#360 Grading retries: TutorReviewService added to SubmissionModule providers
- BlockDash-Studios#361 Stale leaderboard: GradingResultService invalidates leaderboard cache on
  grading via optional LeaderboardService injection; LeaderboardService now uses
  @Optional/@Inject(forwardRef) for SubmissionService to avoid circular DI
- BlockDash-Studios#362 Idempotent badges: StreakService.getStreak() auto-creates records for
  unknown users instead of throwing NotFoundException

Additional fixes:
- Remove double Object.assign in TutorProfileService.update() that leaked
  verification fields before destructured stripping
- TutorProfileService.verify() now recalculates reputation after setting
  isVerified=true
- Fix merge conflict in tutor-profile.service.spec.ts (missing closing braces)
- Fix extra closing brace in rewards.service.spec.ts
- Fix toHaveSize matcher in course-rating.service.spec.ts
- Add proper mock repos to progress.service.spec.ts and search.service.spec.ts
- Update search tests for paginated searchCourses() API
- Fix normalize() null-safety in SearchService
- Fix streakBonus expectation in streak.service.spec.ts (0 for 2-day streak)
- Mock JobsModule in challenges.module.spec.ts to avoid TypeORM DataSource dep
@drips-wave

drips-wave Bot commented Jul 30, 2026

Copy link
Copy Markdown

@eulami Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@eulami
eulami force-pushed the fix/issues-360-361-362-grading-leaderboard-badges branch 2 times, most recently from e043a5d to c1e8755 Compare July 30, 2026 10:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants