Feature Requests
Planned

[G2] Achievement engine: registry, evaluation, import backfill, notifications

The machinery that unlocks achievements. Ships with a handful of definitions for testing; the real catalogue is [G3].

Depends on: [G1] XP ledger, scoring model and level curve.

Scope

  • Definitions live in code, in a shared registry — not in database rows. A self-host install must never need seeding.
  • UserAchievement { userId, key, unlockedAt } — only unlocks are stored. Progress is derived on read, so it stays recomputable, import-proof and free of migration debt.
  • Two evaluation paths:

    • event-driven, hooked on ActivityEvent (already emitted from library, games, books, music, lists, reviews);
    • a nightly job (JobRun, key gamification.evaluate) for everything time-based — streaks, seasonal windows.
  • Import backfill. Imports write straight to the database and bypass activity.emit(), so a full recompute pass is required after an import, plus a one-off backfill when the feature ships.
  • Unlock notification via Notification with dedupeKey = achievement:<key>, which makes it idempotent for free.
  • Achievement shape, one model covering three formats: an optional tier (tiers of a family are distinct entries sharing a root) and an optional progress target give unique achievements (no tier, no target), Steam-style tiers (bronze/silver/gold with "42/100"), and secret achievements (a secret flag: the slot shows, the content doesn't).
  • XP award on unlock, through the G1 ledger.

Rules that constrain the engine

  • No "one object = one achievement". Completion achievements only ever count diversified aggregates (50 series watched, 5 series of 5+ seasons finished), never a single completion. A given object feeds at most one achievement of its family.
  • Thresholds are calibrated per domain and per consumption type — 100 episodes, 100 movies and 100 finished series are not the same effort.
  • Imports grant achievements, but not all of them — which ones are excluded is decided in G3.

Out of scope

The catalogue itself and its wording/icons (G3), all UI (G4/G5), the leaderboard (G7).

0 Comments

Sign in to comment

No comments yet. Be the first to share your thoughts!