Page MenuHomePhabricator

GSoC'24 Proposal: Add For User Badges
Open, Needs TriagePublic

Assigned To
Authored By
Afi570
Tue, Apr 2, 9:35 AM
Referenced Files
F44164648: image.png
Tue, Apr 2, 12:57 PM
F44147281: image.png
Tue, Apr 2, 10:15 AM
F44147784: image.png
Tue, Apr 2, 10:15 AM
F44144608: Screenshot from 2024-04-02 07-21-02.png
Tue, Apr 2, 10:01 AM

Description

Profile Information

Name: MD. Asiful Alam
IRC nickname on Zulip: MD. Asiful Alam

Resume | GIthub | LinkedIn

Location: Bangladesh (GMT+6)
Project size: Medium
Project Description: MediaWiki

Synopsis

The goal of this project is to introduce a scalable and extensible user badge system to the platform, similar to the one used on Stack Overflow. This feature will incentivize users to contribute positively to the community, recognize their expertise, and enhance overall engagement with the platform. User badges will be awarded based on specific criteria, such as the number of contributions, quality of content, and community ratings. The badge system will be designed with a focus on security, performance, and internationalization to ensure a seamless experience for users across different regions and languages.

Possible Mentor(s)

  • Jan Drewniak (WMF)
  • Bernard Wang (WMF)

Deliverables

For the user badge system project, the key deliverables include:

  • Database Schema Design: A detailed plan for creating tables for badges, badge criteria, and user-badge mappings to efficiently manage badge data.
  • Badge Management System: A system for administrators to create, modify, and manage badges and their criteria, ensuring security and input validation.
  • Badge Awarding Logic: Core logic to award badges based on user activities, integrated with caching and load balancing for scalability.
  • User Profile Integration: Integration of the badge system with user profiles, including localization and translation of badge information.
  • Frontend Implementation: Components and UI elements for displaying badges, leaderboards, progress tracking, and badge details, with responsive design and accessibility considerations.
  • Notifications and Leaderboard: A notification system for earned badges and a leaderboard to showcase top badge holders, optimized for performance.
  • Performance Optimization and Testing: Comprehensive testing and optimization to ensure the system is responsive and performant.
  • Documentation: Detailed documentation covering the codebase, project reports, user guides, and admin manuals.
  • Deployment and Maintenance Plan: A plan for deploying the system to production, including monitoring, logging, and future enhancements.

flowchart

For better view please click here.

Technical Approach

Backend (PHP)

flowchart

For better view please click here.

  • Database Schema and Indexing: Design and implement an optimized database schema to store user badges, badge types, badge criteria, and user-badge mappings. Utilize appropriate indexing strategies to ensure efficient querying and retrieval of badge data.
// Example database schema
CREATE TABLE `badges` (
  `id` INT AUTO_INCREMENT PRIMARY KEY, // Unique identifier for each badge
  `name` VARCHAR(255) NOT NULL, // Name of the badge
  `description` TEXT NOT NULL, // Description of the badge
  `icon` VARCHAR(255) NOT NULL // Path to the badge icon image
);

CREATE TABLE `badge_criteria` (
  `id` INT AUTO_INCREMENT PRIMARY KEY,
  `badge_id` INT NOT NULL, // Foreign key referencing the badge
  `type` VARCHAR(50) NOT NULL, // Type of criteria (e.g., post_count, comment_score, etc.)
  `value` INT NOT NULL, // Required value for the criteria
  FOREIGN KEY (`badge_id`) REFERENCES `badges`(`id`)
);

CREATE TABLE `user_badges` (
  `id` INT AUTO_INCREMENT PRIMARY KEY,
  `user_id` INT NOT NULL, // Foreign key referencing the user
  `badge_id` INT NOT NULL, // Foreign key referencing the badge
  `earned_date` DATETIME NOT NULL, // Date and time when the badge was earned
  FOREIGN KEY (`user_id`) REFERENCES `users`(`id`),
  FOREIGN KEY (`badge_id`) REFERENCES `badges`(`id`)
);

// Indexing example for faster queries
CREATE INDEX idx_user_badges ON user_badges (user_id, badge_id);

The database schema is designed to store badge information, badge criteria, and user-badge mappings. The badges table stores the badge details, the badge_criteria table stores the criteria for earning each badge, and the user_badges table stores the mapping between users and the badges they have earned. Indexing is used on the user_badges table to optimize queries involving user and badge data.

  • Badge Management System: Develop a system to manage badge types, criteria, and award rules. This system should allow administrators to create new badges, modify existing ones, and define the criteria for earning each badge. Implement input validation and security measures to prevent unauthorized badge assignments or tampering.
