Skip to content

Implement Leaderboard API Layer and Core Data Types with React Query #57

@0xdevcollins

Description

@0xdevcollins

Build the foundational infrastructure for the leaderboard feature including TypeScript types, API service layer, React Query hooks, and backend API endpoints. This establishes the data contracts and fetching mechanisms that the UI components will consume.

Problem Statement
The platform lacks any infrastructure to track, rank, and serve contributor performance data. This issue establishes the core data layer that powers the leaderboard feature.

Acceptance Criteria

TypeScript Types

  • Create LeaderboardEntry type with rank, contributor, and rank change data
  • Create LeaderboardContributor type with profile and stats
  • Create ContributorStats type with completion metrics
  • Define ReputationTier and LeaderboardTimeframe enums
  • Create LeaderboardFilters and LeaderboardPagination types
  • Create LeaderboardResponse type for API responses

API Service Layer

  • Implement fetchLeaderboard() with filter and pagination support
  • Implement fetchUserRank() for individual user lookup
  • Implement fetchTopContributors() for widget use
  • Add proper error handling and response typing
  • Support URL parameter serialization for filters

React Query Hooks

  • Create useLeaderboard() infinite query hook with pagination
  • Create useUserRank() hook for current user's position
  • Create useTopContributors() hook for mini widget
  • Create usePrefetchLeaderboardPage() for performance optimization
  • Configure appropriate stale times and refetch intervals
  • Implement keepPreviousData for smooth filter transitions

Backend API Endpoints

  • Create GET /api/leaderboard with query parameters
  • Create GET /api/leaderboard/user/[userId] for user rank
  • Create GET /api/leaderboard/top for top N contributors
  • Add input validation and error responses
  • Return mock data structure (actual DB integration separate)

Technical Requirements

TypeScript Types

export type ReputationTier = 
  | 'NEWCOMER'
  | 'CONTRIBUTOR'
  | 'ESTABLISHED'
  | 'EXPERT'
  | 'LEGEND';

export type LeaderboardTimeframe = 
  | 'ALL_TIME'
  | 'THIS_MONTH'
  | 'THIS_WEEK';

export interface ContributorStats {
  totalCompleted: number;
  totalEarnings: number;
  earningsCurrency: string;
  completionRate: number;
  averageCompletionTime: number;
  currentStreak: number;
  longestStreak: number;
}

export interface LeaderboardContributor {
  id: string;
  userId: string;
  walletAddress: string | null;
  displayName: string;
  avatarUrl: string | null;
  totalScore: number;
  tier: ReputationTier;
  stats: ContributorStats;
  topTags: string[];
  lastActiveAt: string;
}

export interface LeaderboardEntry {
  rank: number;
  previousRank: number | null;
  rankChange: number | null;
  contributor: LeaderboardContributor;
}

export interface LeaderboardResponse {
  entries: LeaderboardEntry[];
  totalCount: number;
  currentUserRank: number | null;
  lastUpdatedAt: string;
}

export interface LeaderboardFilters {
  timeframe: LeaderboardTimeframe;
  tier?: ReputationTier;
  tags?: string[];
}

export interface LeaderboardPagination {
  page: number;
  limit: number;
}

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions