Dynamic badges/achievements system with tiered milestones#128
Open
JanMikes wants to merge 5 commits into
Open
Conversation
Plug-in architecture: BadgeConditionInterface + tagged iterator. Five flagship tiered badges (Puzzles Solved, Pieces Solved, 500pc Speed, Streak, Team Player) plus existing Supporter as admin-granted single-tier. - BadgeEvaluator orchestrates recalculation with gap-filling (tier 3 jump also persists tiers 1+2) and a single TemplatedEmail per recalc pass. - Live trigger: RecalculateBadgesForPlayer dispatched from the three solving-time handlers to the async messenger transport. - Console command with --player and --backfill (DelayStamp staggering). - Profile: BadgesProfileSection component with tier medallions + NEW pill. - Catalog page at /en/badges with per-badge progress bars. - SCSS: Bronze/Silver/Gold/Platinum/Diamond radial-gradient medallions.
Filter out null entries from jsonb_array_elements when team puzzler records lack a player_id field.
GetAllPlayerIdsWithSolveTimes, GetPlayerStatsSnapshot, and GetBadges now have DB-backed tests that verify SQL syntax, null-safety, and return-type correctness against real fixture data.
The recalc handler was sending emails inside the doctrine_transaction boundary — a mailer failure rolled back badge rows too. Now the handler dispatches a separate SendBadgeNotificationEmail message to async, so badge writes commit independently of email delivery.
Use DISTINCT ON (type) with tier DESC to return one row per badge type — always the highest earned tier. Profile and email no longer list intermediate tiers.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
BadgeConditionInterface+ tagged iterator — adding a new badge = one enum case + one class filemyspeedpuzzling:recalculate-badges --backfillwith DelayStamp staggeringBadgesProfileSectionTwig component (membership-gated), catalog page at/en/badgeswith progress barsCloses #127
Linked feature request: https://myspeedpuzzling.com/en/feature-requests/019d1d34-8b4e-71f1-81cd-a3da75d28c38
Test plan
myspeedpuzzling:recalculate-badges --backfillin dev and verify badges are awarded + emails land in Mailpit/en/badgeslogged in — per-badge progress bars visible/en/badgeslogged out — catalog visible without progress