Skip to content

Commit

Permalink
feat: new achievements
Browse files Browse the repository at this point in the history
  • Loading branch information
dotslashf committed Oct 4, 2024
1 parent fa99b8b commit bd64592
Show file tree
Hide file tree
Showing 6 changed files with 168 additions and 1 deletion.
11 changes: 11 additions & 0 deletions prisma/migrations/20241004154110_add_new_achievement/migration.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
-- AlterEnum
-- This migration adds more than one value to an enum.
-- With PostgreSQL versions 11 and earlier, this is not possible
-- in a single migration. This can be worked around by creating
-- multiple migrations, each migration adding only one value to
-- the enum.


ALTER TYPE "AchievementType" ADD VALUE 'FiveCopyPastaADay';
ALTER TYPE "AchievementType" ADD VALUE 'TagCollector';
ALTER TYPE "AchievementType" ADD VALUE 'CollectionCurator';
3 changes: 3 additions & 0 deletions prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,9 @@ enum AchievementType {
OneMonthStreak
ThreeMonthStreak
SixMonthStreak
FiveCopyPastaADay
TagCollector
CollectionCurator
}

enum EngagementAction {
Expand Down
8 changes: 8 additions & 0 deletions src/lib/constant.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -161,3 +161,11 @@ export const ENGAGEMENT_SCORE = {
};

export const TIMEZONE = "Asia/Jakarta";

export const ACHIEVEMENT_MINIMUM = {
TAG_COLLECTOR_MINIMUM: 15,
COLLECTION_CURATOR: {
COPY_PASTA_PER_COLLECTION: 5,
COLLECTION_MINIMUM: 3,
},
};
10 changes: 10 additions & 0 deletions src/server/api/routers/collection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
editCollectionForm,
} from "~/server/form/collection";
import { updateUserEngagementScore } from "~/server/util/db";
import { checkAndGrantCollectionCuratorAchievement } from "~/server/util/achievement";

export const collectionRouter = createTRPCRouter({
list: publicProcedure
Expand Down Expand Up @@ -97,6 +98,10 @@ export const collectionRouter = createTRPCRouter({
});
const payload = handleEngagementAction("CreateCollection", collection.id);
await updateUserEngagementScore(ctx.db, ctx.session.user.id, payload);
await checkAndGrantCollectionCuratorAchievement(
ctx.db,
ctx.session.user.id,
);

return collection.id;
}),
Expand Down Expand Up @@ -235,6 +240,11 @@ export const collectionRouter = createTRPCRouter({
},
},
});

await checkAndGrantCollectionCuratorAchievement(
ctx.db,
ctx.session.user.id,
);
}),

delete: protectedProcedure
Expand Down
11 changes: 10 additions & 1 deletion src/server/api/routers/copyPasta.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ import {
type CopyPastaSearchResult,
} from "~/lib/interface";
import { updateUserEngagementScore } from "~/server/util/db";
import {
checkAndGrantFiveCopyPastaADayAchievement,
checkAndGrantTagCollectionAchievement,
} from "~/server/util/achievement";

function tokenize(content: string) {
return content.toLowerCase().split(/\s+/);
Expand Down Expand Up @@ -99,7 +103,12 @@ export const copyPastaRouter = createTRPCRouter({
});

const payload = handleEngagementAction("CreateCopyPasta", copyPasta.id);
await updateUserEngagementScore(ctx.db, ctx.session.user.id, payload);
await Promise.all([
updateUserEngagementScore(ctx.db, ctx.session.user.id, payload),
checkAndGrantTagCollectionAchievement(ctx.db, ctx.session.user.id),
checkAndGrantFiveCopyPastaADayAchievement(ctx.db, ctx.session.user.id),
]);

if (isSuperAdmin) {
const payload = handleEngagementAction(
"ApproveCopyPasta",
Expand Down
126 changes: 126 additions & 0 deletions src/server/util/achievement.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
import { AchievementType, type PrismaClient } from "@prisma/client";
import { ACHIEVEMENT_MINIMUM } from "~/lib/constant";
import { getJakartaDate } from "~/utils";

export async function checkAndGrantFiveCopyPastaADayAchievement(
db: PrismaClient,
userId: string,
) {
const today = getJakartaDate();
today.setHours(0, 0, 0);

const userCreatedCopyPastaToday = await db.copyPasta.count({
where: {
createdAt: {
gte: today,
},
createdById: userId,
},
});

if (userCreatedCopyPastaToday >= 5) {
const existingAchievement = await db.achievement.findUnique({
where: {
userId_type: {
userId,
type: AchievementType.FiveCopyPastaADay,
},
},
});

if (!existingAchievement) {
await db.achievement.create({
data: {
userId,
type: AchievementType.FiveCopyPastaADay,
},
});
console.log(
`User ${userId} has been granted the FiveCopyPastaADay achievement!`,
);
}
}
}

export async function checkAndGrantTagCollectionAchievement(
db: PrismaClient,
userId: string,
) {
const distinctTags = await db.copyPastasOnTags.findMany({
where: {
copyPastas: {
createdById: userId,
},
},
distinct: ["tagId"],
});

if (distinctTags.length >= ACHIEVEMENT_MINIMUM.TAG_COLLECTOR_MINIMUM) {
const existingAchievement = await db.achievement.findUnique({
where: {
userId_type: {
userId,
type: AchievementType.TagCollector,
},
},
});

if (!existingAchievement) {
await db.achievement.create({
data: {
userId,
type: AchievementType.TagCollector,
},
});
console.log(`User ${userId} has been granted the TagMaster achievement!`);
}
}
}

export async function checkAndGrantCollectionCuratorAchievement(
db: PrismaClient,
userId: string,
) {
const collections = await db.collection.findMany({
where: {
createdById: userId,
},
include: {
_count: {
select: { copyPastas: true },
},
},
});

const qualifiedCollections = collections.filter(
(collection) =>
collection._count.copyPastas >=
ACHIEVEMENT_MINIMUM.COLLECTION_CURATOR.COPY_PASTA_PER_COLLECTION,
);

if (
qualifiedCollections.length >=
ACHIEVEMENT_MINIMUM.COLLECTION_CURATOR.COLLECTION_MINIMUM
) {
const existingAchievement = await db.achievement.findUnique({
where: {
userId_type: {
userId,
type: AchievementType.CollectionCurator,
},
},
});

if (!existingAchievement) {
await db.achievement.create({
data: {
userId,
type: AchievementType.CollectionCurator,
},
});
console.log(
`User ${userId} has been granted the CollectionCurator achievement!`,
);
}
}
}

0 comments on commit bd64592

Please sign in to comment.