// Badge creation example
function createBadge($name, $description, $iconPath, $criteria) {
    $conn = openDatabaseConnection();
    $sql = "INSERT INTO badges (name, description, icon) VALUES (?, ?, ?)";
    $stmt = $conn->prepare($sql);
    $stmt->bind_param("sss", $name, $description, $iconPath); // Bind parameters to prevent SQL injection
    $stmt->execute();
    $badgeId = $stmt->insert_id; // Get the ID of the newly created badge
    $stmt->close();

    foreach ($criteria as $criterionType => $criterionValue) {
        addBadgeCriterion($badgeId, $criterionType, $criterionValue);
    }

    $conn->close();
}

// Add badge criterion
function addBadgeCriterion($badgeId, $type, $value) {
    $conn = openDatabaseConnection();
    $sql = "INSERT INTO badge_criteria (badge_id, type, value) VALUES (?, ?, ?)";
    $stmt = $conn->prepare($sql);
    $stmt->bind_param("isi", $badgeId, $type, $value); // Bind parameters to prevent SQL injection
    $stmt->execute();
    $stmt->close();
    $conn->close();
}

The createBadge function allows administrators to create a new badge by inserting its details into the badges table. The addBadgeCriterion function is used to add criteria for earning the badge by inserting records into the badge_criteria table. Input validation and prepared statements are used to prevent SQL injection attacks.

  • Badge Awarding Logic: Implement the core logic to award badges to users based on their activities and contributions. This logic should continuously monitor user actions, evaluate them against the defined criteria, and award badges accordingly. Leverage caching mechanisms and load balancing strategies to handle a large number of users and ensure scalability.
// Badge awarding logic
function awardBadge($userId, $badgeId) {
    $conn = openDatabaseConnection();
    $sql = "INSERT INTO user_badges (user_id, badge_id, earned_date) VALUES (?, ?, NOW())";
    $stmt = $conn->prepare($sql);
    $stmt->bind_param("ii", $userId, $badgeId); // Bind parameters to prevent SQL injection
    $stmt->execute();
    $stmt->close();
    $conn->close();

    // Notify the user about the earned badge
    notifyUser($userId, $badgeId);
}

// Check if user qualifies for a badge
function checkBadgeQualification($userId, $badgeId) {
    $conn = openDatabaseConnection();
    $sql = "SELECT * FROM badge_criteria WHERE badge_id = ?";
    $stmt = $conn->prepare($sql);
    $stmt->bind_param("i", $badgeId); // Bind parameter to prevent SQL injection
    $stmt->execute();
    $result = $stmt->get_result();
    $criteria = $result->fetch_all(MYSQLI_ASSOC);
    $stmt->close();

    foreach ($criteria as $criterion) {
        if ($criterion['type'] === 'post_count') {
            $userPostCount = getUserPostCount($userId);
            if ($userPostCount >= $criterion['value']) {
                awardBadge($userId, $badgeId);
                break;
            }
        }
        // ... Add more criteria checks
    }

    $conn->close();
}

The awardBadge function inserts a record into the user_badges table, indicating that the user has earned the specified badge. The checkBadgeQualification function checks if a user meets the criteria for a particular badge by evaluating the criteria stored in the badge_criteria table. If the user qualifies, the awardBadge function is called to award the badge.

To handle a large number of users and ensure scalability, I plan implement the following strategies:

  • Caching: Cache frequently accessed badge data and user-badge mappings in a fast in-memory cache like Redis or Memcached to reduce database load and improve performance.
  • Load Balancing: Use a load balancer to distribute the workload across multiple application servers, ensuring that the system can handle high traffic and concurrent requests.
  • Asynchronous Processing: Offload badge awarding and notification tasks to a background job queue or message queue system like RabbitMQ or Amazon SQS to prevent blocking the main application thread.
  • Sharding and Partitioning: If the data grows too large, consider sharding or partitioning the database across multiple servers to distribute the load and improve performance.
  • User Profile Integration: Integrate the badge system with the user profile section, displaying the badges earned by each user prominently. Ensure that badge information is properly translated and localized based on the user's language preferences.
// Fetch user badges for display
function getUserBadges($userId, $langCode) {
    $conn = openDatabaseConnection();
    $sql = "SELECT b.id, b.name, b.description, b.icon
            FROM user_badges ub
            JOIN badges b ON ub.badge_id = b.id
            WHERE ub.user_id = ?";
    $stmt = $conn->prepare($sql);
    $stmt->bind_param("i", $userId); // Bind parameter to prevent SQL injection
    $stmt->execute();
    $result = $stmt->get_result();
    $badges = $result->fetch_all(MYSQLI_ASSOC);
    $stmt->close();
    $conn->close();

    // Translate badge names and descriptions
    foreach ($badges as &$badge) {
        $badge['name'] = translateText($badge['name'], $langCode);
        $badge['description'] = translateText($badge['description'], $langCode);
    }

    return $badges;
}

