Skip to content

Commit b1b6fa8

Browse files
authored
Merge pull request #86 from uwblueprint/INTF25-flag-applicant-mutator
[INTF25] Build flag applicant mutator
2 parents 0a494f5 + 56b91b1 commit b1b6fa8

File tree

7 files changed

+140
-1
lines changed

7 files changed

+140
-1
lines changed

backend/typescript/graphql/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ import reviewDashboardResolvers from "./resolvers/reviewDashboardResolvers";
1919
import reviewDashboardType from "./types/reviewDashboardType";
2020
import adminCommentResolvers from "./resolvers/adminCommentsResolvers";
2121
import adminCommentType from "./types/adminCommentsType";
22+
import applicantRecordResolvers from "./resolvers/applicantRecordResolvers";
23+
import applicantRecordType from "./types/applicantRecordType";
2224
import reviewPageType from "./types/reviewPageType";
2325
import reviewPageResolvers from "./resolvers/reviewPageResolvers";
2426

@@ -44,6 +46,7 @@ const executableSchema = makeExecutableSchema({
4446
userType,
4547
reviewDashboardType,
4648
adminCommentType,
49+
applicantRecordType,
4750
reviewPageType,
4851
],
4952
resolvers: merge(
@@ -53,6 +56,7 @@ const executableSchema = makeExecutableSchema({
5356
userResolvers,
5457
reviewDashboardResolvers,
5558
adminCommentResolvers,
59+
applicantRecordResolvers,
5660
reviewPageResolvers,
5761
),
5862
});
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import ApplicantRecordService from "../../services/implementations/applicantRecordService";
2+
import IApplicantRecordService from "../../services/interfaces/applicantRecordService";
3+
import { ApplicantRecordDTO } from "../../types";
4+
import { getErrorMessage } from "../../utilities/errorUtils";
5+
6+
const applicantRecordService: IApplicantRecordService =
7+
new ApplicantRecordService();
8+
9+
const applicantRecordResolvers = {
10+
Mutation: {
11+
setApplicantRecordFlag: async (
12+
_parent: undefined,
13+
{
14+
applicantRecordId,
15+
flagValue,
16+
}: { applicantRecordId: string; flagValue: boolean },
17+
): Promise<ApplicantRecordDTO> => {
18+
try {
19+
const applicantRecord =
20+
await applicantRecordService.setApplicantRecordFlag(
21+
applicantRecordId,
22+
flagValue,
23+
);
24+
return applicantRecord;
25+
} catch (error: unknown) {
26+
throw new Error(getErrorMessage(error));
27+
}
28+
},
29+
},
30+
};
31+
32+
export default applicantRecordResolvers;
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { gql } from "apollo-server-express";
2+
3+
const applicantRecordType = gql`
4+
type ApplicantRecordDTO {
5+
id: String!
6+
applicantId: String!
7+
position: String!
8+
roleSpecificQuestions: [String!]!
9+
choice: Int!
10+
status: String!
11+
skillCategory: String
12+
combined_score: Int
13+
isApplicantFlagged: Boolean!
14+
}
15+
16+
extend type Mutation {
17+
setApplicantRecordFlag(
18+
applicantRecordId: String!
19+
flagValue: Boolean!
20+
): ApplicantRecordDTO!
21+
}
22+
`;
23+
24+
export default applicantRecordType;
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { DataType } from "sequelize-typescript";
2+
import { Migration } from "../umzug";
3+
4+
const TABLE_NAME = "applicant_records";
5+
6+
export const up: Migration = async ({ context: sequelize }) => {
7+
await sequelize.getQueryInterface().addColumn(TABLE_NAME, "createdAt", {
8+
type: DataType.DATE,
9+
allowNull: false,
10+
defaultValue: new Date(),
11+
});
12+
await sequelize.getQueryInterface().addColumn(TABLE_NAME, "updatedAt", {
13+
type: DataType.DATE,
14+
allowNull: false,
15+
defaultValue: new Date(),
16+
});
17+
};
18+
19+
export const down: Migration = async ({ context: sequelize }) => {
20+
await sequelize.getQueryInterface().removeColumn(TABLE_NAME, "createdAt");
21+
await sequelize.getQueryInterface().removeColumn(TABLE_NAME, "updatedAt");
22+
};
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import { ApplicantRecordDTO, PositionTitle } from "../../types";
2+
import { getErrorMessage } from "../../utilities/errorUtils";
3+
import logger from "../../utilities/logger";
4+
import ApplicantRecord from "../../models/applicantRecord.model";
5+
import IApplicantRecordService from "../interfaces/applicantRecordService";
6+
7+
const Logger = logger(__filename);
8+
9+
class ApplicantRecordService implements IApplicantRecordService {
10+
/* eslint-disable class-methods-use-this */
11+
async setApplicantRecordFlag(
12+
applicantRecordId: string,
13+
flagValue: boolean,
14+
): Promise<ApplicantRecordDTO> {
15+
try {
16+
const applicantRecord = await ApplicantRecord.findByPk(applicantRecordId);
17+
if (!applicantRecord) {
18+
throw new Error(
19+
`ApplicantRecord with id ${applicantRecordId} not found.`,
20+
);
21+
}
22+
applicantRecord.isApplicantFlagged = flagValue;
23+
await applicantRecord.save();
24+
return {
25+
id: String(applicantRecord.id),
26+
applicantId: String(applicantRecord.applicantId),
27+
position: applicantRecord.position as PositionTitle,
28+
roleSpecificQuestions: applicantRecord.roleSpecificQuestions,
29+
choice: applicantRecord.choice,
30+
status: applicantRecord.status,
31+
skillCategory: applicantRecord.skillCategory,
32+
combined_score: applicantRecord.combined_score,
33+
isApplicantFlagged: applicantRecord.isApplicantFlagged,
34+
};
35+
} catch (error: unknown) {
36+
Logger.error(
37+
`Failed to set applicant record flag. Reason = ${getErrorMessage(
38+
error,
39+
)}`,
40+
);
41+
throw error;
42+
}
43+
}
44+
}
45+
46+
export default ApplicantRecordService;
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { ApplicantRecordDTO } from "../../types";
2+
3+
interface IApplicantRecordService {
4+
setApplicantRecordFlag(
5+
applicantRecordId: string,
6+
flagValue: boolean,
7+
): Promise<ApplicantRecordDTO>;
8+
}
9+
10+
export default IApplicantRecordService;

backend/typescript/types.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,14 +77,15 @@ export type ApplicantDTO = {
7777
};
7878

7979
export type ApplicantRecordDTO = {
80-
id: number;
80+
id: string;
8181
applicantId: string;
8282
position: string;
8383
roleSpecificQuestions: string[];
8484
choice: number;
8585
status: ApplicationStatus;
8686
skillCategory?: SkillCategory;
8787
combined_score?: number | null;
88+
isApplicantFlagged: boolean;
8889
};
8990

9091
export type ApplicationStatus =

0 commit comments

Comments
 (0)