Skip to content

Commit 74d97b5

Browse files
authored
Merge pull request #78 from uwblueprint/INTF25-mutators-for-admin-comments
[INTF25] Adds mutators to support CUDing for admin comments
2 parents 8107e58 + a589964 commit 74d97b5

File tree

6 files changed

+196
-0
lines changed

6 files changed

+196
-0
lines changed

backend/typescript/graphql/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,9 @@ const graphQLMiddlewares = {
7878
logout: isAuthorizedByUserId("userId"),
7979
resetPassword: isAuthorizedByEmail("email"),
8080
sendSignInLink: authorizedByAllRoles(),
81+
createAdminComment: authorizedByAdmin(),
82+
updateAdminComment: authorizedByAdmin(),
83+
deleteAdminCommentById: authorizedByAdmin(),
8184
},
8285
};
8386

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import AdminCommentService from "../../services/implementations/adminCommentService";
2+
import IAdminCommentService from "../../services/interfaces/adminCommentService";
3+
import { CreateAdminCommentDTO, AdminCommentDTO } from "../../types";
4+
5+
const adminCommentService: IAdminCommentService = new AdminCommentService();
6+
7+
const adminCommentResolvers = {
8+
Mutation: {
9+
createAdminComment: async (
10+
_parent: undefined,
11+
{ adminComment }: { adminComment: CreateAdminCommentDTO },
12+
): Promise<AdminCommentDTO> => {
13+
const newAdminComment = await adminCommentService.createAdminComment(
14+
adminComment,
15+
);
16+
return newAdminComment;
17+
},
18+
updateAdminComment: async (
19+
_parent: undefined,
20+
{ id, content }: { id: string; content: CreateAdminCommentDTO },
21+
): Promise<AdminCommentDTO> => {
22+
const adminComment = await adminCommentService.updateAdminComment(
23+
id,
24+
content,
25+
);
26+
return adminComment;
27+
},
28+
deleteAdminCommentById: async (
29+
_parent: undefined,
30+
{ id }: { id: string },
31+
): Promise<AdminCommentDTO> => {
32+
const adminComment = await adminCommentService.deleteAdminCommentById(id);
33+
return adminComment;
34+
},
35+
},
36+
};
37+
38+
export default adminCommentResolvers;
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { gql } from "apollo-server-express";
2+
3+
const adminCommentsType = gql`
4+
type AdminCommentDTO {
5+
id: String!
6+
userId: Int!
7+
applicantRecordId: String!
8+
comment: String!
9+
createdAt: String!
10+
updatedAt: String!
11+
}
12+
13+
input CreateAdminCommentDTO {
14+
userId: Int!
15+
applicantRecordId: String!
16+
comment: String!
17+
}
18+
19+
extend type Mutation {
20+
createAdminComment(adminComment: CreateAdminCommentDTO!): AdminCommentDTO!
21+
updateAdminComment(
22+
id: String!
23+
content: CreateAdminCommentDTO!
24+
): AdminCommentDTO!
25+
deleteAdminCommentById(id: String!): AdminCommentDTO!
26+
}
27+
`;
28+
29+
export default adminCommentsType;
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
import { AdminCommentDTO, CreateAdminCommentDTO } from "../../types";
2+
import { getErrorMessage } from "../../utilities/errorUtils";
3+
import logger from "../../utilities/logger";
4+
import AdminComment from "../../models/adminComment.model";
5+
import IAdminCommentService from "../interfaces/adminCommentService";
6+
7+
const Logger = logger(__filename);
8+
9+
const grabAdminComment = async (commentId: string): Promise<AdminComment> => {
10+
try {
11+
const adminComment = await AdminComment.findByPk(commentId);
12+
if (!adminComment) {
13+
throw new Error(`adminCommentId ${commentId} not found.`);
14+
}
15+
return adminComment;
16+
} catch (error: unknown) {
17+
Logger.error(
18+
`Failed to get admin comment. Reason = ${getErrorMessage(error)}`,
19+
);
20+
throw error;
21+
}
22+
};
23+
24+
class AdminCommentService implements IAdminCommentService {
25+
/* eslint-disable class-methods-use-this */
26+
27+
async createAdminComment(
28+
content: CreateAdminCommentDTO,
29+
): Promise<AdminCommentDTO> {
30+
try {
31+
const adminComment = await AdminComment.create({
32+
userId: content.userId,
33+
applicantRecordId: content.applicantRecordId,
34+
comment: content.comment,
35+
createdAt: new Date(),
36+
updatedAt: new Date(),
37+
});
38+
return {
39+
id: String(adminComment.id),
40+
userId: adminComment.userId,
41+
applicantRecordId: String(adminComment.applicantRecordId),
42+
comment: adminComment.comment,
43+
createdAt: adminComment.createdAt.toISOString(),
44+
updatedAt: adminComment.updatedAt.toISOString(),
45+
};
46+
} catch (error: unknown) {
47+
Logger.error(
48+
`Failed to create admin comment. Reason = ${getErrorMessage(error)}`,
49+
);
50+
throw error;
51+
}
52+
}
53+
54+
async updateAdminComment(
55+
commentId: string,
56+
content: CreateAdminCommentDTO,
57+
): Promise<AdminCommentDTO> {
58+
const adminComment = await grabAdminComment(commentId);
59+
try {
60+
adminComment.comment = content.comment;
61+
adminComment.updatedAt = new Date();
62+
await adminComment.save();
63+
return {
64+
id: String(adminComment.id),
65+
userId: adminComment.userId,
66+
applicantRecordId: String(adminComment.applicantRecordId),
67+
comment: adminComment.comment,
68+
createdAt: adminComment.createdAt.toISOString(),
69+
updatedAt: adminComment.updatedAt.toISOString(),
70+
};
71+
} catch (error: unknown) {
72+
Logger.error(
73+
`Failed to update admin comment. Reason = ${getErrorMessage(error)}`,
74+
);
75+
throw error;
76+
}
77+
}
78+
79+
async deleteAdminCommentById(id: string): Promise<AdminCommentDTO> {
80+
const adminComment = await grabAdminComment(id);
81+
try {
82+
await adminComment.destroy();
83+
return {
84+
id: String(adminComment.id),
85+
userId: adminComment.userId,
86+
applicantRecordId: String(adminComment.applicantRecordId),
87+
comment: adminComment.comment,
88+
createdAt: adminComment.createdAt.toISOString(),
89+
updatedAt: adminComment.updatedAt.toISOString(),
90+
};
91+
} catch (error: unknown) {
92+
Logger.error(
93+
`Failed to delete admin comment. Reason = ${getErrorMessage(error)}`,
94+
);
95+
throw error;
96+
}
97+
}
98+
}
99+
100+
export default AdminCommentService;
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { AdminCommentDTO, CreateAdminCommentDTO } from "../../types";
2+
3+
interface IAdminCommentService {
4+
createAdminComment(content: CreateAdminCommentDTO): Promise<AdminCommentDTO>;
5+
updateAdminComment(
6+
commentId: string,
7+
content: CreateAdminCommentDTO,
8+
): Promise<AdminCommentDTO>;
9+
deleteAdminCommentById(id: string): Promise<AdminCommentDTO>;
10+
}
11+
12+
export default IAdminCommentService;

backend/typescript/types.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,3 +255,17 @@ export type ReviewedApplicantRecordDTO = {
255255
score?: number | null;
256256
reviewerHasConflict: boolean;
257257
};
258+
259+
export type AdminCommentDTO = {
260+
id: string;
261+
userId: number;
262+
applicantRecordId: string;
263+
comment: string;
264+
createdAt: string;
265+
updatedAt: string;
266+
};
267+
268+
export type CreateAdminCommentDTO = Pick<
269+
AdminCommentDTO,
270+
"userId" | "applicantRecordId" | "comment"
271+
>;

0 commit comments

Comments
 (0)