Skip to content

Commit

Permalink
feat: ✨ user team info 추가
Browse files Browse the repository at this point in the history
- close #138
  • Loading branch information
jpham005 committed Jun 9, 2023
1 parent 76479de commit b7e651d
Show file tree
Hide file tree
Showing 9 changed files with 192 additions and 70 deletions.
26 changes: 26 additions & 0 deletions app/src/api/project/db/project.database.aggregate.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import {
CollectionLookup,
lookupStage,
} from 'src/common/db/common.db.aggregation';
// eslint-disable-next-line
import type { project } from './project.database.schema';

/**
*
* @description
* projects 를 lookup 합니다.
*
* @returns
* ```ts
* type AddType = {
* projects: project[]
* }
* ```
*
* @see project
*/
export const lookupProjects: CollectionLookup = (
localField,
foreignField,
pipeline,
) => lookupStage('projects', localField, foreignField, pipeline);
7 changes: 7 additions & 0 deletions app/src/api/project/project.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@ import { FilterQuery, Model } from 'mongoose';
import { project } from './db/project.database.schema';
import { ProjectPreview } from './models/project.preview';

export const NETWHAT_PREVIEW: ProjectPreview = {
id: 1318,
name: 'netwhat',
url: 'https://api.intra.42.fr/v2/projects/1318',
};

