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

refactor(be): admin problem and submission exception handling #2130

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
85 commits
Select commit Hold shift + click to select a range
ce3eb88
refactor(be): improve admin problem module error handling
mnseok Sep 30, 2024
1b503bd
refactor(be): improve admin submission module error handling
mnseok Sep 30, 2024
94a24d0
refactor(be): improve admin problem module error handling in excluded…
mnseok Sep 30, 2024
aa72481
fix(fe): prevent horizontal scrollbar from appearing (#2097)
eunnbi Sep 19, 2024
b578c0e
fix(be): add image url for production env (#2101)
Jaehyeon1020 Sep 20, 2024
7c89f7c
refactor(fe): admin problem create page refactoring (#2100)
eunnbi Sep 20, 2024
c196b16
fix(be): add condition for compile-error when run test (#2102)
Jaehyeon1020 Sep 20, 2024
921e9cf
fix(fe): block testcase and limit edit when submission exist (#2084)
Kohminchae Sep 22, 2024
c8a5805
feat(be): implement search in contest overall apis (#2088)
Jaehyeon1020 Sep 22, 2024
9ec5b43
fix(infra): remove aws elastic ip for nat gateway (#2113)
bocklag Sep 23, 2024
8b297ad
revert: revert typescript-eslint monorepo from v8 to v7 (#2114)
jimin9038 Sep 23, 2024
fcb2502
refactor(fe): add hide spin button util style (#2109)
B0XERCAT Sep 24, 2024
dbe9918
fix(be): set testcases on cache before publiush message (#2120)
jspark2000 Sep 24, 2024
7512f7e
fix(fe): delete scrollbar (#2116)
jihorobert Sep 25, 2024
7fdaeb6
feat(be): handle prisma exception in global exception filter (#2103)
Jaehyeon1020 Oct 1, 2024
df607ad
refactor(be): improve client submission module error handling logic (…
jimin9038 Oct 1, 2024
bb2be54
refactor(be): improve client problem error handling logic (#2117)
jimin9038 Oct 1, 2024
9365fe9
feat(infra): add lifecycle policy to ecr repositories (#2132)
bocklag Oct 1, 2024
6c13f7c
chore(deps): update codemirror (#2105)
renovate[bot] Oct 1, 2024
53e9edd
fix(deps): update tiptap monorepo to ^2.8.0 (#2106)
renovate[bot] Oct 1, 2024
b30867e
chore(fe): change blind text color from red to neutral (#2131)
B0XERCAT Oct 1, 2024
996819a
refactor(fe): refactor settings page (#2128)
jihorobert Oct 2, 2024
6597996
fix(deps): update all non-major dependencies (#2058)
renovate[bot] Oct 2, 2024
9d25076
chore(deps): lock file maintenance (#2091)
renovate[bot] Oct 2, 2024
52d29c4
fix(deps): update dependency date-fns to v4 (#2110)
renovate[bot] Oct 2, 2024
d44dee9
chore(deps): update dependency @types/express to v5 (#2126)
renovate[bot] Oct 2, 2024
2ff513a
chore(deps): lock file maintenance (#2134)
renovate[bot] Oct 2, 2024
513f962
feat(infra): created gateway vpc endpoint for communication between E…
junhyunlee123 Oct 2, 2024
3751886
fix(fe): allocate more memory to node in devcontainer for smooth fron…
jimin9038 Oct 2, 2024
96004cd
refactor(be): apply global exception filter to admin contest and admi…
Jaehyeon1020 Oct 3, 2024
1f3b16b
feat(iris): pass run output when test submission (#2137)
jspark2000 Oct 4, 2024
2f0762d
fix(fe): fix updateinfo modal (#2129)
juhyeong0505 Oct 4, 2024
ac79773
feat(fe): create submission detail modal (#2104)
jwoojin9 Oct 4, 2024
060b857
refactor(be): refactor client group and admin notice module (#2133)
cho-to Oct 4, 2024
04ae9ad
feat(fe): add code manually save button (#2095)
Kohminchae Oct 5, 2024
05c11e5
feat(fe): implement test in code editor (#2093)
B0XERCAT Oct 6, 2024
60bbeee
fix(fe): show warning when editing contest if submission exists (#2139)
B0XERCAT Oct 6, 2024
d2ef053
chore(deps): lock file maintenance (#2142)
renovate[bot] Oct 7, 2024
33ddbf9
fix(fe): fix scrollbar (#2145)
jihorobert Oct 8, 2024
a4a4fcb
chore(fe): wrap the line of the hint automatically (#2147)
eunnbi Oct 8, 2024
aee2a83
chore(fe): fix admin contest time format (#2146)
jwoojin9 Oct 8, 2024
d3f1492
fix(be): use is-optional (#2149)
Jaehyeon1020 Oct 9, 2024
6b43c88
fix(fe): resolve code disappearing problem after test/submit (#2144)
Kohminchae Oct 9, 2024
ebcebd4
feat(fe): poc - new data table for admin (#2136)
eunnbi Oct 10, 2024
2e4dd44
fix(fe): change language's storekey to include problemId and contestI…
Kohminchae Oct 10, 2024
3fe2567
fix(fe): restore the score of the problems when the new problems are …
eunnbi Oct 10, 2024
4b39136
fix(fe): not show add/delete buttons when testcase cannot be edited (…
eunnbi Oct 11, 2024
18c3e48
fix(fe): fix test bugs (#2148)
B0XERCAT Oct 12, 2024
f157b92
fix(fe): block editing problem when contest has submission (#2158)
B0XERCAT Oct 12, 2024
5c85e18
fix(fe): prevent submission detail modal overflow (#2157)
jwoojin9 Oct 12, 2024
be9eaf5
fix(fe): fix CreateProblem modal (#2156)
Kimhyojung0810 Oct 12, 2024
9ded02d
chore(fe): create signup hover (#2143)
juhyeong0505 Oct 13, 2024
eb959a5
chore(fe): fix updatenow text (#2153)
juhyeong0505 Oct 13, 2024
2f6781e
fix(fe): fix contestdenied message (#2155)
Kimhyojung0810 Oct 13, 2024
39e3bfb
fix(fe): hotfix build error (#2160)
eunnbi Oct 13, 2024
44deed7
fix(fe): restore the imported problem order (#2159)
eunnbi Oct 13, 2024
90b6baa
fix(fe): differentiate toast messages for save and submit actions (#2…
B0XERCAT Oct 13, 2024
6fec43c
chore(fe): edit update information dialog content (#2162)
B0XERCAT Oct 13, 2024
694ff46
fix(fe): fix save button bug (#2163)
jihorobert Oct 13, 2024
d35afe5
feat(infra): created gateway vpc endpoint for communication between E…
junhyunlee123 Oct 14, 2024
c1c8e84
fix(be): no not-found exception in get-score-summaries api (#2167)
Jaehyeon1020 Oct 14, 2024
dc1c378
feat(infra): created gateway vpc endpoint for communication between E…
junhyunlee123 Oct 14, 2024
5ab0220
fix(infra): set portgres version to 14 to avoid downgrade errors and …
bocklag Oct 14, 2024
37d104a
fix(fe): render katex in editor input, output description (#2170)
jimin9038 Oct 16, 2024
7522b80
chore(deps): update all non-major dependencies (#2140)
renovate[bot] Oct 19, 2024
9cd71f8
chore(deps): lock file maintenance (#2166)
renovate[bot] Oct 19, 2024
cf568a6
fix(fe): fix submission take number (#2173)
youznn Oct 23, 2024
d7d2f01
chore(deps): update all non-major dependencies (#2171)
renovate[bot] Oct 26, 2024
e3db67a
chore(deps): update all non-major dependencies (#2174)
renovate[bot] Oct 29, 2024
32d1ec0
fix(deps): update tiptap monorepo to ^2.9.1 (#2175)
renovate[bot] Oct 29, 2024
5610818
refactor(fe): create getResultColor and replace related codes (#2178)
B0XERCAT Nov 1, 2024
866172d
refactor(fe): replace data table admin component to new components (1…
eunnbi Nov 3, 2024
a696c05
refactor(fe): replace data table admin component to new components (2…
eunnbi Nov 3, 2024
6f6b922
fix(deps): update all non-major dependencies (#2180)
renovate[bot] Nov 5, 2024
a731801
chore(deps): lock file maintenance (#2185)
renovate[bot] Nov 6, 2024
6c3ff41
chore(fe): use coolify as stage frontend (#2184)
jimin9038 Nov 6, 2024
9c603d4
refactor(fe): app folder structure refactoring (#2187)
eunnbi Nov 7, 2024
d3cbd37
refactor(be): adm user cli auth exception refator (#2115)
hwantae Nov 8, 2024
5f074ff
fix(be): update redis test key for race condition (#2190)
donghun1214 Nov 8, 2024
5e46e22
refactor(fe): refactor public directory (#2188)
youznn Nov 9, 2024
7b8c762
fix(fe): hotfix params prop type (#2195)
eunnbi Nov 11, 2024
4c13f69
feat(fe): improve editor problems dropdown list ui (#2196)
jwoojin9 Nov 11, 2024
fc5e4eb
refactor(be): remove useless internalserver exception
mnseok Nov 12, 2024
a89e559
refactor(be): remove useless internalserverexceptions
mnseok Nov 12, 2024
e7cdd8d
refactor(be): remove useless internalserverexceptions in admin submis…
mnseok Nov 12, 2024
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
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ jobs:
working-directory: ./apps/iris

- name: Lint (Node.js)
run: git diff --name-only --diff-filter=ACMRUXB origin/main | grep -E "(.ts$|.tsx$|.js$|.jsx$)" | xargs -r pnpm eslint
run: git diff --name-only --diff-filter=ACMRUXB origin/main | grep -E "(.ts$|.tsx$|.js$|.jsx$)" | grep -v 'next.config.js$' | xargs -r pnpm eslint

test-backend:
name: Test Backend
Expand Down
4 changes: 2 additions & 2 deletions apps/backend/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
ARG target=client
ARG app_env=production

FROM node:20.17.0-alpine AS builder
FROM node:20.18.0-alpine AS builder
ARG target

COPY . /build
Expand All @@ -19,7 +19,7 @@ RUN npx prisma generate
RUN npm run build ${target}

### PRODUCTION ###
FROM node:20.17.0-alpine
FROM node:20.18.0-alpine
ARG target
ARG app_env

Expand Down
222 changes: 50 additions & 172 deletions apps/backend/apps/admin/src/contest/contest.resolver.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,8 @@
import {
InternalServerErrorException,
Logger,
NotFoundException,
ParseBoolPipe
} from '@nestjs/common'
import { ParseBoolPipe } from '@nestjs/common'
import { Args, Context, Int, Mutation, Query, Resolver } from '@nestjs/graphql'
import { Contest, ContestProblem } from '@generated'
import { PrismaClientKnownRequestError } from '@prisma/client/runtime/library'
import { AuthenticatedRequest, UseRolesGuard } from '@libs/auth'
import { OPEN_SPACE_ID } from '@libs/constants'
import {
ConflictFoundException,
EntityNotExistException,
UnprocessableDataException
} from '@libs/exception'
import {
CursorValidationPipe,
GroupIDPipe,
Expand All @@ -34,7 +23,6 @@ import { UserContestScoreSummaryWithUserInfo } from './model/score-summary'

@Resolver(() => Contest)
export class ContestResolver {
private readonly logger = new Logger(ContestResolver.name)
constructor(private readonly contestService: ContestService) {}

@Query(() => [ContestWithParticipants])
Expand Down Expand Up @@ -62,16 +50,7 @@ export class ContestResolver {
@Args('contestId', { type: () => Int }, new RequiredIntPipe('contestId'))
contestId: number
) {
try {
return await this.contestService.getContest(contestId)
} catch (error) {
if (
error instanceof PrismaClientKnownRequestError &&
error.code == 'P2025'
) {
throw new NotFoundException(error.message)
}
}
return await this.contestService.getContest(contestId)
}

@Mutation(() => Contest)
Expand All @@ -85,57 +64,23 @@ export class ContestResolver {
groupId: number,
@Context('req') req: AuthenticatedRequest
) {
try {
return await this.contestService.createContest(
groupId,
req.user.id,
input
)
} catch (error) {
if (
error instanceof UnprocessableDataException ||
error instanceof EntityNotExistException
) {
throw error.convert2HTTPException()
}
this.logger.error(error)
throw new InternalServerErrorException()
}
return await this.contestService.createContest(groupId, req.user.id, input)
}

@Mutation(() => Contest)
async updateContest(
@Args('groupId', { type: () => Int }, GroupIDPipe) groupId: number,
@Args('input') input: UpdateContestInput
) {
try {
return await this.contestService.updateContest(groupId, input)
} catch (error) {
if (
error instanceof EntityNotExistException ||
error instanceof UnprocessableDataException
) {
throw error.convert2HTTPException()
}
this.logger.error(error)
throw new InternalServerErrorException()
}
return await this.contestService.updateContest(groupId, input)
}

@Mutation(() => Contest)
async deleteContest(
@Args('groupId', { type: () => Int }, GroupIDPipe) groupId: number,
@Args('contestId', { type: () => Int }) contestId: number
) {
try {
return await this.contestService.deleteContest(groupId, contestId)
} catch (error) {
if (error instanceof EntityNotExistException) {
throw error.convert2HTTPException()
}
this.logger.error(error)
throw new InternalServerErrorException()
}
return await this.contestService.deleteContest(groupId, contestId)
}

@Query(() => [PublicizingRequest])
Expand All @@ -149,21 +94,10 @@ export class ContestResolver {
@Args('groupId', { type: () => Int }, GroupIDPipe) groupId: number,
@Args('contestId', { type: () => Int }) contestId: number
) {
try {
return await this.contestService.createPublicizingRequest(
groupId,
contestId
)
} catch (error) {
if (
error instanceof EntityNotExistException ||
error instanceof ConflictFoundException
) {
throw error.convert2HTTPException()
}
this.logger.error(error)
throw new InternalServerErrorException()
}
return await this.contestService.createPublicizingRequest(
groupId,
contestId
)
}

@Mutation(() => PublicizingResponse)
Expand All @@ -172,18 +106,10 @@ export class ContestResolver {
@Args('contestId', { type: () => Int }) contestId: number,
@Args('isAccepted', ParseBoolPipe) isAccepted: boolean
) {
try {
return await this.contestService.handlePublicizingRequest(
contestId,
isAccepted
)
} catch (error) {
if (error instanceof EntityNotExistException) {
throw error.convert2HTTPException()
}
this.logger.error(error)
throw new InternalServerErrorException()
}
return await this.contestService.handlePublicizingRequest(
contestId,
isAccepted
)
}

@Mutation(() => [ContestProblem])
Expand All @@ -193,22 +119,11 @@ export class ContestResolver {
@Args('problemIdsWithScore', { type: () => [ProblemScoreInput] })
problemIdsWithScore: ProblemScoreInput[]
) {
try {
return await this.contestService.importProblemsToContest(
groupId,
contestId,
problemIdsWithScore
)
} catch (error) {
if (
error instanceof EntityNotExistException ||
error instanceof UnprocessableDataException
) {
throw error.convert2HTTPException()
}
this.logger.error(error)
throw new InternalServerErrorException()
}
return await this.contestService.importProblemsToContest(
groupId,
contestId,
problemIdsWithScore
)
}

@Mutation(() => [ContestProblem])
Expand All @@ -218,22 +133,11 @@ export class ContestResolver {
contestId: number,
@Args('problemIds', { type: () => [Int] }) problemIds: number[]
) {
try {
return await this.contestService.removeProblemsFromContest(
groupId,
contestId,
problemIds
)
} catch (error) {
if (
error instanceof EntityNotExistException ||
error instanceof UnprocessableDataException
) {
throw error.convert2HTTPException()
}
this.logger.error(error)
throw new InternalServerErrorException()
}
return await this.contestService.removeProblemsFromContest(
groupId,
contestId,
problemIds
)
}

/**
Expand All @@ -257,18 +161,13 @@ export class ContestResolver {
@Args('cursor', { nullable: true, type: () => Int }, CursorValidationPipe)
cursor: number | null
) {
try {
return await this.contestService.getContestSubmissionSummaryByUserId(
take,
contestId,
userId,
problemId,
cursor
)
} catch (error) {
this.logger.error(error)
throw new InternalServerErrorException()
}
return await this.contestService.getContestSubmissionSummaryByUserId(
take,
contestId,
userId,
problemId,
cursor
)
}

@Mutation(() => DuplicatedContestResponse)
Expand All @@ -278,22 +177,11 @@ export class ContestResolver {
contestId: number,
@Context('req') req: AuthenticatedRequest
) {
try {
return await this.contestService.duplicateContest(
groupId,
contestId,
req.user.id
)
} catch (error) {
if (
error instanceof UnprocessableDataException ||
error instanceof EntityNotExistException
) {
throw error.convert2HTTPException()
}
this.logger.error(error)
throw new InternalServerErrorException()
}
return await this.contestService.duplicateContest(
groupId,
contestId,
req.user.id
)
}

/**
Expand All @@ -304,37 +192,27 @@ export class ContestResolver {
*/
@Query(() => [UserContestScoreSummaryWithUserInfo])
async getContestScoreSummaries(
@Args('take', { type: () => Int, defaultValue: 10 }) take: number,
@Args('contestId', { type: () => Int }) contestId: number,
@Args('cursor', { type: () => Int, nullable: true }) cursor: number | null
@Args('contestId', { type: () => Int, nullable: false }, IDValidationPipe)
contestId: number,
@Args('take', { type: () => Int, defaultValue: 10 })
take: number,
@Args('cursor', { type: () => Int, nullable: true }, CursorValidationPipe)
cursor: number | null,
@Args('searchingName', { type: () => String, nullable: true })
searchingName?: string
) {
try {
return await this.contestService.getContestScoreSummaries(
take,
contestId,
cursor
)
} catch (error) {
if (error instanceof EntityNotExistException) {
throw error.convert2HTTPException()
}
this.logger.error(error)
throw new InternalServerErrorException()
}
return await this.contestService.getContestScoreSummaries(
contestId,
take,
cursor,
searchingName
)
}

@Query(() => ContestsGroupedByStatus)
async getContestsByProblemId(
@Args('problemId', { type: () => Int }) problemId: number
) {
try {
return await this.contestService.getContestsByProblemId(problemId)
} catch (error) {
if (error instanceof EntityNotExistException) {
throw error.convert2HTTPException()
}
this.logger.error(error)
throw new InternalServerErrorException()
}
return await this.contestService.getContestsByProblemId(problemId)
}
}
Loading
Loading