Skip to content

Commit

Permalink
feat: ✨ 주간, 월간 average review length ranking 추가, 누적 기간에 대해서 전체 평가 수 검…
Browse files Browse the repository at this point in the history
…사 추가

- close #358
  • Loading branch information
jpham005 committed Oct 17, 2023
1 parent d1f60a1 commit 9aac3d5
Show file tree
Hide file tree
Showing 7 changed files with 133 additions and 31 deletions.
24 changes: 18 additions & 6 deletions app/src/api/scaleTeam/scaleTeam.cache.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,14 @@ import {
import { CacheUtilService } from 'src/cache/cache.util.service';
import { DateTemplate } from 'src/dateRange/dtos/dateRange.dto';
import { ScaleTeamService } from './scaleTeam.service';

export const EVAL_COUNT_RANKING = 'evalCountRanking';
export const COMMENT_RANKING = 'commentRanking';

export const AVERAGE_FEEDBACK_LENGTH = 'averageFeedbackLength';
export const AVERAGE_COMMENT_LENGTH = 'averageCommentLength';

export const COMMENT_RANKING = 'commentRanking';

export type EvalCountRankingSupportedDateTemplate = Extract<
RankingSupportedDateTemplate,
DateTemplate.TOTAL | DateTemplate.CURR_MONTH | DateTemplate.CURR_WEEK
Expand All @@ -27,6 +30,11 @@ type AverageReviewLengthCache = Awaited<
ReturnType<ScaleTeamService['averageReviewLength']> | undefined
>;

export type AverageReviewLengthRankingSupportedDateTemplate = Extract<
RankingSupportedDateTemplate,
DateTemplate.TOTAL | DateTemplate.CURR_MONTH | DateTemplate.CURR_WEEK
>;

@Injectable()
export class ScaleTeamCacheService {
constructor(
Expand Down Expand Up @@ -79,21 +87,25 @@ export class ScaleTeamCacheService {
}

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

async getCommentRanking(promo?: number): Promise<RankCache[] | undefined> {
return await this.cacheUtilRankingService.getRawRanking({
async getCommentRanking(
dateTemplate: AverageReviewLengthRankingSupportedDateTemplate,
promo?: number,
): Promise<RankCache[] | undefined> {
return await this.cacheUtilRankingService.getRanking({
keyBase: COMMENT_RANKING,
dateTemplate: DateTemplate.TOTAL,
dateTemplate,
promo,
});
}
Expand Down
73 changes: 60 additions & 13 deletions app/src/api/scaleTeam/scaleTeam.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
findAllAndLean,
type QueryArgs,
} from 'src/database/mongoose/database.mongoose.query';
import type { DateRange } from 'src/dateRange/dtos/dateRange.dto';
import { EvalLogSortOrder } from 'src/page/evalLog/dtos/evalLog.dto.getEvalLog';
import type { EvalLog } from 'src/page/evalLog/models/evalLog.model';
import { CursusUserService } from '../cursusUser/cursusUser.service';
Expand All @@ -18,7 +19,10 @@ import {
conditionalProjectPreview,
} from '../project/db/project.database.aggregate';
import { addUserPreview, lookupUser } from '../user/db/user.database.aggregate';
import { lookupScaleTeams } from './db/scaleTeam.database.aggregate';
import {
evalCountDateRangeFilter,
lookupScaleTeams,
} from './db/scaleTeam.database.aggregate';
import { scale_team } from './db/scaleTeam.database.schema';

export const OUTSTANDING_FLAG_ID = 9;
Expand Down Expand Up @@ -112,11 +116,13 @@ export class ScaleTeamService {
return reviewAggr?.value ?? 0;
}

async averageReviewLengthRanking(
async averageReviewLengthRankingByDateRange(
field: 'comment' | 'feedback',
filter?: FilterQuery<scale_team>,
dateRange?: DateRange,
): Promise<UserRank[]> {
const aggregate = this.cursusUserService.aggregate<UserRank>();
const aggregate = this.cursusUserService.aggregate<
Omit<UserRank, 'rank'> & { count: number }
>();

const fieldMap = {
comment: 'corrector',
Expand All @@ -125,18 +131,19 @@ export class ScaleTeamService {

const target = fieldMap[field];

return await aggregate
const scaleTeamFilter = {
[field]: { $ne: null },
...(dateRange ? evalCountDateRangeFilter(dateRange) : undefined),
};

const rawRanking = await aggregate
.append(
lookupScaleTeams('user.id', `${target}.id`, [
{
$match: {
...filter,
[`${field}`]: { $ne: null },
},
},
{ $match: scaleTeamFilter },
{
$group: {
_id: 'result',
count: { $count: {} },
value: { $avg: { $strLenCP: `$${field}` } },
},
},
Expand All @@ -147,14 +154,54 @@ export class ScaleTeamService {
$ifNull: [{ $round: { $first: '$scale_teams.value' } }, 0],
},
})
.append(addRank())
.sort({ value: -1 })
.append(addUserPreview('user'))
.project({
_id: 0,
userPreview: 1,
value: 1,
rank: 1,
count: { $first: '$scale_teams.count' },
});

const { ranking, zeroValueRanking } = rawRanking.reduce(
(
{ ranking, prevRank, prevValue, zeroValueRanking },
{ userPreview, value, count },
) => {
if (dateRange || count >= 20) {
const rank = prevValue === value ? prevRank : ranking.length + 1;

ranking.push({
userPreview,
value,
rank,
});

return {
ranking,
prevRank: rank,
prevValue: value,
zeroValueRanking,
};
}

zeroValueRanking.push({
userPreview,
value: 0,
rank: Number.MAX_SAFE_INTEGER,
});

return { ranking, prevRank, prevValue, zeroValueRanking };
},
{
ranking: new Array<UserRank>(),
prevRank: 0,
prevValue: Number.MIN_SAFE_INTEGER,
zeroValueRanking: new Array<UserRank>(),
},
);

return [...ranking, ...zeroValueRanking];
}

/**
Expand Down
35 changes: 31 additions & 4 deletions app/src/lambda/lambda.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -190,17 +190,44 @@ export class LambdaService {
DateTemplate.CURR_WEEK,
);

const commentRank = await this.scaleTeamService.averageReviewLengthRanking(
'comment',
);
const totalCommentRanking =
await this.scaleTeamService.averageReviewLengthRankingByDateRange(
'comment',
);

await this.cacheUtilRankingService.setRanking(
commentRank,
totalCommentRanking,
updatedAt,
COMMENT_RANKING,
DateTemplate.TOTAL,
);

const currMonthCommentRanking =
await this.scaleTeamService.averageReviewLengthRankingByDateRange(
'comment',
currMonth,
);

await this.cacheUtilRankingService.setRanking(
currMonthCommentRanking,
updatedAt,
COMMENT_RANKING,
DateTemplate.CURR_MONTH,
);

const currWeekCommentRanking =
await this.scaleTeamService.averageReviewLengthRankingByDateRange(
'comment',
currWeek,
);

await this.cacheUtilRankingService.setRanking(
currWeekCommentRanking,
updatedAt,
COMMENT_RANKING,
DateTemplate.CURR_WEEK,
);

const totalLog = await this.locationService.logtimeRanking(total);

await this.cacheUtilRankingService.setRanking(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,13 @@ export class LeaderboardCommentResolver {
@Args() { pageNumber, pageSize, promo }: GetLeaderboardElementArgs,
@Args() { dateTemplate }: DateTemplateArgs,
): Promise<LeaderboardElementDateRanged> {
if (dateTemplate !== DateTemplate.TOTAL) {
if (
!(
dateTemplate === DateTemplate.TOTAL ||
dateTemplate === DateTemplate.CURR_MONTH ||
dateTemplate === DateTemplate.CURR_WEEK
)
) {
throw new UnsupportedDateTemplate();
}

Expand Down
20 changes: 15 additions & 5 deletions app/src/page/leaderboard/comment/leaderboard.comment.service.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { Injectable } from '@nestjs/common';
import { ScaleTeamCacheService } from 'src/api/scaleTeam/scaleTeam.cache.service';
import {
AverageReviewLengthRankingSupportedDateTemplate,
ScaleTeamCacheService,
} from 'src/api/scaleTeam/scaleTeam.cache.service';
import { assertExist } from 'src/common/assertExist';
import { DateTemplate } from 'src/dateRange/dtos/dateRange.dto';
import { LeaderboardElementDateRanged } from '../common/models/leaderboard.model';
import type { RankingByDateTemplateArgs } from '../common/types/leaderboard.rankingByDateTemplateArgs';
import { LeaderboardUtilService } from '../util/leaderboard.util.service';
Expand All @@ -18,9 +20,17 @@ export class LeaderboardCommentService {
userId,
paginationIndexArgs,
promo,
}: RankingByDateTemplateArgs<DateTemplate.TOTAL>): Promise<LeaderboardElementDateRanged> {
const rank = await this.scaleTeamCacheService.getCommentRank(userId, promo);
const ranking = await this.scaleTeamCacheService.getCommentRanking(promo);
}: RankingByDateTemplateArgs<AverageReviewLengthRankingSupportedDateTemplate>): Promise<LeaderboardElementDateRanged> {
const rank = await this.scaleTeamCacheService.getCommentRank(
dateTemplate,
userId,
promo,
);

const ranking = await this.scaleTeamCacheService.getCommentRanking(
dateTemplate,
promo,
);

assertExist(ranking);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ import { LeaderboardElementDateRanged } from '../../common/models/leaderboard.mo

@ObjectType()
export class LeaderboardComment {
@Field({ description: 'TOTAL 만 가능합니다' })
@Field({ description: 'TOTAL, CURR_MONTH, CURR_WEEK 만 가능합니다' })
byDateTemplate: LeaderboardElementDateRanged;
}
2 changes: 1 addition & 1 deletion app/src/schema.gql
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ type LeaderboardElementDateRanged {
}

type LeaderboardComment {
"""TOTAL 만 가능합니다"""
"""TOTAL, CURR_MONTH, CURR_WEEK 만 가능합니다"""
byDateTemplate(pageSize: Int! = 10, pageNumber: Int! = 1, promo: Int, dateTemplate: DateTemplate!): LeaderboardElementDateRanged!
}

Expand Down

0 comments on commit 9aac3d5

Please sign in to comment.