From a2c853844d3cf063296b3a416a5e2bf1f715a638 Mon Sep 17 00:00:00 2001 From: neketka Date: Tue, 30 Apr 2024 17:00:46 -0400 Subject: [PATCH] Achivement trackers are made for all --- server/src/achievement/achievement.service.ts | 61 ++++++++++++++----- server/src/user/user.module.ts | 2 + server/src/user/user.service.ts | 4 ++ 3 files changed, 52 insertions(+), 15 deletions(-) diff --git a/server/src/achievement/achievement.service.ts b/server/src/achievement/achievement.service.ts index 63e97876..9285b6fb 100644 --- a/server/src/achievement/achievement.service.ts +++ b/server/src/achievement/achievement.service.ts @@ -145,6 +145,7 @@ export class AchievementService { } else { return null; } + if (ach) this.createAchievementTrackers(undefined, ach); return ach; } @@ -358,20 +359,7 @@ export class AchievementService { }); for (const ach of uncompletedAchs) { - let achTracker: AchievementTracker; - if (ach.trackers.length === 0) { - // create tracker since it doesn't exist - achTracker = await this.prisma.achievementTracker.create({ - data: { - userId: user.id, - achievementId: ach.id, - progress: 0, - dateComplete: null, - }, - }); - } else { - achTracker = ach.trackers[0]; - } + let achTracker = ach.trackers[0]; // In case the above completion check fails if (achTracker.progress < ach.requiredPoints) { @@ -391,7 +379,7 @@ export class AchievementService { }, }); - if (achTracker.progress >= ach.requiredPoints) { + if (achTracker.progress > ach.requiredPoints) { achTracker = await this.prisma.achievementTracker.update({ where: { id: achTracker.id }, data: { @@ -405,4 +393,47 @@ export class AchievementService { } } } + + async createAchievementTrackers(user?: User, achievement?: Achievement) { + if (user) { + const ability = this.abilityFactory.createForUser(user); + + const achsWithoutTrackers = await this.prisma.achievement.findMany({ + where: { + id: achievement?.id, + AND: [accessibleBy(ability).Achievement], + trackers: { none: { userId: user.id } }, + }, + }); + + await this.prisma.achievementTracker.createMany({ + data: achsWithoutTrackers.map(ach => ({ + userId: user.id, + progress: 0, + achievementId: ach.id, + })), + }); + } else if (achievement) { + const usersWithoutTrackers = await this.prisma.user.findMany({ + where: { + memberOf: { + some: { achievements: { some: { id: achievement.id } } }, + }, + achievementTrackers: { + none: { achievementId: achievement.id }, + }, + }, + }); + + await this.prisma.achievementTracker.createMany({ + data: usersWithoutTrackers.map(usr => ({ + userId: usr.id, + progress: 0, + achievementId: achievement.id, + })), + }); + } else { + throw 'Cannot create all possible achievement trackers in one call!'; + } + } } diff --git a/server/src/user/user.module.ts b/server/src/user/user.module.ts index ffc69184..bde72264 100644 --- a/server/src/user/user.module.ts +++ b/server/src/user/user.module.ts @@ -9,6 +9,7 @@ import { PrismaModule } from '../prisma/prisma.module'; import { UserGateway } from './user.gateway'; import { UserService } from './user.service'; import { CaslModule } from '../casl/casl.module'; +import { AchievementModule } from '../achievement/achievement.module'; @Module({ imports: [ @@ -19,6 +20,7 @@ import { CaslModule } from '../casl/casl.module'; PrismaModule, EventModule, OrganizationModule, + AchievementModule, CaslModule, ], providers: [UserService, UserGateway], diff --git a/server/src/user/user.service.ts b/server/src/user/user.service.ts index 2f0c7ab4..e8f3dbb5 100644 --- a/server/src/user/user.service.ts +++ b/server/src/user/user.service.ts @@ -22,6 +22,7 @@ import { Action } from '../casl/action.enum'; import { subject } from '@casl/ability'; import { accessibleBy } from '@casl/prisma'; import { join } from 'path'; +import { AchievementService } from '../achievement/achievement.service'; @Injectable() export class UserService { @@ -34,6 +35,7 @@ export class UserService { private orgService: OrganizationService, private clientService: ClientService, private abilityFactory: CaslAbilityFactory, + private achievementService: AchievementService, ) {} /** Find a user by their authentication token */ @@ -112,6 +114,8 @@ export class UserService { await this.orgService.joinOrganization(user, cornellOrg.accessCode); } + await this.achievementService.createAchievementTrackers(user); + return user; }