All checks were successful
Deploy to Test Environment / deploy-to-test (push) Successful in 21m19s
75 lines
2.4 KiB
TypeScript
75 lines
2.4 KiB
TypeScript
// src/services/gamificationService.ts
|
|
|
|
import { gamificationRepo } from './db/index.db';
|
|
import type { Logger } from 'pino';
|
|
import { ForeignKeyConstraintError } from './db/errors.db';
|
|
|
|
class GamificationService {
|
|
/**
|
|
* Awards a specific achievement to a user.
|
|
* @param userId The ID of the user to award the achievement.
|
|
* @param achievementName The name of the achievement to award.
|
|
* @param log The logger instance.
|
|
*/
|
|
async awardAchievement(userId: string, achievementName: string, log: Logger): Promise<void> {
|
|
try {
|
|
await gamificationRepo.awardAchievement(userId, achievementName, log);
|
|
} catch (error) {
|
|
if (error instanceof ForeignKeyConstraintError) {
|
|
// This is an expected error (e.g., achievement name doesn't exist),
|
|
// which the repository layer should have already logged with appropriate context.
|
|
// We re-throw it so the calling layer (e.g., an admin route) can handle it.
|
|
throw error;
|
|
}
|
|
// For unexpected, generic errors, we log them at the service level before re-throwing.
|
|
log.error(
|
|
{ error, userId, achievementName },
|
|
'Error awarding achievement via admin endpoint:',
|
|
);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Retrieves the master list of all available achievements.
|
|
* @param log The logger instance.
|
|
*/
|
|
async getAllAchievements(log: Logger) {
|
|
try {
|
|
return await gamificationRepo.getAllAchievements(log);
|
|
} catch (error) {
|
|
log.error({ error }, 'Error in getAllAchievements service method');
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Retrieves the public leaderboard of top users by points.
|
|
* @param limit The number of users to fetch.
|
|
* @param log The logger instance.
|
|
*/
|
|
async getLeaderboard(limit: number, log: Logger) {
|
|
try {
|
|
return await gamificationRepo.getLeaderboard(limit, log);
|
|
} catch (error) {
|
|
log.error({ error, limit }, 'Error fetching leaderboard in service method.');
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Retrieves all achievements earned by a specific user.
|
|
* @param userId The ID of the user.
|
|
* @param log The logger instance.
|
|
*/
|
|
async getUserAchievements(userId: string, log: Logger) {
|
|
try {
|
|
return await gamificationRepo.getUserAchievements(userId, log);
|
|
} catch (error) {
|
|
log.error({ error, userId }, 'Error fetching user achievements in service method.');
|
|
throw error;
|
|
}
|
|
}
|
|
}
|
|
|
|
export const gamificationService = new GamificationService(); |