import { Injectable } from '@nestjs/common'; import { EntityManager } from 'typeorm'; import { SolveEntity } from '../../database/entities/solve.entity'; export interface RankInfo { rank: number | null; points: number; } @Injectable() export class UsersRankService { async rankOfUser(manager: EntityManager, userId: string): Promise { const solveRepo = manager.getRepository(SolveEntity); const pointsRow = await solveRepo .createQueryBuilder('s') .select('COALESCE(SUM(s.pointsAwarded), 0)', 'total') .where('s.userId = :userId', { userId }) .getRawOne<{ total: string | number | null }>(); const points = Number(pointsRow?.total ?? 0); if (points <= 0) { return { rank: null, points: 0 }; } const ahead = await solveRepo .createQueryBuilder('s') .select('s.userId', 'userId') .addSelect('SUM(s.pointsAwarded)', 'total') .groupBy('s.userId') .having('SUM(s.pointsAwarded) > :points', { points }) .getRawMany<{ userId: string }>(); return { rank: ahead.length + 1, points }; } }