35 lines
1.1 KiB
TypeScript
35 lines
1.1 KiB
TypeScript
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<RankInfo> {
|
|
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 };
|
|
}
|
|
}
|