// Translate text based on language code
function translateText($text, $langCode) {
    // Use a translation library or service to translate the text
    $translatedText = getTranslation($text, $langCode);
    return $translatedText;
}

The getUserBadges function retrieves the badges earned by a user from the user_badges and badges tables. It also translates the badge names and descriptions based on the user's language preference using the translateText function. The translateText function can leverage a translation library or service to translate the text based on the provided language code.

For better performance, we can cache the translated badge names and descriptions in a separate table or in-memory cache, reducing the need for real-time translation on every request.

  • Notifications and Leaderboard: Implement a notification system to inform users when they earn a new badge. Additionally, create a leaderboard to showcase the top badge holders, fostering a competitive and engaging environment. The leaderboard should be optimized for performance and support filtering and sorting options.
// Notify user about earned badge
function notifyUser($userId, $badgeId) {
    $conn = openDatabaseConnection();
    $sql = "SELECT b.name, b.description
            FROM badges b
            WHERE b.id = ?";
    $stmt = $conn->prepare($sql);
    $stmt->bind_param("i", $badgeId); // Bind parameter to prevent SQL injection
    $stmt->execute();
    $result = $stmt->get_result();
    $badge = $result->fetch_assoc();
    $stmt->close();
    $conn->close();

    // Send notification to the user (e.g., email, push notification)
    $message = "Congratulations! You earned the '{$badge['name']}' badge: {$badge['description']}";
    sendNotification($userId, $message);
}

// Fetch leaderboard data
function getLeaderboard($filters, $sortBy, $langCode) {
    $conn = openDatabaseConnection();
    $sql = "SELECT u.username, COUNT(ub.id) AS badge_count
            FROM users u
            LEFT JOIN user_badges ub ON u.id = ub.user_id
            GROUP BY u.id
            ORDER BY {$sortBy}";
    $stmt = $conn->prepare($sql);
    $stmt->execute();
    $result = $stmt->get_result();
    $leaderboard = $result->fetch_all(MYSQLI_ASSOC);
    $stmt->close();
    $conn->close();

    // Translate usernames based on language code
    foreach ($leaderboard as &$entry) {
        $entry['username'] = translateText($entry['username'], $langCode);
    }

    return $leaderboard;
}

The notifyUser function retrieves the badge name and description from the badges table and sends a notification to the user informing them about the earned badge. The notification can be sent via email, push notification, or any other suitable method. The getLeaderboard function retrieves the top badge holders by joining the users and user_badges tables and aggregating the badge counts. It supports filtering and sorting options through the $filters and $sortBy parameters. The usernames in the leaderboard are also translated based on the provided language code.

To optimize the leaderboard performance, I plan to implement the following strategies:

  • Caching: Cache the leaderboard data in a fast in-memory cache like Redis or Memcached, updating the cache periodically or when badge data changes.
  • Pagination: Implement pagination to limit the number of results returned and improve response times.
  • Indexing: Create appropriate indexes on the users and user_badges tables to optimize the JOIN and aggregation queries.
  • Denormalization: Consider denormalizing the badge count data into a separate table or column to avoid expensive aggregation queries for the leaderboard.

By implementing these strategies, we can ensure that the notification system and leaderboard remain responsive and performant, even with a large user base and high traffic.

Frontend Implementation

flowchart

For better view please click here.

To provide a seamless user experience and integrate the badge system into the existing MediaWiki interface, the following frontend tasks will be undertaken:

  • User Profile Badge Display: Implement components to fetch and display earned badges on user profile pages, including badge icons, names, descriptions, and any additional metadata.
  • Leaderboard Integration: Develop a leaderboard section to showcase top badge holders, incorporating filtering, sorting, and pagination capabilities for improved performance and usability.
  • Badge Progress Tracking: Create UI elements to inform users about their progress towards earning specific badges, displaying the criteria and remaining requirements.
  • Badge Details and Modals: Implement modals or overlays to display detailed information about each badge, such as its description, criteria, and any relevant statistics or leaderboard rankings.
  • Responsive Design and Accessibility: Ensure that all badge-related UI components are responsive, adhering to best practices for mobile and accessibility standards.
  • Internationalization and Localization: Integrate with MediaWiki's internationalization and localization frameworks to provide translated badge information based on the user's language preferences.
