Skip to content

Commit

Permalink
feat(be): implement contest participant standings (#1233)
Browse files Browse the repository at this point in the history
* feat(be): implement participant rank

* chore(be): add contest record seed script

* fix(be): add rankings property when returning

* test(be): add test code for service code

* docs(be): fix bruno api docs

* docs(be): fix bruno api docs

* docs(be): fix bruno api docs

* feat: add score field to contest record table to implement participant standings

* fix: fix seed script

* fix(be): fix service code

* test(be): fix test code

* docs(be): fix bruno api doc

* docs(be): add login script for pre-request script

* docs(be): fix pre request script
  • Loading branch information
gyunseo authored Jan 25, 2024
1 parent c2255d3 commit 77c3334
Show file tree
Hide file tree
Showing 6 changed files with 126 additions and 12 deletions.
40 changes: 37 additions & 3 deletions backend/apps/client/src/contest/contest.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -183,10 +183,37 @@ const record: ContestRecord = {
contestId,
userId,
acceptedProblemNum: 0,
score: 0,
totalPenalty: 0,
createTime: new Date(),
updateTime: new Date()
}
const sortedContestRecordsWithUserDetail = [
{
user: {
id: 13,
username: 'user10'
},
score: 36,
totalPenalty: 720
},
{
user: {
id: 12,
username: 'user09'
},
score: 33,
totalPenalty: 660
},
{
user: {
id: 11,
username: 'user08'
},
score: 30,
totalPenalty: 600
}
]

const mockPrismaService = {
contest: {
Expand Down Expand Up @@ -330,10 +357,17 @@ 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,
standings: sortedContestRecordsWithUserDetail.map((record, index) => ({
...record,
standing: index + 1
}))
})
})
})

Expand Down
42 changes: 37 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,43 @@ 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
}
},
score: true,
totalPenalty: true
},
orderBy: [
{
score: 'desc'
},
{
totalPenalty: 'asc'
}
]
})

return contest
const UsersWithStandingDetail = sortedContestRecordsWithUserDetail.map(
(contestRecord, index) => ({
...contestRecord,
standing: index + 1
})
)
// combine contest and sortedContestRecordsWithUserDetail
return {
...contest,
standings: UsersWithStandingDetail
}
}

async createContestRecord(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE "contest_record" ADD COLUMN "score" INTEGER NOT NULL DEFAULT 0;
1 change: 1 addition & 0 deletions backend/prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,7 @@ model ContestRecord {
user User? @relation(fields: [userId], references: [id], onDelete: SetNull)
userId Int? @map("user_id")
acceptedProblemNum Int @default(0) @map("accepted_problem_num")
score Int @default(0)
totalPenalty Int @default(0) @map("total_penalty")
createTime DateTime @default(now()) @map("create_time")
updateTime DateTime @updatedAt @map("update_time")
Expand Down
33 changes: 32 additions & 1 deletion backend/prisma/seed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ import {
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,35 @@ const createCodeDrafts = async () => {
return codeDrafts
}

const createContestRecords = async () => {
const contestRecords: ContestRecord[] = []
let i = 0
// 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,
// TODO: 아직 점수 계산 로직을 구현하지 않아서,
// 임시로 임의로 좀수와 페널티를 부여하도록 하였습니다.
// 점수 계산 로직을 구현하면 아래의 코드를 수정해주세요.
score: i < 3 ? 3 : i * 3,
totalPenalty: i * 60
}
})
contestRecords.push(contestRecord)
i++
}

return contestRecords
}

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

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

get {
url: {{baseUrl}}/contest/13
url: {{baseUrl}}/contest/1?groupId=1
body: none
auth: none
}

query {
~groupId: 2
groupId: 1
}

assert {
Expand All @@ -24,12 +24,26 @@ assert {
res("group.groupName"): isString
res("description"): isString
res("_count.contestRecord"): isNumber
res("standings[0].user.id"): isNumber
res("standings[0].user.username"): isString
res("standings[0].score"): isNumber
res("standings[0].totalPenalty"): isNumber
res("standings[0].standing"): isNumber
}

script:pre-request {
await require("./login").loginUser(req);
}

docs {
# Get Contest by ID

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

| 이름 | 타입 | 설명 |
|-----|-----|-----|
|id|Integer|Contest(대회) ID|

## Query

Expand Down

0 comments on commit 77c3334

Please sign in to comment.