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 calculate contest participants score #1271

Closed
wants to merge 25 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
2d84670
feat(be): implement participant rank
gyunseo Jan 18, 2024
a1b969b
chore(be): add contest record seed script
gyunseo Jan 18, 2024
96bb369
Merge branch 'main' into 1203-contest-participant-rank
gyunseo Jan 21, 2024
db5262c
fix(be): add rankings property when returning
gyunseo Jan 21, 2024
e7bf92c
test(be): add test code for service code
gyunseo Jan 21, 2024
ef018ee
docs(be): fix bruno api docs
gyunseo Jan 22, 2024
07d9e7c
docs(be): fix bruno api docs
gyunseo Jan 22, 2024
daa1388
Merge branch 'main' into 1203-contest-participant-rank
gyunseo Jan 22, 2024
6a42267
docs(be): fix bruno api docs
gyunseo Jan 22, 2024
b9cc6a7
Merge branch 'main' into 1203-contest-participant-rank
gyunseo Jan 24, 2024
b18310e
feat: add score field to contest record table to implement participan…
gyunseo Jan 24, 2024
3616c04
fix: fix seed script
gyunseo Jan 24, 2024
6efc6fd
fix(be): fix service code
gyunseo Jan 24, 2024
a3ac53c
test(be): fix test code
gyunseo Jan 24, 2024
0f3a202
docs(be): fix bruno api doc
gyunseo Jan 24, 2024
c45771a
docs(be): add login script for pre-request script
gyunseo Jan 24, 2024
8b24f42
docs(be): fix pre request script
gyunseo Jan 24, 2024
2a880b5
fix(be): update seed script
gyunseo Jan 25, 2024
8e1d66e
fix(be): add latest_accepted_time to constest_record and change cpu_t…
gyunseo Jan 29, 2024
cb59bd9
fix: change seed script
gyunseo Jan 29, 2024
9837f4e
feat(be): implement calculate contest participants score
gyunseo Jan 29, 2024
109260a
docs(be): add bruno api docs
gyunseo Jan 29, 2024
063b621
Merge branch 'main' into 1238-calc-contest-participants-score
gyunseo Mar 3, 2024
3c80ce1
Merge branch 'main' into 1238-calc-contest-participants-score
gyunseo Apr 1, 2024
07c0ec7
fix(be): add prisma migration sql script
gyunseo Apr 1, 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
62 changes: 60 additions & 2 deletions apps/backend/apps/client/src/contest/contest.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,54 @@ const contests = [
...ongoingContests,
...finishedContests,
...upcomingContests
] satisfies Partial<ContestResult>[]
] satisfies Partial<ContestSelectResult>[]

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: {
findUnique: stub(),
findUniqueOrThrow: stub(),
findFirst: stub(),
findFirstOrThrow: stub(),
findMany: stub()
},
contestRecord: {
findFirst: stub(),
findMany: stub(),
create: stub()
},
userGroup: {
findFirst: stub(),
findMany: stub()
},
getPaginator: PrismaService.prototype.getPaginator
}

