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(be): apply sorting on admin get-contest-submissions api #2183

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export enum ContestSubmissionOrder {
studentIdASC = 'studentId-asc',
studentIdDESC = 'studentId-desc',
realNameASC = 'realName-asc',
realNameDESC = 'realName-desc',
usernameASC = 'username-asc',
usernameDESC = 'username-desc'
}
30 changes: 16 additions & 14 deletions apps/backend/apps/admin/src/submission/submission.resolver.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
import { InternalServerErrorException, Logger } from '@nestjs/common'
import { Args, Int, Query, Resolver } from '@nestjs/graphql'
import { CursorValidationPipe } from '@libs/pipe'
import { ContestSubmissionOrderPipe, CursorValidationPipe } from '@libs/pipe'
import { Submission } from '@admin/@generated'
import { ContestSubmissionOrder } from './enum/contest-submission-order.enum'
import { ContestSubmission } from './model/contest-submission.model'
import { GetContestSubmissionsInput } from './model/get-contest-submission.input'
import { SubmissionDetail } from './model/submission-detail.output'
import { SubmissionService } from './submission.service'

@Resolver(() => Submission)
export class SubmissionResolver {
private readonly logger = new Logger(SubmissionResolver.name)
constructor(private readonly submissionService: SubmissionService) {}

/**
Expand All @@ -28,19 +27,22 @@ export class SubmissionResolver {
@Args('cursor', { nullable: true, type: () => Int }, CursorValidationPipe)
cursor: number | null,
@Args('take', { nullable: true, defaultValue: 10, type: () => Int })
take: number
take: number,
@Args(
'order',
{ nullable: true, type: () => String },
ContestSubmissionOrderPipe
)
order: ContestSubmissionOrder | null
): Promise<ContestSubmission[]> {
try {
return await this.submissionService.getContestSubmissions(
input,
take,
cursor
)
} catch (error) {
this.logger.error(error.error)
throw new InternalServerErrorException()
}
return await this.submissionService.getContestSubmissions(
input,
take,
cursor,
order
)
}

/**
* 특정 Contest의 특정 제출 내역에 대한 상세 정보를 불러옵니다.
*/
Expand Down
35 changes: 33 additions & 2 deletions apps/backend/apps/admin/src/submission/submission.service.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { Injectable } from '@nestjs/common'
import type { Prisma } from '@prisma/client'
import { plainToInstance } from 'class-transformer'
import { EntityNotExistException } from '@libs/exception'
import { PrismaService } from '@libs/prisma'
import type { Language, ResultStatus } from '@admin/@generated'
import { Snippet } from '@admin/problem/model/template.input'
import { ContestSubmissionOrder } from './enum/contest-submission-order.enum'
import type { GetContestSubmissionsInput } from './model/get-contest-submission.input'

@Injectable()
Expand All @@ -13,7 +15,8 @@ export class SubmissionService {
async getContestSubmissions(
input: GetContestSubmissionsInput,
take: number,
cursor: number | null
cursor: number | null,
order: ContestSubmissionOrder | null
) {
const paginator = this.prisma.getPaginator(cursor)

Expand Down Expand Up @@ -59,7 +62,8 @@ export class SubmissionService {
}
}
}
}
},
orderBy: order ? this.getOrderBy(order) : undefined
})

const results = contestSubmissions.map((c) => {
Expand All @@ -84,6 +88,33 @@ export class SubmissionService {
return results
}

getOrderBy(
order: ContestSubmissionOrder
): Prisma.SubmissionOrderByWithRelationInput {
const [attr, value] = order.split('-')

switch (order) {
case ContestSubmissionOrder.studentIdASC:
case ContestSubmissionOrder.studentIdDESC:
case ContestSubmissionOrder.usernameASC:
case ContestSubmissionOrder.usernameDESC:
return {
user: {
[attr]: value
}
}
case ContestSubmissionOrder.realNameASC:
case ContestSubmissionOrder.realNameDESC:
return {
user: {
userProfile: {
[attr]: value
}
}
}
}
}

async getSubmission(id: number) {
const submission = await this.prisma.submission.findFirst({
where: {
Expand Down
24 changes: 24 additions & 0 deletions apps/backend/libs/pipe/src/contest-submission-order.pipe.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import {
BadRequestException,
Injectable,
type PipeTransform
} from '@nestjs/common'
import { ContestSubmissionOrder } from '@admin/submission/enum/contest-submission-order.enum'

@Injectable()
export class ContestSubmissionOrderPipe implements PipeTransform {
transform(value: unknown) {
if (!value) {
return null
} else if (
!Object.values(ContestSubmissionOrder).includes(
value as ContestSubmissionOrder
)
) {
throw new BadRequestException(
'Contest-submission-order validation failed'
)
}
return value
}
}
1 change: 1 addition & 0 deletions apps/backend/libs/pipe/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ export * from './id-validation.pipe'
export * from './group-id.pipe'
export * from './required-int.pipe'
export * from './problem-order.pipe'
export * from './contest-submission-order.pipe'
23 changes: 17 additions & 6 deletions collection/admin/Submission/Get Contest Submissions/Succeed.bru
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,14 @@ body:graphql {
query GetContestSubmissions(
$input: GetContestSubmissionsInput!,
$cursor: Int,
$take: Int
$take: Int,
$order: String
) {
getContestSubmissions(
input: $input,
cursor: $cursor,
take: $take
take: $take,
order: $order
) {
title
studentId
Expand All @@ -44,7 +46,8 @@ body:graphql:vars {
"problemId": 1,
"searchingName": "lee"
},
"take": 10
"take": 10,
"order": "username-desc"
}
}

Expand All @@ -55,13 +58,21 @@ docs {
- https://github.com/skkuding/codedang/pull/1924

#### 필요 인자
| `input` | `take` | `cursor` |
|----------|--------|----------|
| 밑에서 설명 | Pagination 구현을 위함 | Pagination 구현을 위함 |
| `input` | `take` | `cursor` |`order`|
|----------|--------|----------|--------|
| 밑에서 설명 | Pagination 구현을 위함 | Pagination 구현을 위함 | 정렬 |

`input`
- `contestId`: 제출 내역을 불러올 Contest의 ID
- `problemId?`: 제출된 내역 중 특정 Problem의 제출만 필터링
- `searchingName?`: 필터링할 User의 realName(없으면 모든 유저)

`order`
- `studentId-asc`: 학번 오름차순 정렬
- `studentId-desc`: 학번 내림차순 정렬
- `realName-asc`: 학생이름 오름차순 정렬
- `realName-desc`: 학생이름 내림차순 정렬
- `username-asc`: username 오름차순 정렬
- `username-desc`: username 내림차순 정렬

}