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): implement contest participant standings #1233

Merged
merged 17 commits into from
Jan 25, 2024
Merged
Show file tree
Hide file tree
Changes from 8 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
33 changes: 30 additions & 3 deletions backend/apps/client/src/contest/contest.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,29 @@ const record: ContestRecord = {
createTime: new Date(),
updateTime: new Date()
}
const sortedContestRecordsWithUserDetail = [
{
user: {
id: 13,
username: 'user10'
},
acceptedProblemNum: 13
},
{
user: {
id: 12,
username: 'user09'
},
acceptedProblemNum: 12
},
{
user: {
id: 11,
username: 'user08'
},
acceptedProblemNum: 11
}
]

const mockPrismaService = {
contest: {
Expand Down Expand Up @@ -330,10 +353,14 @@ describe('ContestService', () => {

it('should return contest', async () => {
mockPrismaService.contest.findUniqueOrThrow.resolves(contestDetail)

expect(await service.getContest(groupId, contestId)).to.deep.equal(
contestDetail
mockPrismaService.contestRecord.findMany.resolves(
sortedContestRecordsWithUserDetail
)

expect(await service.getContest(groupId, contestId)).to.deep.equal({
...contestDetail,
rankings: sortedContestRecordsWithUserDetail
})
})
})

Expand Down
30 changes: 25 additions & 5 deletions backend/apps/client/src/contest/contest.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -214,10 +214,7 @@ export class ContestService {
return upcomingContest
}

async getContest(
id: number,
groupId = OPEN_SPACE_ID
): Promise<Partial<Contest>> {
async getContest(id: number, groupId = OPEN_SPACE_ID) {
const contest = await this.prisma.contest.findUniqueOrThrow({
where: {
id,
Expand All @@ -232,8 +229,31 @@ export class ContestService {
description: true
}
})
// get contest participants ranking using ContestRecord
const sortedContestRecordsWithUserDetail =
await this.prisma.contestRecord.findMany({
where: {
contestId: id
},
select: {
user: {
select: {
id: true,
username: true
}
},
acceptedProblemNum: true
},
orderBy: {
acceptedProblemNum: 'desc'
}
})

return contest
// combine contest and sortedContestRecordsWithUserDetail
return {
...contest,
rankings: sortedContestRecordsWithUserDetail
}
}

async createContestRecord(
Expand Down
28 changes: 27 additions & 1 deletion backend/prisma/seed.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {

Check warning on line 1 in backend/prisma/seed.ts

View workflow job for this annotation

GitHub Actions / Lint

Import "ContestRecord" is only used as types
PrismaClient,
Role,
Level,
Expand All @@ -13,7 +13,8 @@
type Submission,
type ProblemTestcase,
type Announcement,
type CodeDraft
type CodeDraft,
ContestRecord
} from '@prisma/client'
import { hash } from 'argon2'
import { readFile } from 'fs/promises'
Expand Down Expand Up @@ -1562,6 +1563,30 @@
return codeDrafts
}

const createContestRecords = async () => {
const contestRecords: ContestRecord[] = []

// group 1 users
const group1Users = await prisma.userGroup.findMany({
where: {
groupId: 1
}
})
for (const user of group1Users) {
const contestRecord = await prisma.contestRecord.create({
data: {
userId: user.userId,
contestId: 1,
acceptedProblemNum: user.userId,
totalPenalty: 0
}
})
contestRecords.push(contestRecord)
}

return contestRecords
}

const main = async () => {
await createUsers()
await createGroups()
Expand All @@ -1572,6 +1597,7 @@
await createSubmissions()
await createAnnouncements()
await createCodeDrafts()
await createContestRecords()
}

main()
Expand Down
13 changes: 8 additions & 5 deletions collection/client/Contest/Get contest by ID/Succeed.bru
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ meta {
}

get {
url: {{baseUrl}}/contest/13
url: {{baseUrl}}/contest/5?groupId=2
body: none
auth: none
}
Expand All @@ -24,15 +24,18 @@ assert {
res("group.groupName"): isString
res("description"): isString
res("_count.contestRecord"): isNumber
res("rankings[0].user.id"): isNumber
res("rankings[0].user.username"): isString
res("rankings[0].acceptedProblemNum"): isNumber
}

docs {
# Get Contest by ID
하나의 대회 정보를 가져옵니다.

하나의 대회 정보와 Contest 참여자 정보를 가져옵니다.

## Query

| 이름 | 타입 | 설명 |
|-----|-----|-----|
|groupId|Integer|대회가 속한 Group ID|
Expand Down