feat: phase 5 — rewards system, triggers sur session/ami/groupe, seed 7 récompenses
This commit is contained in:
76
backend/src/services/reward.service.ts
Normal file
76
backend/src/services/reward.service.ts
Normal file
@@ -0,0 +1,76 @@
|
||||
import { prisma } from "../index";
|
||||
|
||||
// Conditions disponibles — à étendre librement
|
||||
const CONDITIONS: Record<string, (userId: string) => Promise<boolean>> = {
|
||||
first_program: async (userId) => {
|
||||
const count = await prisma.history.count({
|
||||
where: { userId, completedAt: { not: null } },
|
||||
});
|
||||
return count >= 1;
|
||||
},
|
||||
five_programs: async (userId) => {
|
||||
const count = await prisma.history.count({
|
||||
where: { userId, completedAt: { not: null } },
|
||||
});
|
||||
return count >= 5;
|
||||
},
|
||||
ten_programs: async (userId) => {
|
||||
const count = await prisma.history.count({
|
||||
where: { userId, completedAt: { not: null } },
|
||||
});
|
||||
return count >= 10;
|
||||
},
|
||||
first_friend: async (userId) => {
|
||||
const count = await prisma.friendRequest.count({
|
||||
where: {
|
||||
status: "ACCEPTED",
|
||||
OR: [{ senderId: userId }, { receiverId: userId }],
|
||||
},
|
||||
});
|
||||
return count >= 1;
|
||||
},
|
||||
five_friends: async (userId) => {
|
||||
const count = await prisma.friendRequest.count({
|
||||
where: {
|
||||
status: "ACCEPTED",
|
||||
OR: [{ senderId: userId }, { receiverId: userId }],
|
||||
},
|
||||
});
|
||||
return count >= 5;
|
||||
},
|
||||
first_group: async (userId) => {
|
||||
const count = await prisma.groupMember.count({ where: { userId } });
|
||||
return count >= 1;
|
||||
},
|
||||
first_program_created: async (userId) => {
|
||||
const count = await prisma.program.count({ where: { authorId: userId } });
|
||||
return count >= 1;
|
||||
},
|
||||
};
|
||||
|
||||
// Vérifie et attribue toutes les récompenses débloquées pour un utilisateur
|
||||
export async function checkAndGrantRewards(userId: string): Promise<string[]> {
|
||||
const allRewards = await prisma.reward.findMany();
|
||||
const earned = await prisma.userReward.findMany({
|
||||
where: { userId },
|
||||
select: { rewardId: true },
|
||||
});
|
||||
const earnedIds = new Set(earned.map((r) => r.rewardId));
|
||||
|
||||
const newlyEarned: string[] = [];
|
||||
|
||||
for (const reward of allRewards) {
|
||||
if (earnedIds.has(reward.id!)) continue;
|
||||
|
||||
const checker = CONDITIONS[reward.condition];
|
||||
if (!checker) continue;
|
||||
|
||||
const unlocked = await checker(userId);
|
||||
if (unlocked) {
|
||||
await prisma.userReward.create({ data: { userId, rewardId: reward.id! } });
|
||||
newlyEarned.push(reward.name);
|
||||
}
|
||||
}
|
||||
|
||||
return newlyEarned;
|
||||
}
|
||||
Reference in New Issue
Block a user