// 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 { 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();