Skip to content

feat: Collector Achievements — badge system for collection milestones and patterns #200

@SimplicityGuy

Description

@SimplicityGuy

Overview

A badge and achievement system that rewards collectors for meaningful patterns in their Discogs collection. Achievements are computed from graph relationships and collection data — not arbitrary gamification, but recognition of genuine collecting depth and breadth.

Achievements give users a reason to explore their collection from new angles ("I'm 2 releases away from completing this label's catalog") and surface interesting facts they might not have noticed ("You own releases spanning 6 decades").

Achievement Categories

Completionist

Badge Criteria Tiers
Label Loyalist Own X% of a label's catalog Bronze (25%), Silver (50%), Gold (75%), Platinum (90%)
Discography Deep Dive Own X% of an artist's discography Bronze (25%), Silver (50%), Gold (75%), Platinum (90%)
Master Collector Own multiple pressings of the same master release 3, 5, 10, 25 pressings

Breadth

Badge Criteria Tiers
Genre Tourist Collect across X distinct genres 5, 10, 20, 30 genres
Style Explorer Collect across X distinct styles 10, 25, 50, 100 styles
Label Hopper Collect from X distinct labels 10, 50, 100, 500 labels
World Collector Collect releases from X distinct countries 5, 15, 30, 50 countries

Temporal

Badge Criteria Tiers
Time Traveler Own releases from X distinct decades 3, 4, 5, 6+ decades
Era Specialist Own X+ releases from a single decade 25, 50, 100, 250 releases
Vinyl Archaeologist Own releases older than X years 25yr, 40yr, 50yr, 60yr

Graph-Powered

Badge Criteria Tiers
Six Degrees Collection spans a path of X hops in the artist collaboration graph 3, 5, 7, 10 hops
Scene Builder Own releases from X+ artists in a connected collaboration cluster 5, 10, 20 artists
Taste Architect Taste fingerprint covers X+ genre/style dimensions 5, 10, 15, 20 dimensions

Special

Badge Criteria
First Pressing Own a first pressing of any release
Mono Enthusiast Own 10+ mono pressings
Format Completionist Own releases in 5+ distinct formats (LP, CD, cassette, 7", 12", etc.)
Deep Cut Own a release with fewer than 100 Discogs owners

Proposed Endpoints

API Endpoints (api/routers/achievements.py)

Endpoint Description
GET /api/user/achievements All earned achievements for the authenticated user
GET /api/user/achievements/progress Progress toward unearned achievements (nearest milestones)
GET /api/user/achievements/summary Achievement stats: total earned, rarest, most recent
GET /api/user/achievements/{achievement_id} Detail for a specific achievement including unlock date and evidence

Response Shape (example: achievements list)

{
  "achievements": [
    {
      "id": "label-loyalist-gold",
      "category": "completionist",
      "name": "Label Loyalist",
      "tier": "gold",
      "description": "Own 75%+ of a label's catalog",
      "unlocked_at": "2026-03-15T10:30:00Z",
      "evidence": {
        "label": "Warp Records",
        "label_id": 123,
        "owned": 187,
        "total": 243,
        "percentage": 76.9
      }
    }
  ],
  "stats": {
    "total_earned": 14,
    "by_category": {"completionist": 3, "breadth": 5, "temporal": 4, "graph": 1, "special": 1},
    "rarest": "label-loyalist-gold"
  }
}

Response Shape (example: progress)

{
  "in_progress": [
    {
      "id": "label-loyalist-platinum",
      "name": "Label Loyalist",
      "next_tier": "platinum",
      "current": 76.9,
      "target": 90.0,
      "remaining": "Add 32 more Warp Records releases",
      "evidence": {
        "label": "Warp Records",
        "label_id": 123,
        "owned": 187,
        "total": 243
      }
    }
  ]
}

Explore UI — Achievements Section

Add an Achievements section to the Collection pane (authenticated users only).

Layout

  1. Achievement Showcase — top row of 3-4 most impressive/recent badges as large cards with icons
  2. Progress Bar Strip — horizontal bar showing nearest achievements to completion, sorted by proximity. Clicking expands to show what's needed
  3. Full Achievement Grid — grouped by category, showing earned (full color) and locked (greyed with progress %). Filter by category
  4. Achievement Detail Modal — click any badge to see: description, unlock date, evidence (which label, which artists, etc.), and shareable card

UI Details

  • Badge icons should be distinctive per category (use simple SVG/emoji)
  • Tier progression shown as connected dots (bronze → silver → gold → platinum)
  • Locked achievements show progress percentage and "X more to go" hint
  • New achievement toast notification on collection sync when new badges are earned

Computation Strategy

  • Achievements are recomputed on collection sync (not real-time) to avoid performance impact
  • Store earned achievements + progress snapshots in PostgreSQL user_achievements table
  • Graph-powered achievements (Six Degrees, Scene Builder) use existing Neo4j queries
  • Completionist achievements leverage existing gap analysis queries
  • Breadth/temporal achievements are simple aggregations from collection data

Integration Points

Implementation Notes

  • New PostgreSQL table: user_achievements (user_id, achievement_id, tier, unlocked_at, evidence JSONB)
  • Achievement definitions stored as a Python registry (not DB) — versioned with code
  • Computation is async — triggered by sync, runs in background, results cached
  • Progress computation can be expensive for graph-powered badges — compute these less frequently or cap at 1/day
  • Consider a AchievementEngine class with pluggable evaluators per category

Acceptance Criteria

  • Achievement registry defines all badges with tiers and criteria
  • Achievements recomputed on collection sync
  • All 5 achievement categories produce correct results
  • Progress endpoint shows nearest unearned achievements
  • Evidence field provides specific details (which label, which artists, etc.)
  • Explore UI displays earned and in-progress achievements
  • New achievement detection produces toast notification
  • Achievement detail modal shows evidence and shareable card
  • Graph-powered achievements use existing Neo4j queries efficiently
  • ≥80% test coverage

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions