Skip to content

Commit 7657f7f

Browse files
committed
🐛 Fixed bug that caused updates to fail due to unique constraint violations (#1202)
1 parent cf838a7 commit 7657f7f

File tree

3 files changed

+48
-25
lines changed

3 files changed

+48
-25
lines changed

src/lib/actions/update_task_result.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ export const updateTaskResult = async (
2626

2727
await crud.updateTaskResult(taskId, submissionStatus, userId);
2828
} catch (error) {
29-
console.log('Failed to update task result: ', error);
29+
console.error('Failed to update task result: ', error);
3030
return fail(BAD_REQUEST);
3131
}
3232
};

src/lib/services/answers.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,5 +69,35 @@ export async function createAnswer(task_id: string, user_id: string, status_id:
6969
return taskAnswer;
7070
}
7171

72+
export async function upsertAnswer(taskId: string, userId: string, statusId: string) {
73+
try {
74+
const id = await sha256(taskId + userId);
75+
const newAnswer = {
76+
id: id,
77+
task_id: taskId,
78+
user_id: userId,
79+
status_id: statusId,
80+
created_at: new Date(),
81+
updated_at: new Date(),
82+
};
83+
84+
await prisma.taskAnswer.upsert({
85+
where: {
86+
task_id_user_id: { task_id: taskId, user_id: userId },
87+
},
88+
update: {
89+
status_id: statusId,
90+
},
91+
create: newAnswer, // await createAnswer(taskId, userId, statusId)とすると、一意制約違反(P2002)が発生するため
92+
});
93+
} catch (error) {
94+
console.error(
95+
`Failed to update answer with taskId ${taskId}, userId ${userId}, statusId: ${statusId}:`,
96+
error,
97+
);
98+
throw error;
99+
}
100+
}
101+
72102
// TODO: updateAnswer()
73103
// TODO: deleteAnswer()

src/lib/services/task_results.ts

Lines changed: 17 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
import { error } from '@sveltejs/kit';
2+
3+
import { default as db } from '$lib/server/database';
24
import { getTasks, getTask } from '$lib/services/tasks';
3-
import * as answer_crud from './answers';
4-
import type { TaskResult, TaskResults, Tasks } from '$lib/types/task';
5+
import * as answer_crud from '$lib/services/answers';
6+
7+
import type { TaskAnswer } from '$lib/types/answer';
58
import type { Task } from '$lib/types/task';
9+
import type { TaskResult, TaskResults, Tasks } from '$lib/types/task';
610
import type { WorkBookTaskBase, WorkBookTasksBase } from '$lib/types/workbook';
11+
712
import { NOT_FOUND } from '$lib/constants/http-response-status-codes';
8-
import { default as db } from '$lib/server/database';
913
import { getSubmissionStatusMapWithId, getSubmissionStatusMapWithName } from './submission_status';
10-
import type { TaskAnswer } from '../types/answer';
1114

1215
// DBから取得した問題一覧とログインしているユーザの回答を紐付けしたデータ保持
1316
const statusById = await getSubmissionStatusMapWithId();
@@ -170,29 +173,19 @@ export async function getTaskResult(slug: string, userId: string) {
170173
return taskResult;
171174
}
172175

173-
export async function updateTaskResult(slug: string, submissionStatus: string, userId: string) {
174-
const taskResult: TaskResult | null = await getTaskResult(slug, userId);
175-
176-
if (taskResult) {
177-
const status_id = statusByName.get(submissionStatus).id;
176+
export async function updateTaskResult(taskId: string, submissionStatus: string, userId: string) {
177+
const taskResult: TaskResult | null = await getTaskResult(taskId, userId);
178178

179-
const registeredTaskAnswer = await db.taskAnswer.findMany({
180-
where: { task_id: slug, user_id: userId },
181-
});
179+
if (!taskResult) {
180+
console.error(`Failed to get task result for taskId ${taskId} and userId ${userId}`);
181+
return;
182+
}
182183

183-
if (registeredTaskAnswer.length == 0) {
184-
await answer_crud.createAnswer(slug, userId, status_id);
185-
}
184+
const statusId = statusByName.get(submissionStatus).id;
186185

187-
await db.taskAnswer.update({
188-
where: {
189-
task_id_user_id: { task_id: slug, user_id: userId },
190-
},
191-
data: {
192-
status_id: status_id,
193-
},
194-
});
195-
}
186+
await db.$transaction(async () => {
187+
await answer_crud.upsertAnswer(taskId, userId, statusId);
188+
});
196189
}
197190

198191
export async function getTasksWithTagIds(

0 commit comments

Comments
 (0)