Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 8x 8x 2x 5x 2x 2x 3x 2x 2x 2x 2x 2x 2x 5x 5x 2x 2x 2x 2x 2x 2x 2x 6x 6x 2x 2x 2x 2x 2x 2x 6x 6x 2x 2x 25x | // 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(); |