feat: update language leaderboard calculation

This commit is contained in:
2024-08-09 21:45:14 +07:00
parent a5cd6383f3
commit 0142224f60
19 changed files with 330 additions and 59 deletions
+5 -5
View File
@@ -37,15 +37,15 @@ export const calculateUserPoints = async (data: CalculateUserPointsType) => {
: 0;
// User repositories
const repos = await db
.select()
.from(repositories)
.where(eq(repositories.userId, user.id));
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.lang))
repos.flatMap((i) => i.languages?.map((j) => j.name))
);
points += languages.size * weights.languagesKnown;
+49 -10
View File
@@ -2,7 +2,8 @@ import db from "@server/db";
import github from "@server/lib/github";
import queue from "@server/lib/queue";
import { repositories } from "@server/models";
import { eq } from "drizzle-orm";
import { repoLanguages } from "@server/models/repo-languages";
import { and, eq, notInArray } from "drizzle-orm";
export type FetchRepoDataJobType = {
id: number;
@@ -10,17 +11,55 @@ export type FetchRepoDataJobType = {
};
export const fetchRepoData = async (data: FetchRepoDataJobType) => {
const details = await github.getRepoDetails(data.uri);
const [repository] = await db
.select()
.from(repositories)
.where(eq(repositories.id, data.id));
const [result] = await db
.update(repositories)
.set({ languages: details.languages })
.where(eq(repositories.id, data.id))
.returning();
if (!result) {
if (!repository) {
throw new Error("Repository not found!");
}
await queue.add("calculateUserPoints", { userId: result.userId });
const details = await github.getRepoDetails(data.uri);
const { languages } = details;
await db.transaction(async (tx) => {
// Remove languages that don't exist anymore
const purgeLangFilter = and(
eq(repoLanguages.repoId, repository.id),
notInArray(
repoLanguages.name,
languages.map((i) => i.lang)
)
);
await tx.delete(repoLanguages).where(purgeLangFilter);
// Add or update languages
for (const lang of languages) {
const [existing] = await tx
.select({ id: repoLanguages.id })
.from(repoLanguages)
.where(
and(
eq(repoLanguages.repoId, repository.id),
eq(repoLanguages.name, lang.lang)
)
);
if (existing) {
await tx
.update(repoLanguages)
.set({ percentage: lang.amount })
.where(eq(repoLanguages.id, existing.id));
} else {
await tx.insert(repoLanguages).values({
repoId: repository.id,
name: lang.lang,
percentage: lang.amount,
});
}
}
});
await queue.add("calculateUserPoints", { userId: repository.userId });
};
+1
View File
@@ -19,6 +19,7 @@ export const fetchUserProfile = async (data: FetchUserProfileType) => {
.update(users)
.set({
name: details.name,
avatar: details.avatar,
followers: details.followers,
following: details.following,
location: details.location,