describe('ContestService', () => {
let service: ContestService
Expand Down Expand Up @@ -296,7 +343,18 @@ describe('ContestService', () => {
})

it('should return contest', async () => {
expect(await service.getContest(contestId, groupId, user01Id)).to.be.ok
mockPrismaService.contest.findUniqueOrThrow.resolves(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
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export const submissionResults: SubmissionResult[] = [
result: ResultStatus.Accepted,
submissionId: 1,
updateTime: new Date('2023-01-01'),
cpuTime: BigInt(12345),
cpuTime: Number(12345),
memoryUsage: 12345
},
{
Expand All @@ -19,7 +19,7 @@ export const submissionResults: SubmissionResult[] = [
result: ResultStatus.Accepted,
submissionId: 2,
updateTime: new Date('2023-01-01'),
cpuTime: BigInt(12345),
cpuTime: Number(12345),
memoryUsage: 12345
},
{
Expand All @@ -29,7 +29,7 @@ export const submissionResults: SubmissionResult[] = [
result: ResultStatus.WrongAnswer,
submissionId: 1,
updateTime: new Date('2023-01-01'),
cpuTime: BigInt(12345),
cpuTime: Number(12345),
memoryUsage: 12345
},
{
Expand All @@ -39,7 +39,7 @@ export const submissionResults: SubmissionResult[] = [
result: ResultStatus.CompileError,
submissionId: 1,
updateTime: new Date('2023-01-01'),
cpuTime: BigInt(12345),
cpuTime: Number(12345),
memoryUsage: 12345
}
]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/*
Warnings:

- You are about to alter the column `cpu_time` on the `submission_result` table. The data in that column could be lost. The data in that column will be cast from `BigInt` to `Integer`.

*/
-- AlterTable
ALTER TABLE "contest_record" ADD COLUMN "latest_accepted_time" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP;

-- AlterTable
ALTER TABLE "submission_result" ALTER COLUMN "cpu_time" SET DATA TYPE INTEGER;
5 changes: 4 additions & 1 deletion apps/backend/prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,9 @@ model ContestRecord {
userId Int? @map("user_id")
acceptedProblemNum Int @default(0) @map("accepted_problem_num")
score Int @default(0)
// FIXME: latestAcceptedTime(최근 정답 제출 시간)의 default 값을 now()로 설정했습니다.
// 구현 로직에 따라 추후 수정이 필요할 수 있습니다.
latestAcceptedTime DateTime @default(now()) @map("latest_accepted_time")
totalPenalty Int @default(0) @map("total_penalty")
createTime DateTime @default(now()) @map("create_time")
updateTime DateTime @updatedAt @map("update_time")
Expand Down Expand Up @@ -395,7 +398,7 @@ model SubmissionResult {
problemTestcase ProblemTestcase @relation(fields: [problemTestcaseId], references: [id], onDelete: Cascade)
problemTestcaseId Int @map("problem_test_case_id")
result ResultStatus
cpuTime BigInt @map("cpu_time")
cpuTime Int @map("cpu_time")
memoryUsage Int @map("memory_usage")
createTime DateTime @default(now()) @map("create_time")
updateTime DateTime @updatedAt @map("update_time")
Expand Down
1 change: 1 addition & 0 deletions apps/backend/prisma/seed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1244,6 +1244,7 @@ const createContests = async () => {
data: {
order: problem.id - 1,
contestId: ongoingContests[0].id,
score: problem.id + 3,
problemId: problem.id
}
})
Expand Down
5 changes: 4 additions & 1 deletion collection/client/Contest/Get contest by ID/Succeed.bru
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ assert {
}

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

docs {
Expand All @@ -37,6 +37,9 @@ docs {
하나의 대회 정보와 Contest 참여자 정보, 로그인한 유저가 해당 Contest에 참여가능한지 여부에 대한 정보를 가져옵니다. (로그인 하지 않은 유저는 Open Space의 Contest 정보만 볼 수 있고, `isRegistered`는 항상 `false`)
### Path

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

| 이름 | 타입 | 설명 |
|-----|-----|-----|
|id|Integer|Contest(대회) ID|
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
meta {
name: 409: You already got AC for this problem
type: http
seq: 1
}

post {
url: {{baseUrl}}/submission?problemId=1&groupId=1&contestId=1
body: json
auth: none
}

query {
problemId: 1
groupId: 1
contestId: 1
~workbookId: 1
}

body:json {
{
"code": [
{
"id": 1,
"text": "#include <stdio.h>\nint main() { int a, b; scanf(\"%d%d\", &a, &b); printf(\"%d\\n\", a + b);}",
"locked": false
}
],
"language": "C"
}
}

assert {
res.status: eq 409
res.body.message: eq You already got AC for this problem
res.body.error: eq Conflict
res.body.statusCode: eq 409
}

script:pre-request {
await require("./login").loginUser(req);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
meta {
name: 422: Required Query Missing
type: http
seq: 1
}

post {
url: {{baseUrl}}/submission
body: json
auth: none
}

query {
~problemId:
~groupId: 1
~workbookId: 1
~contestId: 1
}

body:json {
{
"code": [
{
"id": 1,
"text": "#include <stdio.h>\nint main() { int a, b; scanf(\"%d%d\", &a, &b); printf(\"%d\\n\", a + b);}",
"locked": false
}
],
"language": "C"
}
}

assert {
res.status: eq 422
res.body.message: eq Required query is missing: problemId
res.body.error: eq Unprocessable Entity
res.body.statusCode: eq 422
}

script:pre-request {
await require("./login").loginUser(req);
}
43 changes: 33 additions & 10 deletions collection/client/Submission/Create Submission/Succeed.bru
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@ meta {
}

post {
url: {{baseUrl}}/submission?problemId=1
url: {{baseUrl}}/submission?problemId=1&groupId=1&contestId=1
body: json
auth: none
}

query {
problemId: 1
~groupId: 1
~contestId: 1
groupId: 1
contestId: 1
~workbookId: 1
}

Expand All @@ -30,24 +30,47 @@ body:json {
}
}

assert {
res.status: eq 201
res.body.id: isNumber
res.body.userId: isNumber
res.body.problemId: isNumber
res.body.language: isString
res.body.result: isString
res.body.createTime: isString
res.body.updateTime: isString
res.body.code[0].id: isNumber
res.body.code[0].text: isString
res.body.code[0].locked: isBoolean
}

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

docs {
# Create Submission
## Create Submission

코드를 제출하여 채점 요청을 보냅니다.
## Query

### Query

> 필수 query는 * 표시하였습니다.

| 이름 | 타입 | 설명 |
|-----|-----|-----|
|problemId *|Integer|문제 ID|
|groupId|Integer|문제가 속한 Group ID (default: 1)|
|contestId|Integer|문제가 속한 대회 ID|
|workbookId|Integer|문제가 속한 문제집 ID|


### Error Case

#### 422: Required query is missing: problemId

query parameter인 problemId가 없습니다.

#### 409: You already got AC for this problem

이미 같은 문제로 AC를 받은 경우, 재제출을 할 수가 없습니다.
}
Loading
Loading