Achievements
Achievements reward activity across every Esposter product — posts, likes, messages, rooms, emails, surveys, sheets, flowcharts, webpages, and the games — from one system: definitions are data, unlocking is a single tRPC plugin, and unlocks toast in real time. The gallery at /achievements shows every achievement by category with progress.
Key concepts
- Definitions are constant maps — one
<Category>AchievementDefinitionMapper product undershared/services/achievement/definitions/, merged intoAchievementDefinitionMap. A definition is{ triggerPath, amount, incrementAmount, condition?, isHidden?, category, icon, points, description }, wheretriggerPathis a typed tRPC path (TRPCPaths), so a renamed procedure breaks the definition at compile time. - Progress is a counter —
userAchievements(userId, achievementId, amount, unlockedAt); each matching trigger addsincrementAmountuntilamountis reached, which stampsunlockedAt. One-shot achievements are justamount: 1. - Conditions — an optional predicate tree evaluated against the mutation's raw input:
Property(dot-path + binary operators / regex / palindrome / customOperationcallback),Timewindows, composed withAnd/Or. This is what powers input-dependent achievements ("50 comments under 50 characters") and the games' save-payload milestones (clicker, dungeons). - Hidden achievements —
isHiddendefinitions read as???until the viewer unlocks them.
See unlock pipeline for how a mutation becomes a toast, and points leaderboard for the global ranking by total unlocked points.