Skip to main content

Badge System

Badges are permanent achievements that recognize your accomplishments in CodeJam. Each badge commemorates a specific milestone or skill mastery.

Badge Schema

Badges are stored in the user_badges table:
convex/schema.ts
user_badges: defineTable({
  userId: v.id("users"),
  badgeId: v.string(),
  unlockedAt: v.number(),
}).index("by_user", ["userId"])
Each badge is uniquely identified by a badgeId string. The unlockedAt timestamp records when you earned it.

Available Badges

CodeJam features multiple badge categories, each with unique unlock conditions.

Badge Metadata

Badge definitions are managed server-side:
convex/users.ts
const BADGES_META: Record<string, { title: string; icon: string }> = {
  'hello-world': { title: '"Hello World" Master', icon: 'BookOpen' },
  'streak-5': { title: '5 Day Streak', icon: 'Flame' },
  'bug-hunter': { title: 'Bug Hunter', icon: 'Bug' },
  'algo-architect': { title: 'Algo Architect', icon: 'Cpu' },
  'css-wizard': { title: 'CSS Wizard', icon: 'Palette' },
};

Hello World Master

Badge ID: hello-worldComplete your first challenge and join the CodeJam community.

5 Day Streak

Badge ID: streak-5Maintain activity for 5 consecutive days. Consistency is key!

Bug Hunter

Badge ID: bug-hunterExcel at finding and fixing syntax errors in code challenges.

Algo Architect

Badge ID: algo-architectMaster algorithmic challenges and optimize for performance.

CSS Wizard

Badge ID: css-wizardDemonstrate mastery of CSS layouts and styling.

Unlocking Badges

Badges are awarded automatically when you meet specific criteria.

Award Badge Mutation

The awardBadge mutation grants badges:
convex/users.ts
export const awardBadge = mutation({
  args: { badgeId: v.string() },
  handler: async (ctx, args) => {
    const userId = await getAuthUserId(ctx);
    if (!userId) return;

    const existing = await ctx.db
      .query("user_badges")
      .withIndex("by_user", q => q.eq("userId", userId))
      .filter(q => q.eq(q.field("badgeId"), args.badgeId))
      .first();
    
    if (!existing) {
      await ctx.db.insert("user_badges", {
        userId,
        badgeId: args.badgeId,
        unlockedAt: Date.now()
      });
    }
  }
});
Badges can only be unlocked once per user. The system prevents duplicate awards.

Unlock Conditions

“Hello World” MasterUnlock by: Completing your first code challenge
  • Awarded on first successful challenge completion
  • Welcomes new players to the platform
  • Gateway badge for all users
5 Day StreakUnlock by: Maintaining activity for 5 consecutive days
  • Tracked via user.streak >= 5
  • Requires daily activity (XP earning)
  • Resets if you miss a day
Bug HunterUnlock by: Excelling at syntax error challenges
  • Complete Syntax Smasher with perfect objectives
  • Fix errors quickly and accurately
  • Demonstrates debugging proficiency
Algo ArchitectUnlock by: Mastering algorithmic challenges
  • Complete Algo Arena (Expert difficulty)
  • Meet memory complexity requirements
  • Pass all unit tests
CSS WizardUnlock by: Achieving CSS Combat mastery
  • Complete CSS Combat with perfect layout matching
  • Demonstrate flexbox and grid expertise
  • Advanced CSS skills validated

Displaying Badges

Badges appear throughout the platform to showcase your achievements.

Recent Badges Query

The dashboard displays your latest badges:
convex/users.ts
export const getRecentBadges = query({
  args: {},
  handler: async (ctx) => {
    const userId = await getAuthUserId(ctx);
    if (!userId) return [];

    const userBadges = await ctx.db
      .query("user_badges")
      .withIndex("by_user", q => q.eq("userId", userId))
      .order("desc") 
      .take(3);

    return userBadges.map(b => ({
      ...b,
      meta: BADGES_META[b.badgeId] || { 
        title: 'Unknown Badge', 
        icon: 'Lock' 
      }
    }));
  }
});
This query returns the 3 most recently unlocked badges, sorted by unlockedAt timestamp.

Badge Display Components

Badges enhance multiple UI areas:

Dashboard Widget

Shows your latest 3 badges with icons and titles

Profile Page

Full badge collection with unlock timestamps

Leaderboard

Badge highlights next to player names

Activity Feed

Real-time badge unlock notifications

Badge Icons

Each badge uses a distinct icon for visual recognition:
'BookOpen'  // Hello World Master
'Flame'     // 5 Day Streak
'Bug'       // Bug Hunter
'Cpu'       // Algo Architect
'Palette'   // CSS Wizard
'Lock'      // Unknown/Locked badges

Achievement Tracking

Monitor your progress toward locked badges:

Progress Indicators

1

Check Streak Status

View your current streak in the dashboard
user.streak // Current consecutive days
2

Review Challenge Completion

Track which challenges you’ve completed
game_stats.gamesPlayed // Per-challenge attempts
game_stats.bestScore   // Your high score
3

Monitor XP Progress

Higher XP unlocks advanced challenge badges
user.xp    // Total experience
user.level // Current level

Badge Notifications

When you unlock a badge, the system may trigger notifications:
Example Flow
// 1. Complete objective (e.g., 5-day streak)
// 2. System checks criteria
// 3. awardBadge mutation called
// 4. Notification sent (if enabled)
// 5. Badge appears in dashboard
Check your Recent Badges widget after completing challenges to see if you unlocked new achievements!

Badge Rarity

Some badges are harder to earn than others:
Easy to unlock
  • Hello World Master
  • First-time completion badges
  • Low barrier to entry

Future Badges

More badges are planned for future releases:

Social Achievements

  • Friend milestones
  • Battle victories
  • Collaboration badges

Mastery Badges

  • Language-specific expertise
  • Challenge speed records
  • Perfect score runs

Campaign Progress

  • Tier completion
  • Boss defeats
  • Campaign milestones

Special Events

  • Seasonal badges
  • Limited-time challenges
  • Community events

Badge Strategy

Protect your 5-day streak
  • Set daily reminders
  • Complete at least one challenge per day
  • Check-in before UTC day rollover
Target specific badge challenges
  • Practice Syntax Smasher for Bug Hunter
  • Master CSS Combat for CSS Wizard
  • Optimize Algo Arena for Algo Architect
Prioritize badge-granting objectives
  • Perfect runs over speed
  • All objectives completed
  • High-quality submissions
Badges are permanent once unlocked, but some (like streak badges) require ongoing effort to earn!

Next Steps

Progression

Learn about XP, levels, and streaks

Challenges

Explore challenges that unlock badges

Leaderboard

See who has the most badges

User API

Badge queries and mutations reference

Build docs developers (and LLMs) love