Skip to content

Commit 5f0672b

Browse files
authored
Merge pull request #81 from uwblueprint/INTF25-applicant-record-review-query
[INTF25] Adds applicant record and reviews query
2 parents daecb44 + 1b2121f commit 5f0672b

File tree

5 files changed

+140
-3
lines changed

5 files changed

+140
-3
lines changed

backend/typescript/graphql/resolvers/reviewDashboardResolvers.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
import ReviewDashboardService from "../../services/implementations/reviewDashboardService";
2-
import { ReviewDashboardRowDTO } from "../../types";
2+
import {
3+
ReviewDashboardRowDTO,
4+
ReviewDashboardSidePanelDTO,
5+
} from "../../types";
36
import { getErrorMessage } from "../../utilities/errorUtils";
47

58
const reviewDashboardService = new ReviewDashboardService();
@@ -19,6 +22,18 @@ const reviewDashboardResolvers = {
1922
throw new Error(getErrorMessage(error));
2023
}
2124
},
25+
reviewDashboardSidePanel: async (
26+
_parent: undefined,
27+
args: { applicantId: string },
28+
): Promise<ReviewDashboardSidePanelDTO> => {
29+
try {
30+
return await reviewDashboardService.getReviewDashboardSidePanel(
31+
args.applicantId,
32+
);
33+
} catch (error) {
34+
throw new Error(getErrorMessage(error));
35+
}
36+
},
2237
},
2338
};
2439

backend/typescript/graphql/types/reviewDashboardType.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,39 @@ const reviewDashboardType = gql`
1717
totalScore: Int
1818
}
1919
20+
type Review {
21+
passionFSG: Int
22+
teamPlayer: Int
23+
desireToLearn: Int
24+
skill: Int
25+
skillCategory: String
26+
comments: String
27+
}
28+
29+
type ReviewDetails {
30+
reviewerFirstName: String!
31+
reviewerLastName: String!
32+
review: Review!
33+
}
34+
35+
type ReviewDashboardSidePanelDTO {
36+
firstName: String!
37+
lastName: String!
38+
positionTitle: String!
39+
program: String!
40+
resumeUrl: String!
41+
applicationStatus: String!
42+
skillCategory: String
43+
reviewDetails: [ReviewDetails!]!
44+
}
45+
2046
extend type Query {
2147
reviewDashboard(
2248
pageNumber: Int!
2349
resultsPerPage: Int!
2450
): [ReviewDashboardRowDTO!]!
51+
52+
reviewDashboardSidePanel(applicantId: String!): ReviewDashboardSidePanelDTO!
2553
}
2654
`;
2755

backend/typescript/services/implementations/reviewDashboardService.ts

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
import { ReviewDashboardRowDTO } from "../../types";
1+
import {
2+
PositionTitle,
3+
ReviewDashboardRowDTO,
4+
ReviewDashboardSidePanelDTO,
5+
} from "../../types";
26
import IReviewDashboardService from "../interfaces/IReviewDashboardService";
37
import { getErrorMessage } from "../../utilities/errorUtils";
48
import logger from "../../utilities/logger";
@@ -22,6 +26,26 @@ function toDTO(model: ApplicantRecord): ReviewDashboardRowDTO {
2226
};
2327
}
2428

29+
function toSidePanelDTO(model: ApplicantRecord): ReviewDashboardSidePanelDTO {
30+
const reviewDetails =
31+
model.reviewedApplicantRecords?.map((reviewRecord) => ({
32+
reviewerFirstName: reviewRecord.user?.first_name || "",
33+
reviewerLastName: reviewRecord.user?.last_name || "",
34+
review: reviewRecord.review,
35+
})) || [];
36+
37+
return {
38+
firstName: model.applicant!.firstName,
39+
lastName: model.applicant!.lastName,
40+
positionTitle: model.position as PositionTitle,
41+
program: model.applicant!.program,
42+
resumeUrl: model.applicant!.resumeUrl,
43+
applicationStatus: model.status,
44+
skillCategory: model.skillCategory,
45+
reviewDetails,
46+
};
47+
}
48+
2549
class ReviewDashboardService implements IReviewDashboardService {
2650
/* eslint-disable class-methods-use-this */
2751
async getReviewDashboard(
@@ -72,6 +96,47 @@ class ReviewDashboardService implements IReviewDashboardService {
7296
throw error;
7397
}
7498
}
99+
100+
async getReviewDashboardSidePanel(
101+
applicantId: string,
102+
): Promise<ReviewDashboardSidePanelDTO> {
103+
try {
104+
const applicantRecord: ApplicantRecord | null =
105+
await ApplicantRecord.findOne({
106+
where: { applicantId },
107+
attributes: { exclude: ["createdAt", "updatedAt"] },
108+
include: [
109+
{
110+
attributes: { exclude: ["createdAt", "updatedAt"] },
111+
association: "reviewedApplicantRecords",
112+
include: [
113+
{
114+
attributes: { exclude: ["createdAt", "updatedAt"] },
115+
association: "user",
116+
},
117+
],
118+
},
119+
{
120+
attributes: { exclude: ["createdAt", "updatedAt"] },
121+
association: "applicant",
122+
},
123+
],
124+
});
125+
126+
if (!applicantRecord || !applicantRecord.applicant) {
127+
throw new Error(`Applicant with ID ${applicantId} not found`);
128+
}
129+
130+
return toSidePanelDTO(applicantRecord);
131+
} catch (error: unknown) {
132+
Logger.error(
133+
`Failed to get review dashboard side panel for applicant ${applicantId}. Reason = ${getErrorMessage(
134+
error,
135+
)}`,
136+
);
137+
throw error;
138+
}
139+
}
75140
}
76141

77142
export default ReviewDashboardService;

backend/typescript/services/interfaces/IReviewDashboardService.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
import { ReviewDashboardRowDTO } from "../../types";
1+
import {
2+
ReviewDashboardRowDTO,
3+
ReviewDashboardSidePanelDTO,
4+
} from "../../types";
25

36
interface IReviewDashboardService {
47
/**
@@ -10,6 +13,14 @@ interface IReviewDashboardService {
1013
page: number,
1114
resultsPerPage: number,
1215
): Promise<ReviewDashboardRowDTO[]>;
16+
17+
/**
18+
* Fetch data that can fill out the review dashboard side panel for an applicant
19+
* @Param applicantId the ID of the applicant
20+
*/
21+
getReviewDashboardSidePanel(
22+
applicantId: string,
23+
): Promise<ReviewDashboardSidePanelDTO>;
1324
}
1425

1526
export default IReviewDashboardService;

backend/typescript/types.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,7 @@ export type Review = {
198198
desireToLearn?: number;
199199
skill?: number;
200200
skillCategory?: SkillCategory;
201+
comments?: string;
201202
};
202203

203204
export type ReviewedApplicantRecordDTO = {
@@ -221,6 +222,23 @@ export type DeleteReviewedApplicantRecordDTO = {
221222
reviewerId: number;
222223
};
223224

225+
export type ReviewDetails = {
226+
reviewerFirstName: string;
227+
reviewerLastName: string;
228+
review: Review;
229+
};
230+
231+
export type ReviewDashboardSidePanelDTO = {
232+
firstName: string;
233+
lastName: string;
234+
positionTitle: PositionTitle;
235+
program: string;
236+
resumeUrl: string;
237+
applicationStatus: ApplicationStatus;
238+
skillCategory: SkillCategory | null;
239+
reviewDetails: ReviewDetails[];
240+
};
241+
224242
export type AdminCommentDTO = {
225243
id: string;
226244
userId: number;

0 commit comments

Comments
 (0)