// todo: refactor all
@Injectable()
export class ProjectService {
constructor(
Expand Down
8 changes: 6 additions & 2 deletions app/src/api/team/db/team.database.schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,12 @@ export class TeamBase {
@Prop({ required: true })
users: TeamUser[];

@Prop({ required: true })
status: string;
@Prop({ required: true, type: String })
status:
| 'creating_group'
| 'finished'
| 'in_progress'
| 'waiting_for_correction';

@Prop()
terminatingAt?: Date;
Expand Down
1 change: 1 addition & 0 deletions app/src/api/team/team.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ import { TeamService } from './team.service';
providers: [TeamService],
exports: [MongooseModule, TeamService],
})
// eslint-disable-next-line
export class TeamModule {}
101 changes: 94 additions & 7 deletions app/src/api/team/team.service.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
import { Inject, Injectable } from '@nestjs/common';
import { Injectable } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import type { FilterQuery, Model } from 'mongoose';
import type { AggrNumeric } from 'src/common/db/common.db.aggregation';
import {
TeamStatus,
UserTeam,
} from 'src/page/personal/general/models/personal.general.model';
import { lookupProjects } from '../project/db/project.database.aggregate';
import { NETWHAT_PREVIEW } from '../project/project.service';
import { team } from './db/team.database.schema';
import { FilterQuery, Model } from 'mongoose';
import { AggrNumeric } from 'src/common/db/common.db.aggregation';

@Injectable()
export class TeamService {
constructor(
@Inject(team.name)
@InjectModel(team.name)
private teamModel: Model<team>,
) {}

Expand All @@ -18,21 +25,88 @@ export class TeamService {
return await this.teamModel.countDocuments(filter);
}

async userTeams(
userId: number,
): Promise<(UserTeam & Pick<team, 'createdAt'>)[]> {
const aggregate = this.teamModel.aggregate<
Omit<UserTeam, 'status'> & Pick<team, 'status' | 'createdAt'>
>();

const teamsAggr = await aggregate
.match({ 'users.id': userId })
.append(lookupProjects('projectId', 'id'))
.addFields({
users: {
$filter: {
input: '$users',
as: 'user',
cond: { $eq: ['$$user.id', userId] },
},
},
projects: { $first: '$projects' },
})
.project({
_id: 0,
id: 1,
name: 1,
occurrence: { $first: '$users.occurrence' },
projectPreview: {
id: '$projects.id',
name: '$projects.name',
// todo: project 꺼 사용
url: {
$concat: [
'https://api.intra.42.fr/v2/projects/',
{ $toString: '$projectId' },
],
},
},
status: 1,
lastEventTime: {
$max: [
'$createdAt',
'$lockedAt',
'$closedAt',
{
$cond: [
{ $eq: ['$status', 'finished'] },
{ $max: '$scaleTeams.filledAt' },
null,
],
},
{ $max: '$teamsUploads.createdAt' },
],
},
isValidated: '$validated?',
finalMark: 1,
createdAt: 1,
})
.sort({ lastEventTime: 1 });

return teamsAggr.map((team) => ({
...team,
projectPreview: team.projectPreview.id
? team.projectPreview
: NETWHAT_PREVIEW,
status: convertStauts(team.status),
}));
}

/**
*
* @return number[] 0번째에 pass, 1번째에 fail 숫자를 담은 배열을 반환합니다.
*/
async teamResult(filter?: FilterQuery<team>): Promise<[number, number]> {
const aggregate = this.teamModel.aggregate<
{ _id: 'true' | 'false' } & AggrNumeric
{ _id: boolean } & AggrNumeric
>();

const teamResultAggr = await aggregate
.match({ ...filter, status: 'finished' })
.group({ _id: '$validated?', value: { $count: {} } });

const pass = teamResultAggr.find(({ _id }) => _id === 'true')?.value ?? 0;
const fail = teamResultAggr.find(({ _id }) => _id === 'false')?.value ?? 0;
const pass = teamResultAggr.find(({ _id }) => _id === true)?.value ?? 0;
const fail = teamResultAggr.find(({ _id }) => _id === false)?.value ?? 0;

return [pass, fail];
}
Expand Down Expand Up @@ -67,3 +141,16 @@ export class TeamService {
.project({ _id: 0, userId: '$_id', value: 1 });
}
}

const convertStauts = (status: team['status']): TeamStatus => {
switch (status) {
case 'creating_group':
return TeamStatus.REGISTERED;
case 'in_progress':
return TeamStatus.IN_PROGRESS;
case 'waiting_for_correction':
return TeamStatus.WAITING_FOR_CORRECTION;
case 'finished':
return TeamStatus.FINISHED;
}
};
47 changes: 24 additions & 23 deletions app/src/page/personal/general/models/personal.general.model.ts
Original file line number Diff line number Diff line change
@@ -1,42 +1,43 @@
import { Field, Float, ObjectType } from '@nestjs/graphql';
import { Field, Float, ObjectType, registerEnumType } from '@nestjs/graphql';
import { ProjectPreview } from 'src/api/project/models/project.preview';
import { IntDateRanged } from 'src/common/models/common.dateRanaged.model';
import { DateRanged } from 'src/dateRange/models/dateRange.model';
import { UserProfile } from './personal.general.userProfile.model';

export enum TeamStatus {
REGISTERED,
IN_PROGRESS,
WAITING_FOR_CORRECTION,
FINISHED,
}

registerEnumType(TeamStatus, { name: 'TeamStatus' });

@ObjectType()
export class TempTeam {
export class UserTeam {
@Field()
id: number;

@Field()
teamName: string;

@Field() //todo: projectId 를 통해 구하기
projectName: string;
name: string;

@Field()
occurrence: number;

@Field()
finalMark?: number;

@Field({ description: '레지스터' })
createdAt: Date;
projectPreview: ProjectPreview;

@Field({ description: '팀 빌딩' })
lockedAt?: Date;

@Field({ description: '제출' })
closedAt?: Date;
@Field((_type) => TeamStatus)
status: TeamStatus;

@Field()
isValidated?: boolean;
lastEventTime: Date;

@Field({ description: '평가완료날' }) //todo: teamsUploads.createdAt
finishedAt?: Date;
@Field({ nullable: true })
isValidated?: boolean;

@Field({ description: '상태: 팀빌딩, 진행중, 평가중, 완료' })
status: string;
@Field({ nullable: true })
finalMark?: number;
}

@ObjectType()
Expand Down Expand Up @@ -75,10 +76,10 @@ export class TeamInfo {
lastRegistered?: string;

@Field({ nullable: true })
lastPass?: string;
lastPassed?: string;

@Field((_type) => [TempTeam], { nullable: 'items' })
teams: TempTeam[];
@Field((_type) => [UserTeam], { nullable: 'items' })
teams: UserTeam[];
}

@ObjectType()
Expand Down
4 changes: 4 additions & 0 deletions app/src/page/personal/general/personal.general.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import { CursusUserService } from 'src/api/cursusUser/cursusUser.service';
import { LocationModule } from 'src/api/location/location.module';
import { ScoreModule } from 'src/api/score/score.module';
import { ScoreService } from 'src/api/score/score.service';
import { TeamModule } from 'src/api/team/team.module';
import { TeamService } from 'src/api/team/team.service';
import { DateRangeModule } from 'src/dateRange/dateRange.module';
import { DateRangeService } from 'src/dateRange/dateRange.service';
import { PersonalUtilModule } from '../util/personal.util.module';
Expand All @@ -17,6 +19,7 @@ import { PersonalGeneralService } from './personal.general.service';
ScoreModule,
CursusUserModule,
LocationModule,
TeamModule,
DateRangeModule,
],
providers: [
Expand All @@ -25,6 +28,7 @@ import { PersonalGeneralService } from './personal.general.service';
PersonalUtilService,
ScoreService,
CursusUserService,
TeamService,
DateRangeService,
],
})
Expand Down
32 changes: 15 additions & 17 deletions app/src/page/personal/general/personal.general.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { CursusUserService } from 'src/api/cursusUser/cursusUser.service';
import type { location } from 'src/api/location/db/location.database.schema';
import { LocationService } from 'src/api/location/location.service';
import { ScoreService } from 'src/api/score/score.service';
import { TeamService } from 'src/api/team/team.service';
import type { IntDateRanged } from 'src/common/models/common.dateRanaged.model';
import { DateRangeService } from 'src/dateRange/dateRange.service';
import type { DateRange, DateTemplate } from 'src/dateRange/dtos/dateRange.dto';
Expand All @@ -25,6 +26,7 @@ export class PersonalGeneralService {
private cursusUserService: CursusUserService,
private locationService: LocationService,
private scoreService: ScoreService,
private teamService: TeamService,
private dateRangeService: DateRangeService,
) {}

Expand Down Expand Up @@ -177,24 +179,20 @@ export class PersonalGeneralService {
}

async teamInfo(userId: number): Promise<TeamInfo> {
const userTeams = await this.teamService.userTeams(userId);

const lastRegistered = userTeams
.sort((a, b) => a.createdAt.getTime() - b.createdAt.getTime())
.at(-1)?.projectPreview.name;

const lastPassed = userTeams
.filter((team) => team.isValidated === true)
.at(-1)?.projectPreview.name;

return {
lastRegistered: 'avaj-launcher',
lastPass: 'avaj-launcher',
teams: [
{
id: 2966047,
projectName: 'avaj-launcher',
teamName: `jaham's team`,
occurrence: 0,
finalMark: 125,
createdAt: new Date('2022-10-20T04:06:32.437Z'),
lockedAt: new Date('2022-10-20T04:06:32.437Z'),
closedAt: new Date('2022-10-20T16:26:30.317Z'),
isValidated: true,
finishedAt: new Date(),
status: '완료',
},
],
lastRegistered,
lastPassed,
teams: userTeams,
};
}

Expand Down
Loading

0 comments on commit b7e651d

Please sign in to comment.