Skip to content

Commit 11141ce

Browse files
committed
query for applicant record and review
1 parent 54693ae commit 11141ce

File tree

5 files changed

+135
-3
lines changed

5 files changed

+135
-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: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,38 @@ const reviewDashboardType = gql`
1818
totalScore: Int
1919
}
2020
21+
type Review {
22+
passionFSG: Int
23+
teamPlayer: Int
24+
desireToLearn: Int
25+
skill: Int
26+
skillCategory: 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+
2146
extend type Query {
2247
reviewDashboard(
2348
pageNumber: Int!
2449
resultsPerPage: Int!
2550
): [ReviewDashboardRowDTO!]!
51+
52+
reviewDashboardSidePanel(applicantId: String!): ReviewDashboardSidePanelDTO!
2653
}
2754
`;
2855

backend/typescript/services/implementations/reviewDashboardService.ts

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
import { PositionTitle, 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";
@@ -72,6 +76,64 @@ class ReviewDashboardService implements IReviewDashboardService {
7276
throw error;
7377
}
7478
}
79+
80+
async getReviewDashboardSidePanel(
81+
applicantId: string,
82+
): Promise<ReviewDashboardSidePanelDTO> {
83+
try {
84+
// Find the applicant record with all necessary joins
85+
const applicantRecord = await ApplicantRecord.findOne({
86+
where: { applicantId: applicantId },
87+
attributes: { exclude: ["createdAt", "updatedAt"] },
88+
include: [
89+
{
90+
attributes: { exclude: ["createdAt", "updatedAt"] },
91+
association: "applicant",
92+
},
93+
{
94+
attributes: { exclude: ["createdAt", "updatedAt"] },
95+
association: "reviewedApplicantRecords",
96+
include: [
97+
{
98+
attributes: { exclude: ["createdAt", "updatedAt"] },
99+
association: "user",
100+
},
101+
],
102+
},
103+
],
104+
});
105+
106+
if (!applicantRecord || !applicantRecord.applicant) {
107+
throw new Error(`Applicant with ID ${applicantId} not found`);
108+
}
109+
110+
// Transform the data to the required DTO format
111+
const reviewDetails =
112+
applicantRecord.reviewedApplicantRecords?.map((reviewRecord) => ({
113+
reviewerFirstName: reviewRecord.user?.first_name || "",
114+
reviewerLastName: reviewRecord.user?.last_name || "",
115+
review: reviewRecord.review,
116+
})) || [];
117+
118+
return {
119+
firstName: applicantRecord.applicant.firstName,
120+
lastName: applicantRecord.applicant.lastName,
121+
positionTitle: applicantRecord.position as PositionTitle,
122+
program: applicantRecord.applicant.program,
123+
resumeUrl: applicantRecord.applicant.resumeUrl,
124+
applicationStatus: applicantRecord.status,
125+
skillCategory: applicantRecord.skillCategory || "Junior",
126+
reviewDetails: reviewDetails,
127+
};
128+
} catch (error: unknown) {
129+
Logger.error(
130+
`Failed to get review dashboard side panel for applicant ${applicantId}. Reason = ${getErrorMessage(
131+
error,
132+
)}`,
133+
);
134+
throw error;
135+
}
136+
}
75137
}
76138

77139
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: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,3 +255,20 @@ export type ReviewedApplicantRecordDTO = {
255255
score?: number | null;
256256
reviewerHasConflict: boolean;
257257
};
258+
259+
export type ReviewDetails = {
260+
reviewerFirstName: string;
261+
reviewerLastName: string;
262+
review: Review;
263+
};
264+
265+
export type ReviewDashboardSidePanelDTO = {
266+
firstName: string;
267+
lastName: string;
268+
positionTitle: PositionTitle;
269+
program: string;
270+
resumeUrl: string;
271+
applicationStatus: ApplicationStatus;
272+
skillCategory: SkillCategory;
273+
reviewDetails: ReviewDetails[];
274+
};

0 commit comments

Comments
 (0)