Skip to content

Commit cf0f017

Browse files
committed
Change Approach to Create Attempt on Entering Room
1 parent 05569ac commit cf0f017

File tree

8 files changed

+53
-15
lines changed

8 files changed

+53
-15
lines changed

backend/question-service/controllers/historyController.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,15 @@ export const createOrUpdateUserHistoryEntry = async (req: any, res: Response) =>
4040
try {
4141
const userId = req.userId;
4242

43-
const { questionId, roomId, attemptStartedAt, attemptCompletedAt, collaboratorId, attemptCode } = req.body;
43+
const { questionId, roomId, attemptStartedAt, attemptCompletedAt, collaboratorId, attemptCode, isInitial } = req.body;
4444

4545
if (!roomId) {
4646
return res.status(400).json({ error: "roomId is required" });
4747
}
4848

4949
const existingEntry = await historyEntryModel.findOne({ userId, roomId });
5050

51-
if (existingEntry) {
51+
if (!isInitial && existingEntry) {
5252
existingEntry.question = questionId;
5353
existingEntry.attemptStartedAt = attemptStartedAt;
5454
existingEntry.attemptCompletedAt = attemptCompletedAt;
@@ -58,20 +58,23 @@ export const createOrUpdateUserHistoryEntry = async (req: any, res: Response) =>
5858
const updatedEntry = await existingEntry.save();
5959

6060
return res.status(200).json(updatedEntry);
61-
} else {
61+
} else if (!existingEntry) {
6262
const newHistoryEntry = new historyEntryModel({
6363
userId,
6464
question: questionId,
6565
roomId,
6666
attemptStartedAt,
6767
attemptCompletedAt,
6868
collaboratorId,
69-
attemptCodes: [attemptCode],
69+
attemptCodes: isInitial ? [attemptCode] : [],
7070
});
7171

7272
const savedEntry = await newHistoryEntry.save();
7373

7474
return res.status(201).json(savedEntry);
75+
} else {
76+
return res.status(200).json("Attempt already exists.");
77+
// To reach here, this must be initial creation and there's an existing entry. No need to create new attempt.
7578
}
7679
} catch (error) {
7780
return res.status(500).json({ error: getErrorMessage(error) });

backend/question-service/models/HistoryEntry.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ const historyEntrySchema: Schema = new Schema<HistoryEntry>({
1919
attemptStartedAt: { type: Date, required: true, default: Date.now() },
2020
attemptCompletedAt: { type: Date, required: true, default: Date.now() },
2121
collaboratorId: { type: String, required: true },
22-
attemptCodes: [{ type: String, required: true }],
22+
attemptCodes: [{ type: String }],
2323
});
2424

2525
const historyEntryModel = mongoose.model<HistoryEntry>('historyEntry', historyEntrySchema);

frontend/src/data/repositories/HistoryRemoteDataSource.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ export class HistoryRemoteDataSource extends BaseApi {
1313
return await this.protectedGet<HistoryEntry[]>("/");
1414
}
1515

16-
async createOrUpdateUserHistory(questionId: string, roomId: string, attemptStartedAt: string, attemptCompletedAt: string, collaboratorId: string, attemptCode: string): Promise<void> {
17-
return await this.protectedPost<void>("/", { questionId, roomId, attemptStartedAt, attemptCompletedAt, collaboratorId, attemptCode });
16+
async createOrUpdateUserHistory(questionId: string, roomId: string, attemptStartedAt: string, attemptCompletedAt: string, collaboratorId: string, attemptCode: string, isInitial: boolean): Promise<void> {
17+
return await this.protectedPost<void>("/", { questionId, roomId, attemptStartedAt, attemptCompletedAt, collaboratorId, attemptCode, isInitial });
1818
}
1919

2020
async deleteSelectedHistories(selectedHistoryIds: string[]): Promise<void> {

frontend/src/data/repositories/HistoryRepositoryImpl.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ export class HistoryRepositoryImpl {
88
return this.dataSource.getAllUserHistories();
99
}
1010

11-
async createOrUpdateUserHistory(questionId: string, roomId: string, attemptStartedAt: string, attemptCompletedAt: string, collaboratorId: string, attemptCode: string): Promise<void> {
12-
this.dataSource.createOrUpdateUserHistory(questionId, roomId, attemptStartedAt, attemptCompletedAt, collaboratorId, attemptCode)
11+
async createOrUpdateUserHistory(questionId: string, roomId: string, attemptStartedAt: string, attemptCompletedAt: string, collaboratorId: string, attemptCode: string, isInitial: boolean): Promise<void> {
12+
this.dataSource.createOrUpdateUserHistory(questionId, roomId, attemptStartedAt, attemptCompletedAt, collaboratorId, attemptCode, isInitial)
1313
}
1414

1515
async deleteSelectedUserHistories(selectedHistoryIds: string[]): Promise<void> {

frontend/src/domain/repositories/IHistoryRepository.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { HistoryEntry } from "domain/entities/HistoryEntry";
22

33
export interface IHistoryRepository {
44
getAllUserHistories(): Promise<HistoryEntry[]>;
5-
createOrUpdateUserHistory(questionId: string, roomId: string, attemptStartedAt: string, attemptCompletedAt: string, collaboratorId: string, attemptCode: string): Promise<void>;
5+
createOrUpdateUserHistory(questionId: string, roomId: string, attemptStartedAt: string, attemptCompletedAt: string, collaboratorId: string, attemptCode: string, isInitial: boolean): Promise<void>;
66
deleteSelectedUserHistories(selectedHistoryIds: string[]): Promise<void>;
77
deleteAllUserHistories(): Promise<void>;
88
}

frontend/src/domain/usecases/HistoryUseCases.ts

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,21 +14,37 @@ export class HistoryUseCases {
1414
return allHistories;
1515
}
1616

17+
/**
18+
* Creates a new User History Entry.
19+
* (Note that just roomId isn't enough because the collaborator will also have a very similar History Entry)
20+
* @returns Promise resolving when the history has been successfully created.
21+
*/
22+
async createUserHistory(questionId: string, roomId: string, attemptStartedAt: string, attemptCompletedAt: string, collaboratorId: string, attemptCode: string): Promise<void> {
23+
if (!questionId || questionId.trim() === ""
24+
|| !roomId || roomId.trim() === ""
25+
|| !attemptStartedAt || attemptStartedAt.trim() === ""
26+
|| !attemptCompletedAt || attemptCompletedAt.trim() === ""
27+
|| !collaboratorId || collaboratorId.trim() === "") {
28+
throw new Error("Missing Attempt Details");
29+
}
30+
await this.historyRepository.createOrUpdateUserHistory(questionId, roomId, attemptStartedAt, attemptCompletedAt, collaboratorId, attemptCode, true);
31+
}
32+
1733
/**
1834
* Creates a new User History Entry. If there already exists a History Entry with the same userId (obtained in
1935
* backend via JWT token and not passed here) and roomId, update the existing one instead.
2036
* (Note that just roomId isn't enough because the collaborator will also have a very similar History Entry)
2137
* @returns Promise resolving when the history has been successfully created.
2238
*/
23-
async createOrUpdateUserHistory(questionId: string, roomId: string, attemptStartedAt: string, attemptCompletedAt: string, collaboratorId: string, attemptCode: string): Promise<void> {
39+
async updateUserHistory(questionId: string, roomId: string, attemptStartedAt: string, attemptCompletedAt: string, collaboratorId: string, attemptCode: string): Promise<void> {
2440
if (!questionId || questionId.trim() === ""
2541
|| !roomId || roomId.trim() === ""
2642
|| !attemptStartedAt || attemptStartedAt.trim() === ""
2743
|| !attemptCompletedAt || attemptCompletedAt.trim() === ""
2844
|| !collaboratorId || collaboratorId.trim() === "") {
2945
throw new Error("Missing Attempt Details");
3046
}
31-
await this.historyRepository.createOrUpdateUserHistory(questionId, roomId, attemptStartedAt, attemptCompletedAt, collaboratorId, attemptCode);
47+
await this.historyRepository.createOrUpdateUserHistory(questionId, roomId, attemptStartedAt, attemptCompletedAt, collaboratorId, attemptCode, false);
3248
}
3349

3450
/**

frontend/src/presentation/components/CodeEditor/LeaveButton.tsx

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useState } from "react";
1+
import React, { useEffect, useState } from "react";
22
import { Button, Modal, message } from "antd";
33
import { StopOutlined } from "@ant-design/icons";
44
import styles from "./LeaveButton.module.css";
@@ -23,6 +23,7 @@ const LeaveButton: React.FC<LeaveButtonProps> = ({
2323
const navigate = useNavigate();
2424
const [isModalVisible, setIsModalVisible] = useState(false);
2525
const [editorContent, setEditorContent] = useState("");
26+
const [created, setCreated] = useState(false);
2627

2728
const showModal = () => {
2829
const content = getEditorText();
@@ -41,7 +42,7 @@ const LeaveButton: React.FC<LeaveButtonProps> = ({
4142

4243
const handleSaveAndLeave = async () => {
4344
try {
44-
await historyUseCases.createOrUpdateUserHistory(
45+
await historyUseCases.updateUserHistory(
4546
questionId,
4647
roomId,
4748
attemptStartedAt.getTime().toString(),
@@ -64,6 +65,24 @@ const LeaveButton: React.FC<LeaveButtonProps> = ({
6465
}
6566
};
6667

68+
useEffect(() => { //On init, send request to create attempt if it is absent.
69+
const createEntry = async () => {
70+
await historyUseCases.createUserHistory(
71+
questionId,
72+
roomId,
73+
attemptStartedAt.getTime().toString(),
74+
Date.now().toString(),
75+
collaboratorId,
76+
getEditorText(),
77+
);
78+
}
79+
if (!roomId || !questionId || !attemptStartedAt || !collaboratorId || !getEditorText) return;
80+
if (!created) {
81+
setCreated(true);
82+
createEntry();
83+
};
84+
}, [roomId, questionId, attemptStartedAt, collaboratorId, getEditorText, created])
85+
6786
return (
6887
<>
6988
<Button

frontend/src/presentation/components/CodeEditor/SubmitButton.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ const SaveButton: React.FC<SaveButtonProps> = ({
3434

3535
const handleSave = async () => {
3636
try {
37-
await historyUseCases.createOrUpdateUserHistory(
37+
await historyUseCases.updateUserHistory(
3838
questionId,
3939
roomId,
4040
attemptStartedAt.getTime().toString(),

0 commit comments

Comments
 (0)