Skip to content

Commit fb3e436

Browse files
committed
feat: implement presentation schedule creation with trial and official dates
1 parent 7533086 commit fb3e436

7 files changed

Lines changed: 92 additions & 8 deletions

File tree

backend/prisma/schema.prisma

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -177,8 +177,8 @@ model Present {
177177
id String @id @default(uuid()) @db.VarChar(36)
178178
teamId String @map("team_id") @db.VarChar(36)
179179
180-
tentativeSchedule Json @map("tentative_schedule") @db.Json
181-
finalSchedule Json @map("final_schedule") @db.Json
180+
trialDate String @unique @map("trial_date") @db.VarChar(255)
181+
officialDate Json @map("offical_date") @db.Json
182182
183183
createdAt DateTime @default(now()) @map("created_at")
184184
updatedAt DateTime @updatedAt @map("updated_at")

backend/src/controllers/team.controllers.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1+
import { ParamsDictionary } from "express-serve-static-core";
12
import { NextFunction, Request, Response } from "express";
23
import { RoleType } from "~/constants/enums";
34
import { HTTP_STATUS } from "~/constants/httpStatus";
45
import { ResponseClient } from "~/rules/response";
56
import teamService from "~/services/team.service";
7+
import { CreateSchedulePresent } from "~/rules/requests/team.request";
68

79
export const getAll = async (req: Request, res: Response, next: NextFunction) => {
810
try {
@@ -23,6 +25,27 @@ export const getAll = async (req: Request, res: Response, next: NextFunction) =>
2325
return next(error);
2426
}
2527
};
28+
export const createSchedulePresentation = async (
29+
req: Request<ParamsDictionary, {}, CreateSchedulePresent>,
30+
res: Response,
31+
next: NextFunction,
32+
) => {
33+
const userId = req.userId!;
34+
const { teamId, trialDate, officialDate } = req.body;
35+
try {
36+
const result = await teamService.createSchedulePresentation({
37+
userId,
38+
teamId,
39+
trialDate,
40+
officialDate,
41+
});
42+
return res
43+
.status(HTTP_STATUS.CREATED)
44+
.json(new ResponseClient({ message: "Tạo lịch trình thuyết trình thành công!", result }));
45+
} catch (error) {
46+
return next(error);
47+
}
48+
};
2649

2750
export const getDetail = async (req: Request<{ id: string }>, res: Response, next: NextFunction) => {
2851
try {

backend/src/repositories/team.repository.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import prisma from "~/configs/prisma";
22
import { paginate } from "~/utils/pagination";
33
import userRespository from "./user.repository";
44
import { RoleType } from "~/constants/enums";
5+
import Present from "~/schemas/present.schema";
56

67
class TeamRepository {
78
findWithPagination = async () => {
@@ -227,6 +228,25 @@ class TeamRepository {
227228
});
228229
return !!team;
229230
};
231+
232+
isTrialDateExists = async (trialDate: string) => {
233+
const team = await prisma.present.findFirst({
234+
where: {
235+
trialDate,
236+
},
237+
});
238+
return !!team;
239+
};
240+
241+
createPresentationSchedule = async (data: { teamId: string; trialDate: string; officialDate: string[] }) => {
242+
return prisma.present.create({
243+
data: new Present({
244+
teamId: data.teamId,
245+
trialDate: data.trialDate,
246+
officialDate: data.officialDate,
247+
}),
248+
});
249+
};
230250
}
231251

232252
const teamRepository = new TeamRepository();

backend/src/routes/team.routes.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ const teamRouter = Router();
1414

1515
// teamRouter.get("/", auth, isRole([RoleType.ADMIN, RoleType.MENTOR]), validate(getAllSchema), teamController.getAll);
1616
teamRouter.get("/", auth, validate(getAllSchema), teamController.getAll);
17+
teamRouter.post("/present", auth, teamController.createSchedulePresentation);
1718

1819
teamRouter.get("/:id", auth, validate(idParamSchema), teamController.getDetail);
1920

@@ -59,4 +60,5 @@ teamRouter.get(
5960
// validate(uuidParamsAndBodySchema),
6061
teamController.getTeamsByMentor,
6162
);
63+
6264
export default teamRouter;
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export interface CreateSchedulePresent {
2+
teamId: string;
3+
trialDate: string;
4+
officialDate: string[];
5+
}

backend/src/schemas/present.schema.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,24 @@ import { v4 as uuidv4 } from "uuid";
33
interface PresentType {
44
id?: string;
55
teamId: string;
6-
tentativeSchedule: string;
7-
finalSchedule: string;
6+
trialDate: string;
7+
officialDate: string[];
88
createdAt?: Date;
99
updatedAt?: Date;
1010
}
1111

1212
class Present {
1313
id: string;
1414
teamId: string;
15-
tentativeSchedule: string;
16-
finalSchedule: string;
15+
trialDate: string;
16+
officialDate: string[];
1717
createdAt: Date;
1818
updatedAt: Date;
1919
constructor(present: PresentType) {
2020
this.id = present.id || uuidv4();
2121
this.teamId = present.teamId;
22-
this.tentativeSchedule = present.tentativeSchedule;
23-
this.finalSchedule = present.finalSchedule;
22+
this.trialDate = present.trialDate;
23+
this.officialDate = present.officialDate;
2424
this.createdAt = present.createdAt || new Date();
2525
this.updatedAt = present.updatedAt || new Date();
2626
}

backend/src/services/team.service.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,40 @@ class TeamService {
127127
const updated = await teamRepository.update(teamId, { name });
128128
return updated;
129129
}
130+
createSchedulePresentation = async ({
131+
userId,
132+
teamId,
133+
trialDate,
134+
officialDate,
135+
}: {
136+
userId: string;
137+
teamId: string;
138+
trialDate: string;
139+
officialDate: string[];
140+
}) => {
141+
// trial_date: chỉ có 1 nhóm được đăng ký, nên là check sự trùng lặp
142+
// check trial_date có bị trùng với nhóm khác không
143+
const isTrialDateExist = await teamRepository.isTrialDateExists(trialDate);
144+
if (isTrialDateExist) {
145+
throw new ErrorWithStatus({
146+
status: HTTP_STATUS.BAD_REQUEST,
147+
message: "Ngày thuyết trình thử đã được đăng ký bởi nhóm khác, vui lòng chọn ngày khác.",
148+
});
149+
}
150+
const isLeader = await teamRepository.isLeader(teamId, userId);
151+
if (!isLeader) {
152+
throw new ErrorWithStatus({
153+
status: HTTP_STATUS.FORBIDDEN,
154+
message: "Chỉ trưởng nhóm mới có quyền đăng ký lịch trình thuyết trình.",
155+
});
156+
}
157+
const created = await teamRepository.createPresentationSchedule({
158+
teamId,
159+
trialDate,
160+
officialDate,
161+
});
162+
return created;
163+
};
130164
// async getTeamByMentor(mentorId: string) {
131165
// const teams = await teamRepository.findByMentorId(mentorId);
132166
// return teams;

0 commit comments

Comments
 (0)