near-protocol-rewards
Version:
A transparent, metric-based rewards system for NEAR projects
164 lines (163 loc) • 5.96 kB
JavaScript
"use strict";
/**
* GitHub Rewards Calculator
* Calculates developer rewards based on GitHub activity metrics
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.GitHubRewardsCalculator = exports.DEFAULT_THRESHOLDS = exports.DEFAULT_WEIGHTS = void 0;
exports.DEFAULT_WEIGHTS = {
commits: 0.35,
pullRequests: 0.25,
reviews: 0.2,
issues: 0.2,
};
exports.DEFAULT_THRESHOLDS = {
commits: 100,
pullRequests: 20,
reviews: 30,
issues: 30,
};
const LEVELS = [
{ name: "Diamond", minScore: 90, maxScore: 100, color: "#B9F2FF" },
{ name: "Platinum", minScore: 80, maxScore: 89, color: "#E5E4E2" },
{ name: "Gold", minScore: 70, maxScore: 79, color: "#FFD700" },
{ name: "Silver", minScore: 60, maxScore: 69, color: "#C0C0C0" },
{ name: "Bronze", minScore: 50, maxScore: 59, color: "#CD7F32" },
{ name: "Member", minScore: 0, maxScore: 49, color: "#A4A4A4" },
];
class GitHubRewardsCalculator {
constructor(weights, thresholds, logger, validator) {
this.weights = weights;
this.thresholds = thresholds;
this.logger = logger;
this.validator = validator;
}
calculateRewards(metrics, timeframe) {
const score = this.calculateScore(metrics);
const now = Date.now();
let periodStart;
switch (timeframe) {
case "day":
periodStart = now - 24 * 60 * 60 * 1000;
break;
case "last-week":
periodStart = now - 7 * 24 * 60 * 60 * 1000;
break;
case "last-thirty-days":
periodStart = now - 30 * 24 * 60 * 60 * 1000;
break;
case "current-month": {
const currentDate = new Date();
const startOfMonth = new Date(currentDate.getFullYear(), currentDate.getMonth(), 1);
periodStart = startOfMonth.getTime();
break;
}
default:
periodStart = now - 7 * 24 * 60 * 60 * 1000; // Default to week
}
// Calculate level based on score
const level = this.determineLevel(score.total);
// Calculate achievements
const achievements = this.calculateAchievements(metrics);
return {
score,
breakdown: score.breakdown,
level,
achievements,
metadata: {
timestamp: now,
periodStart,
periodEnd: now,
},
};
}
calculateScore(metrics) {
const commitScore = Math.min(metrics.commits.count / this.thresholds.commits, 1) *
this.weights.commits *
50;
const prScore = Math.min(metrics.pullRequests.merged / this.thresholds.pullRequests, 1) *
this.weights.pullRequests *
50;
const reviewScore = Math.min(metrics.reviews.count / this.thresholds.reviews, 1) *
this.weights.reviews *
50;
const issueScore = Math.min(metrics.issues.closed / this.thresholds.issues, 1) *
this.weights.issues *
50;
return {
total: Math.min(commitScore + prScore + reviewScore + issueScore, 50),
breakdown: {
commits: commitScore,
pullRequests: prScore,
reviews: reviewScore,
issues: issueScore,
},
};
}
determineLevel(score) {
if (score >= 90) {
return { name: "Diamond", minScore: 90, maxScore: 100, color: "#B9F2FF" };
}
else if (score >= 80) {
return { name: "Platinum", minScore: 80, maxScore: 89, color: "#E5E4E2" };
}
else if (score >= 70) {
return { name: "Gold", minScore: 70, maxScore: 79, color: "#FFD700" };
}
else if (score >= 60) {
return { name: "Silver", minScore: 60, maxScore: 69, color: "#C0C0C0" };
}
else if (score >= 50) {
return { name: "Bronze", minScore: 50, maxScore: 59, color: "#CD7F32" };
}
else {
return { name: "Member", minScore: 0, maxScore: 49, color: "#A4A4A4" };
}
}
calculateAchievements(metrics) {
const achievements = [];
const now = new Date().toISOString();
// Commit achievements
if (metrics.commits.count >= this.thresholds.commits) {
achievements.push({
id: "commit-master",
name: "Commit Master",
description: `Made ${this.thresholds.commits} or more commits`,
earnedAt: now,
category: "commit",
});
}
// PR achievements
if (metrics.pullRequests.merged >= this.thresholds.pullRequests) {
achievements.push({
id: "pr-master",
name: "PR Master",
description: `Merged ${this.thresholds.pullRequests} or more pull requests`,
earnedAt: now,
category: "pr",
});
}
// Review achievements
if (metrics.reviews.count >= this.thresholds.reviews) {
achievements.push({
id: "review-expert",
name: "Review Expert",
description: `Completed ${this.thresholds.reviews} or more code reviews`,
earnedAt: now,
category: "review",
});
}
// Issue achievements
if (metrics.issues.closed >= this.thresholds.issues) {
achievements.push({
id: "issue-resolver",
name: "Issue Resolver",
description: `Closed ${this.thresholds.issues} or more issues`,
earnedAt: now,
category: "issue",
});
}
return achievements;
}
}
exports.GitHubRewardsCalculator = GitHubRewardsCalculator;