Skip to content

Commit 4c55845

Browse files
author
ruiichen
committed
setup and pseudocode
# Conflicts: # backend/typescript/graphql/resolvers/reviewDashboardResolvers.ts # backend/typescript/services/implementations/reviewDashboardService.ts # backend/typescript/services/interfaces/IReviewDashboardService.ts
1 parent 0a944f4 commit 4c55845

File tree

4 files changed

+80
-0
lines changed

4 files changed

+80
-0
lines changed

backend/typescript/graphql/resolvers/reviewDashboardResolvers.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import ReviewDashboardService from "../../services/implementations/reviewDashboa
22
import {
33
ReviewDashboardRowDTO,
44
ReviewDashboardSidePanelDTO,
5+
ReviewedApplicantRecordDTO,
56
} from "../../types";
67
import { getErrorMessage } from "../../utilities/errorUtils";
78

@@ -35,6 +36,15 @@ const reviewDashboardResolvers = {
3536
}
3637
},
3738
},
39+
Mutation: {
40+
delegateReviewers: async (): Promise<ReviewedApplicantRecordDTO[]> => {
41+
try {
42+
return await reviewDashboardService.delegateReviewers();
43+
} catch (error) {
44+
throw new Error(getErrorMessage(error));
45+
}
46+
},
47+
},
3848
};
3949

4050
export default reviewDashboardResolvers;

backend/typescript/graphql/types/reviewDashboardType.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,12 @@
11
import { gql } from "apollo-server-express";
2+
import {
3+
ApplicationStatus,
4+
PositionTitle,
5+
Review,
6+
ReviewerDTO,
7+
ReviewStatus,
8+
SkillCategory,
9+
} from "../../types";
210

311
const reviewDashboardType = gql`
412
type ReviewerDTO {
@@ -16,6 +24,15 @@ const reviewDashboardType = gql`
1624
reviewers: [ReviewerDTO!]!
1725
totalScore: Int
1826
}
27+
28+
type ReviewedApplicantRecordDTO {
29+
applicantRecordId: String!
30+
reviewerId: Int!
31+
review: Review
32+
status: String!
33+
score: Int
34+
reviewerHasConflict: Boolean!
35+
}
1936
2037
type Review {
2138
passionFSG: Int
@@ -51,6 +68,10 @@ const reviewDashboardType = gql`
5168
5269
reviewDashboardSidePanel(applicantId: String!): ReviewDashboardSidePanelDTO!
5370
}
71+
72+
extend type Mutation {
73+
delegateReviewers: [ReviewedApplicantRecordDTO!]!
74+
}
5475
`;
5576

5677
export default reviewDashboardType;

backend/typescript/services/implementations/reviewDashboardService.ts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import {
22
PositionTitle,
33
ReviewDashboardRowDTO,
4+
ReviewedApplicantRecordDTO,
45
ReviewDashboardSidePanelDTO,
56
} from "../../types";
67
import IReviewDashboardService from "../interfaces/IReviewDashboardService";
@@ -137,6 +138,47 @@ class ReviewDashboardService implements IReviewDashboardService {
137138
throw error;
138139
}
139140
}
141+
142+
async delegateReviewers(): Promise<ReviewedApplicantRecordDTO[]> {
143+
// NOTE: We do not have to concern ourselves with locality. That is, each user can be
144+
// assigned to the same parter every time.
145+
146+
const FSM = new Map<string, [number, string[]]>();
147+
// maps (position title) => (current index of list, list of users with position_title)
148+
const delegations = new Map<string, [string, string]>();
149+
// maps (applicant_record_id) => pair of user_ids assigned to it
150+
151+
// STEP 1:
152+
// Populate the FSM
153+
// NOTE: need to add a sentinel value at the end of the list if the number of user is odd.
154+
// The last 'real' user will bear the burden of solo reviewing.
155+
156+
// STEP 2:
157+
// Round robin with the FSM
158+
/*
159+
for (auto& a : applicant_records) {
160+
pair<int,vector<string>>& position_entry = FSM[a.position];
161+
162+
// get first user
163+
string id1 = position_entry.second[position_entry.first];
164+
position_entry.first++;
165+
position_entry.first %= position_entry.second.size();
166+
167+
// get second user
168+
string id2 = position_entry.second[position_entry.first];
169+
position_entry.first++;
170+
position_entry.first %= position_entry.second.size();
171+
172+
delegations[a.id] = make_pair(id1, id2);
173+
}
174+
*/
175+
176+
// STEP 3:
177+
// Batch the delegations into ReviewedApplicantRecords
178+
// NOTE: do not add the sentinel value we inserted earlier.
179+
180+
return [];
181+
}
140182
}
141183

142184
export default ReviewDashboardService;

backend/typescript/services/interfaces/IReviewDashboardService.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import {
22
ReviewDashboardRowDTO,
33
ReviewDashboardSidePanelDTO,
4+
ReviewedApplicantRecordDTO,
45
} from "../../types";
56

67
interface IReviewDashboardService {
@@ -14,6 +15,12 @@ interface IReviewDashboardService {
1415
resultsPerPage: number,
1516
): Promise<ReviewDashboardRowDTO[]>;
1617

18+
/**
19+
* Assigns each user to an applicant record to review, and
20+
* returns the newly created ReviewedApplicantRecords
21+
*/
22+
delegateReviewers(): Promise<ReviewedApplicantRecordDTO[]>;
23+
1724
/**
1825
* Fetch data that can fill out the review dashboard side panel for an applicant
1926
* @Param applicantId the ID of the applicant

0 commit comments

Comments
 (0)