Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat ✨ coalition ranking #382

Merged
merged 3 commits into from
Oct 31, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion app/src/api/coalition/coalition.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ import { InjectModel } from '@nestjs/mongoose';
import type { Aggregate, Model } from 'mongoose';
import { API_CONFIG } from 'src/config/api';
import { CDN_CONFIG } from 'src/config/cdn';
import { findAllAndLean } from 'src/database/mongoose/database.mongoose.query';
import type { Coalition } from '../../page/common/models/coalition.model';
import { coalition } from './db/coalition.database.schema';
import type { Coalition } from './models/coalition.model';

@Injectable()
export class CoalitionService {
Expand All @@ -26,7 +27,9 @@ export class CoalitionService {
return {
...dao,
coverUrl: this.coverUrlById(dao.id),
// todo: deprecated at v0.9.0
imageUrl: this.imageUrlById(dao.id),
imgUrl: this.imageUrlById(dao.id),
color: dao.color ?? '#161616',
};
}
Expand Down Expand Up @@ -57,4 +60,14 @@ export class CoalitionService {
getSeoulCoalitionIds(): readonly number[] {
return this.apiConfig.SEOUL_COALITION_ID;
}

async getSeoulCoalitions(): Promise<Coalition[]> {
const coalitions = await findAllAndLean<coalition>(this.coalitionModel, {
filter: {
id: { $in: this.getSeoulCoalitionIds() },
},
});

return coalitions.map((coalition) => this.daoToDto(coalition));
}
}
28 changes: 0 additions & 28 deletions app/src/api/coalition/models/coalition.model.ts

This file was deleted.

16 changes: 6 additions & 10 deletions app/src/api/cursusUser/cursusUser.cache.service.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { Injectable } from '@nestjs/common';
import {
CacheUtilRankingService,
type GetRankArgs,
type GetRankingArgs,
type RankCache,
} from 'src/cache/cache.util.ranking.service';
import {
Expand Down Expand Up @@ -41,26 +43,20 @@ export class CursusUserCacheService {
}

async getUserRank(
keyBase: UserRankingKey,
userId: number,
promo?: number,
cacheArgs: Omit<GetRankArgs, 'dateTemplate'>,
): Promise<RankCache | undefined> {
return await this.cacheUtilRankingService.getRawRank({
keyBase,
userId,
dateTemplate: DateTemplate.TOTAL,
promo,
...cacheArgs,
});
}

async getUserRanking(
keyBase: UserRankingKey,
promo?: number,
cacheArgs: Omit<GetRankingArgs, 'dateTemplate'>,
): Promise<RankCache[] | undefined> {
return await this.cacheUtilRankingService.getRawRanking({
keyBase,
dateTemplate: DateTemplate.TOTAL,
promo,
...cacheArgs,
});
}
}
16 changes: 6 additions & 10 deletions app/src/api/experienceUser/experienceUser.cache.service.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { Injectable } from '@nestjs/common';
import {
CacheUtilRankingService,
type GetRankArgs,
type GetRankingArgs,
type RankCache,
type RankingSupportedDateTemplate,
} from 'src/cache/cache.util.ranking.service';
Expand All @@ -20,26 +22,20 @@ export class ExperienceUserCacheService {
) {}

async getExpIncreamentRank(
dateTemplate: ExpIncreamentRankingCacheSupportedDateTemplate,
userId: number,
promo?: number,
cacheArgs: Omit<GetRankArgs, 'keyBase'>,
): Promise<RankCache | undefined> {
return await this.cacheUtilRankingService.getRank({
keyBase: EXP_INCREAMENT_RANKING,
dateTemplate,
userId,
promo,
...cacheArgs,
});
}

async getExpIncreamentRanking(
dateTemplate: ExpIncreamentRankingCacheSupportedDateTemplate,
promo?: number,
cacheArgs: Omit<GetRankingArgs, 'keyBase'>,
): Promise<RankCache[] | undefined> {
return await this.cacheUtilRankingService.getRanking({
keyBase: EXP_INCREAMENT_RANKING,
dateTemplate,
promo,
...cacheArgs,
});
}
}
32 changes: 10 additions & 22 deletions app/src/api/scaleTeam/scaleTeam.cache.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,35 +43,29 @@ export class ScaleTeamCacheService {
) {}