<!-- Example badge display component -->
<template>
  <div class="user-badges">
    <h3>{{ $t('badges.title') }}</h3>
    <div class="badge-list">
      <div v-for="badge in userBadges" :key="badge.id" class="badge-item">
        <img :src="badge.iconUrl" :alt="badge.name" />
        <div class="badge-details">
          <h4>{{ badge.name }}</h4>
          <p>{{ badge.description }}</p>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import { getUserBadges } from '@/api/badges';

export default {
  data() {
    return {
      userBadges: [],
    };
  },
  mounted() {
    this.fetchUserBadges();
  },
  methods: {
    async fetchUserBadges() {
      try {
        const badges = await getUserBadges(this.userId);
        this.userBadges = badges;
      } catch (error) {
        console.error('Error fetching user badges:', error);
      }
    },
  },
};
</script>

The above example showcases a Vue.js component that fetches and displays the user's earned badges. The component imports the getUserBadges function from an API module and renders a list of badge items with their icons, names, and descriptions.

Timeline

Week 1: Planning and Database Design

  • Finalize the requirements and scope of the project
  • Design the database schema for badges, badge criteria, and user-badge mappings
  • Plan indexes and optimize database performance

Week 2-3: Badge Management System

  • Develop the backend system for creating, modifying, and managing badges and their criteria
  • Implement input validation and security measures
  • Build the admin interface for managing badges

Week 4: Badge Awarding Logic (Part 1)

  • Implement the core logic for awarding badges based on user activities
  • Integrate caching strategies for scalability

Week 5: Badge Awarding Logic (Part 2)

  • Develop the system for monitoring user actions and evaluating badge criteria
  • Implement load balancing strategies for scalability

Week 6-7: User Profile Integration

  • Integrate the badge system with user profiles
  • Display earned badges prominently on user profiles
  • Implement localization and translation of badge information

Week 8: Notifications and Leaderboard

  • Develop a notification system for earned badges (email, push notifications, etc.)
  • Build a leaderboard to showcase top badge holders
  • Optimize leaderboard performance with caching and pagination

Week 9: Performance Optimization and Testing

  • Conduct comprehensive performance testing and optimization
  • Identify and address potential bottlenecks
  • Implement additional caching strategies if needed

Week 10: Documentation and Deployment Preparation

  • Document the codebase, project reports, user guides, and admin manuals
  • Prepare a deployment plan, including monitoring, logging, and future enhancements
  • Set up staging and production environments

Week 11: Final Testing and Deployment

  • Perform final testing in staging and production environments
  • Address any remaining issues or bugs
  • Deploy the user badge system to production
  • Monitor the system's performance and gather user feedback

Week 12: Project Wrap-up and Maintenance Plan

  • Conduct a project retrospective and document lessons learned
  • Develop a maintenance plan for future enhancements and bug fixes
  • Provide training and knowledge transfer to the development team

Conclusion

Implementing a scalable and extensible user badge system in this platform will enhance user engagement, incentivize positive contributions, and recognize users for their expertise and contributions. By following the proposed technical approach and timeline, this project will successfully introduce a gamification aspect to the platform, making it more interactive and rewarding for users. The badge system will be designed with a focus on security, performance, internationalization, and integration with existing features, ensuring a seamless and localized experience for users across different regions.

Participation

Communication Medium: Community Zulip room
Communication Frequency: Attending Community meeting, 1:1 call with mentors
Source Code Publication: via Github/Gerrit

About Me

  • Education: Will BSc in Computer Science and Engineering in May 2024.
  • How did you hear about this program - From LinkedIn
  • Will you have any other time commitments, such as school work, another job, planned vacation, etc, during the duration of the program - No
  • We advise all candidates eligible for Google Summer of Code and Outreachy to apply for both programs. Are you planning to apply to both programs and, if so, with what organization(s)? - I am applying only for GSoC.
  • What does making this project happen mean to you?

To answer this question in one line, I really love working for wikimedia, wikidata, wikipedia! Secondly, the required skill set perfectly matches my skill.

Event Timeline

Afi570 updated the task description. (Show Details)

@Afi570 Kindly add a proposal title and add the "Intern Proposal" tag to this ticket. Please note that the deadline to do this is today.

Thank you,

Afi570 renamed this task from Insert project title here to GSoC'24 Proposal: Add For User Badges.Tue, Apr 2, 12:53 PM

@Maryann-Onyinye , thank you for the guidance! But unfortunately, I am unable to find the tag in tag section. What can I do?

image.png (300×480 px, 38 KB)

Done. Please ensure you have also submitted your application on Google's Program Site. All the best

(I'm not sure either what an "Intern Proposal" tag is :)