Skip to main content

Overview

Leaderboard routes display rankings for regular and autumn competition participants, separated by key stage.

Regular Leaderboard

/leaderboard
GET
Display leaderboards separated by key stages
Route Decorator:
@bp.route("/leaderboard")
Authentication: None required Response Data:
ks3_entries
array
Top 20 KS3 (Years 7-8) leaderboard entries, ordered by score descending
ks4_entries
array
Top 20 KS4 (Years 9-11) leaderboard entries, ordered by score descending
ks5_entries
array
Top 20 KS5 (Years 12-13) leaderboard entries, ordered by score descending
recent_activity
array
Last 15 activities including:
  • Challenge completions (with challenge title)
  • Points awarded events
  • Timestamps for each activity
stats
object
Competition statistics:
  • ks3_participants: Number of KS3 participants
  • ks4_participants: Number of KS4 participants
  • ks5_participants: Number of KS5 participants
  • total_points_awarded: Sum of all points
  • total_challenges: Total challenge count
  • total_submissions: Total submission count
Data Sources:
  • Leaderboard entries from LeaderboardEntry model
  • Recent submissions from AnswerSubmission (correct answers only)
  • Key stage filtering using lowercase comparison ('ks3', 'ks4', 'ks5')
Returns: Rendered main/leaderboard.html template

Autumn Competition Leaderboard

/autumn_leaderboard
GET
Display autumn competition leaderboards by key stage with school rankings
Route Decorator:
@bp.route("/autumn_leaderboard")
Authentication: None required Response Data:

Individual Rankings

ks3_leaders
array
Top 15 KS3 individual leaders with:
  • User details (name, year, school)
  • Current score
  • School affiliation
ks4_leaders
array
Top 15 KS4 individual leaders
ks5_leaders
array
Top 15 KS5 individual leaders

School Rankings

ks3_school_leaders
array
Top 8 KS3 schools with:
  • id: School ID
  • name: School name
  • total_score: Sum of all student scores
  • participant_count: Number of students from school
  • average_score: Average score per student
ks4_school_leaders
array
Top 8 KS4 schools (same structure)
ks5_school_leaders
array
Top 8 KS5 schools (same structure)

Activity Feed

recent_activity
array
Last 15 correct submissions with points awarded:
  • User name
  • School name
  • Challenge title
  • Points awarded
  • Submission timestamp

Competition Statistics

stats
object
Autumn competition metrics:
  • ks3_participants: KS3 participant count
  • ks4_participants: KS4 participant count
  • ks5_participants: KS5 participant count
  • total_participants: All participants
  • total_schools: Number of participating schools
  • total_submissions: All submissions
  • correct_submissions: Correct submissions only
  • total_points_awarded: Sum of all points
  • active_challenges: Number of unlocked challenges
Data Sources:
  • Individual leaders from SummerLeaderboard joined with User and School
  • School rankings aggregated using SQLAlchemy func.sum(), func.count(), func.avg()
  • Recent activity from SummerSubmission (where is_correct=True and points_awarded > 0)
  • Key stage filtering using uppercase ('KS3', 'KS4', 'KS5')
Returns: Rendered main/summer_leaderboard.html template

Leaderboard Update Logic

Regular Competition

Function: update_leaderboard(user_id, score, challenge_key_stage) Updates user’s points for specific challenge key stage:
user_id
integer
required
ID of the user to update
score
integer
required
Points to add to user’s total
challenge_key_stage
string
required
Key stage of completed challenge (KS3/KS4/KS5)
Behavior:
  1. Looks for existing LeaderboardEntry for user + key stage
  2. If exists: Adds score to existing total
  3. If new: Creates entry with initial score
  4. Updates last_updated timestamp to current time

Autumn Competition

Function: update_summer_leaderboard(user_id, school_id, points) Updates summer leaderboard and school rankings:
user_id
integer
required
ID of the user
school_id
integer
required
ID of user’s school
points
integer
required
Points to add (1 or 3)
Behavior:
  1. Finds SummerLeaderboard entry by user + school
  2. Adds points to existing score or creates new entry
  3. Updates last_updated timestamp
  4. School rankings automatically recalculated on next view

Point Distribution

Regular Challenges

  • First to complete all boxes: 3 points
  • Subsequent completions: 1 point
  • Partial completion: 0 points (no credit until all boxes correct)

Summer Challenges

  • First to complete entire challenge: 3 points
  • Everyone else who completes: 1 point
  • Partial answers: 0 points (encouragement message only)

Recent Activity Tracking

Both leaderboards show recent activity feed: Regular Leaderboard:
  • Sources from AnswerSubmission (correct answers)
  • Joins with User, ChallengeAnswerBox, Challenge
  • Sorted by submitted_at descending
  • Limit: 10 submissions
Summer Leaderboard:
  • Sources from SummerSubmission where points_awarded > 0
  • Joins with User, SummerChallenge, School
  • Sorted by submitted_at descending
  • Limit: 15 submissions with points

Key Stage Filtering Differences

Important: Key stage filtering uses different cases:
  • Regular leaderboard: Lowercase ('ks3', 'ks4', 'ks5')
  • Summer leaderboard: Uppercase ('KS3', 'KS4', 'KS5')
This is based on how the data is stored in each respective model.

Build docs developers (and LLMs) love