import db from "@server/db"; import { repositories, users } from "@server/models"; import { eq } from "drizzle-orm"; type CalculateUserPointsType = { userId: number; }; const weights = { followers: 20, following: 10, achievements: 100, repositories: 1, contributorsAmount: 25, stars: 10, forks: 10, languagesKnown: 50, commits: 1, lineOfCodes: 0.01, }; export const calculateUserPoints = async (data: CalculateUserPointsType) => { const [user] = await db.select().from(users).where(eq(users.id, data.userId)); if (!user) { throw new Error("User not found!"); } let points = 0; let totalCommits = 0; let totalLineOfCodes = 0; // User statistics points += user.followers * weights.followers; points += user.following * weights.following; points += user.achievements ? user.achievements?.length * weights.achievements : 0; // User repositories const repos = await db.query.repositories.findMany({ where: eq(repositories.userId, user.id), with: { languages: true }, }); points += repos.length * weights.repositories; // Languages known const languages = new Set( repos.flatMap((i) => i.languages?.map((j) => j.name)) ); points += languages.size * weights.languagesKnown; // Activities repos.forEach((repo) => { const contributors = repo.contributors?.filter( (i) => i.author?.login !== user.username ); points += contributors ? contributors.length * weights.contributorsAmount : 0; points += repo.stars * weights.stars; points += repo.forks * weights.forks; const contrib = repo.contributors?.find( (i) => i.author?.login === user.username ); const commits = contrib?.commits || 0; const lineOfCodes = contrib?.additions || 0; points += commits * weights.commits; points += lineOfCodes * weights.lineOfCodes; totalCommits += commits; totalLineOfCodes += lineOfCodes; }); await db .update(users) .set({ points: Math.round(points), commits: totalCommits, lineOfCodes: totalLineOfCodes, }) .where(eq(users.id, user.id)); };