async getEvalCountRank(
dateTemplate: EvalCountRankingSupportedDateTemplate,
userId: number,
promo?: number,
cacheArgs: Omit<GetRankArgs, 'keyBase'>,
): Promise<RankCache | undefined> {
const args: GetRankArgs = {
keyBase: EVAL_COUNT_RANKING,
userId,
dateTemplate,
promo,
...cacheArgs,
};

if (dateTemplate === DateTemplate.TOTAL) {
if (cacheArgs.dateTemplate === DateTemplate.TOTAL) {
return await this.cacheUtilRankingService.getRawRank(args);
}

return await this.cacheUtilRankingService.getRank(args);
}

async getEvalCountRanking(
dateTemplate: EvalCountRankingSupportedDateTemplate,
promo?: number,
cacheArgs: Omit<GetRankingArgs, 'keyBase'>,
): Promise<RankCache[] | undefined> {
const args: GetRankingArgs = {
keyBase: EVAL_COUNT_RANKING,
dateTemplate,
promo,
...cacheArgs,
};

if (dateTemplate === DateTemplate.TOTAL) {
if (cacheArgs.dateTemplate === DateTemplate.TOTAL) {
return await this.cacheUtilRankingService.getRawRanking(args);
}

Expand All @@ -87,26 +81,20 @@ export class ScaleTeamCacheService {
}

async getCommentRank(
dateTemplate: AverageReviewLengthRankingSupportedDateTemplate,
userId: number,
promo?: number,
cacheArgs: Omit<GetRankArgs, 'keyBase'>,
): Promise<RankCache | undefined> {
return await this.cacheUtilRankingService.getRank({
keyBase: COMMENT_RANKING,
userId,
dateTemplate,
promo,
...cacheArgs,
});
}

async getCommentRanking(
dateTemplate: AverageReviewLengthRankingSupportedDateTemplate,
promo?: number,
cacheArgs: Omit<GetRankingArgs, 'keyBase'>,
): Promise<RankCache[] | undefined> {
return await this.cacheUtilRankingService.getRanking({
keyBase: COMMENT_RANKING,
dateTemplate,
promo,
...cacheArgs,
});
}
}
23 changes: 13 additions & 10 deletions app/src/api/score/score.cache.service.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { Injectable } from '@nestjs/common';
import {
CacheUtilRankingService,
type GetRankArgs,
type GetRankingArgs,
type RankCache,
type RankingSupportedDateTemplate,
} from 'src/cache/cache.util.ranking.service';
Expand All @@ -11,6 +13,7 @@ import { ScoreService } from './score.service';
export const SCORE_RANKING = 'scoreRanking';
export const TOTAL_SCORES_BY_COALITION = 'totalScoresByCoalition';
export const SCORE_RECORDS = 'scoreRecords';
export const WIN_COUNT_PER_COALITION = 'winCountPerCoalition';

export type ScoreRankingSupportedDateTemplate = Extract<
RankingSupportedDateTemplate,
Expand All @@ -27,26 +30,20 @@ export class ScoreCacheService {
) {}

async getScoreRank(
dateTemplate: ScoreRankingSupportedDateTemplate,
userId: number,
promo?: number,
cacheArgs: Omit<GetRankArgs, 'keyBase'>,
): Promise<RankCache | undefined> {
return await this.cacheUtilRankingService.getRank({
keyBase: SCORE_RANKING,
userId,
dateTemplate,
promo,
...cacheArgs,
});
}

async getScoreRanking(
dateTemplate: ScoreRankingSupportedDateTemplate,
promo?: number,
cacheArgs: Omit<GetRankingArgs, 'keyBase'>,
): Promise<RankCache[] | undefined> {
return await this.cacheUtilRankingService.getRanking({
keyBase: SCORE_RANKING,
dateTemplate,
promo,
...cacheArgs,
});
}

Expand All @@ -63,4 +60,10 @@ export class ScoreCacheService {
> {
return await this.cacheUtilService.getWithoutDate(SCORE_RECORDS);
}

async getWinCountPerCoalition(): Promise<
ReturnType<ScoreService['winCountPerCoalition']> | undefined
> {
return await this.cacheUtilService.getWithoutDate(WIN_COUNT_PER_COALITION);
}
}
52 changes: 32 additions & 20 deletions app/src/api/score/score.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { InjectModel } from '@nestjs/mongoose';
import type { FilterQuery, Model } from 'mongoose';
import { RUNTIME_CONFIG } from 'src/config/runtime';
import { addRank } from 'src/database/mongoose/database.mongoose.aggregation';
import { DateWrapper } from 'src/dateWrapper/dateWrapper';
import type {
IntPerCoalition,
ScoreRecordPerCoalition,
Expand Down Expand Up @@ -75,9 +76,11 @@ export class ScoreService {
const targetCoalitionIds =
args?.targetCoalitionIds ?? this.coalitionService.getSeoulCoalitionIds();

const aggregate = this.scoreModel.aggregate<IntPerCoalition>();
const aggregate = this.scoreModel.aggregate<
Omit<IntPerCoalition, 'coalition'> & { coalition: coalition }
>();

return await aggregate
const scoresPerCoalitionDao = await aggregate
.match({
coalitionsUserId: { $ne: null },
coalitionId: { $in: targetCoalitionIds },
Expand All @@ -93,6 +96,11 @@ export class ScoreService {
coalition: { $first: '$coalitions' },
value: 1,
});

return scoresPerCoalitionDao.map(({ value, coalition }) => ({
coalition: this.coalitionService.daoToDto(coalition),
value,
}));
}

async scoreRecordsPerCoalition(args?: {
Expand All @@ -102,10 +110,11 @@ export class ScoreService {
const targetCoalitionIds =
args?.targetCoalitionIds ?? this.coalitionService.getSeoulCoalitionIds();

const aggregate =
this.coalitionService.aggregate<ScoreRecordPerCoalition>();
const aggregate = this.coalitionService.aggregate<
Omit<ScoreRecordPerCoalition, 'coalition'> & { coalition: coalition }
>();

return await aggregate
const scoreRecordsPerCoalitionDao = await aggregate
.match({
id: { $in: targetCoalitionIds },
})
Expand Down Expand Up @@ -160,6 +169,11 @@ export class ScoreService {
},
},
});

return scoreRecordsPerCoalitionDao.map(({ coalition, records }) => ({
coalition: this.coalitionService.daoToDto(coalition),
records,
}));
}

async tigCountPerCoalition(args?: {
Expand Down Expand Up @@ -202,20 +216,17 @@ export class ScoreService {
);
}

async winCountPerCoalition(args?: {
targetCoalitionIds?: readonly number[];
filter?: FilterQuery<score>;
}): Promise<IntPerCoalition[]> {
const targetCoalitionIds =
args?.targetCoalitionIds ?? this.coalitionService.getSeoulCoalitionIds();
async winCountPerCoalition(): Promise<IntPerCoalition[]> {
const endDate = new DateWrapper().startOfMonth().toDate();

const aggregate = this.scoreModel.aggregate<IntPerCoalition>();
const aggregate = this.scoreModel.aggregate<
Omit<IntPerCoalition, 'coalition'> & { coalition: coalition }
>();

return await aggregate
const winCountPerCoalitionDao = await aggregate
.match({
...args?.filter,
createdAt: { $lt: endDate },
coalitionsUserId: { $ne: null },
coalitionId: { $in: targetCoalitionIds },
})
.group({
_id: {
Expand All @@ -242,16 +253,17 @@ export class ScoreService {
_id: '$winCoalition._id.coalitionId',
value: { $count: {} },
})
.sort({ _id: 1 })
.append(lookupCoalition('_id', 'id'))
.project({
_id: 0,
coalition: { $first: '$coalitions' },
value: 1,
})
.then((winCountPerCoalition) => {
return winCountPerCoalition.sort(
(a, b) => a.coalition.id - b.coalition.id,
);
});

return winCountPerCoalitionDao.map(({ coalition, value }) => ({
coalition: this.coalitionService.daoToDto(coalition),
value,
}));
}
}
Loading