Introduction

What is RecruitBook?

Without the help of technology, managing huge amount of data can be a really tedious and cumbersome task. As such, RecruitBook v1.4 is created as a offline Java desktop application for job agents to better organise the list of available job offers and prospective job candidates. By keeping in mind the aim of easing the recruitment process, it is specifically designed for job agents to perform both simple commands such as add, delete, edit, find, filter and more complicated ones such as shortlist, email. Adding on, security comes as a top priority when managing highly confidential details of all our candidates. To prevent any loss or leakage of data, our group has come up with a password-protection mechanism so that only authorised users are able to access it.

RecruitBook mainly uses a Command Line Interface(CLI) that allows you to interact with specific commands while it also has a Graphical User Interface created with JavaFX. All in all, it has a codebase of about 10,000 lines of code and we definitely welcome future collaborations with any developer.

Summary of contributions

  • Major enhancement: enhanced the find command such that it becomes more extensive

    • What it does: It allows the user to find candidates, companies and job offers based on multiple fields. Entries that satisfies any of the searched parameters will be returned.

    • Justification: The previous version of the find command only allows for the name field to be searched, making it not very user-friendly as the user should want to be able to search based on all fields.

    • Highlights: This enhancement improves the product significantly because a user can not only search for multiple prefixes but also multiple fields of the same prefix e.g. findc n/Alex n/Bob p/91234567. This fundamental feature proved to be extremely important for other features implemented by my colleagues as it allows the user to easily locate or access targeted entries based on a certain criteria.

  • Major enhancement: tweaked the find command and implemented another filter command so that locating of entries become more specific and accurate

    • What it does: It allows the user to filter candidates, companies and job offers based on multiple fields. It differs from the find command as only entries that satisfies all of the searched parameters will be returned.

    • Justification: Find command returns a very general list of entries based on the searched criteria and might still be a broad list based on the number of entries in the database. As such, having a filter command to locate the specific entries makes it more convenient and user-friendly for the user.

    • Highlights: This enhancement allows the user to look locate the entry easily if he/she already knows what to look for

  • Minor enhancement: automatically switches the user interface to the correct book when a command belonging to the other book is entered.

    • Credits: used methods ShowCandidateBookRequestEvent() and ShowCompanyBookRequestEvent() that were implemented by my colleague leerachel to switch the current view to the respective views.

  • Code contributed: Under the username of kianmengtan.

  • Other contributions:

    • Project Management:

      • Managed release v1.3.1 on GitHub

    • Documentation:

      • Did cosmetic tweaks to existing contents of the User Guide and Developer Guide: #24, #130

    • Community:

      • PRs reviewed (with non-trivial comments): #66

      • Reported bugs and suggestions for other teams in the class: #115, #118, #126, #169

      • Some parts of the find and filter feature I added was adopted by several other classmates: #192

Contributions to the User Guide

Given below are sections I contributed to the User Guide. They showcase my ability to write documentation targeting end-users.

Finding candidates / companies / job offers : findc findC findj

Each find command is differentiated by the letter that comes right after the find word. By using the find command, you can search for candidates/companies/job offers that contains any of the searched parameters.

Our app’s GUI provides two different views where the Candidate Book view and the Company Book view shows the details of all the candidates and companies respectively.

Entering commands in the other book will automatically switch your view to the correct book and still display the details of the results that you are searching for.

This note works for the below filter command as well:

  • Each search field has to come with a preceding prefix e.g. n/NAME, p/PHONE

  • The search is case insensitive e.g n/hans will match Hans

  • Only full words will be matched e.g. Han will not match Hans

  • Candidates matching at least one keyword will be returned (i.e. OR search). e.g. n/Hans n/Bo will return Hans Gruber, Bo Yang

Finds names of candidates from RecruitBook based on search fields that you have entered.

Format: findc <tag>/KEYWORD
Supported tags: n/NAME, p/PHONE, e/EMAIL, a/ADDRESS, x/AGE, h/HIGHEST EDUCATION, g/GENDER, j/JOB INTERESTED, s/EXPECTED SALARY), t/TAGS

Examples:

  • findc n/john
    (Returns all candidates with the name John)

  • findc n/alice p/91234567
    (Returns all candidates with the name alice or candidates with phone number 91234567)

Finds names of companies from RecruitBook based on searched fields that you have entered.

Format: findC <tag>/KEYWORD
Supported tags: c/COMPANY NAME, p/PHONE, e/EMAIL, a/ADDRESS

Examples:

  • findC n/HanBaoBao Pte Ltd a/Yishun MRT
    (Returns all companies with the name HanBaoBao Pte Ltd or with address saved as Yishun MRT)

Finds job offers from RecruitBook based on searched fields that you have entered.

Format: findj <tag>/KEYWORD
Supported tags: c/COMPANY NAME, j/JOB OFFER, g/GENDER, s/SALARY, x/AGE, h/HIGHEST EDUCATION

Examples:

  • findj c/KFC x/18
    (Returns all job offers either listed by KFC or job offers with age range that is suitable for the entered age)

Filter candidates / companies / job offers : filterc filterC filterj

Each filter command is differentiated by the letter that comes right after the filter word. By using the filter command, you can search for candidates/companies/job offers that contains all of the searched parameters.

Our app’s GUI provides two different views where the Candidate Book view and the Company Book view shows the details of all the candidates and companies respectively.

Entering commands in the other book will automatically switch your view to the correct book and still display the details of the results that you are searching for.

Filters names of candidates from RecruitBook based on search fields that you have entered.

Format: filterc <tag>/KEYWORD
Supported tags: n/NAME, p/PHONE, e/EMAIL, a/ADDRESS, x/AGE, h/HIGHEST EDUCATION, g/GENDER, j/JOB INTERESTED, s/EXPECTED SALARY), t/TAGS

Examples:

  • filterc n/alice p/91234567
    (Returns all candidates with the name alice and phone number 91234567)

Filters names of companies from RecruitBook based on searched fields that you have entered.

Format: filterC <tag>/KEYWORD
Supported tags: c/COMPANY NAME, p/PHONE, e/EMAIL, a/ADDRESS

Examples:

  • filterC n/HanBaoBao Pte Ltd a/Yishun MRT
    (Returns all companies with the name HanBaoBao Pte Ltd and address saved as Yishun MRT)

Filters job offers from a selected company based on searched fields that you have entered.

Format: filterj <tag>/KEYWORD
Supported tags: c/COMPANY NAME, j/JOB OFFER, g/GENDER, s/SALARY, x/AGE, h/HIGHEST EDUCATION

  • To search for job offers from only one company, you should include the name of that particular company in the searched field together with the other search fields.

Examples:

To look for job offers listed by KFC only, include the name of company in the searched field.

  • filterj c/KFC j/cashier
    (Returns all cashier job offers listed by KFC)

  • filterj c/KFC s/1500
    (Returns all job offers listed by KFC that has pay higher than $1500(inclusive))

Contributions to the Developer Guide

Given below are sections I contributed to the Developer Guide. They showcase my ability to write technical documentation and the technical depth of my contributions to the project.

Find Feature

Current Implementation

The find mechanism is implemented by creating a keywordsMap which stores the searched keywords in a HashMap. Based on the preceding prefixes of the user input, the tokenized argument is being stored as the value of the respective prefix key.

Candidates

The findCandidateCommand is facilitated by the CandidateContainsFindKeywordsPredicate which implements Predicate<Candidate> and overrides the test and equal methods such that more fields can be searched at the same time.

Companies

The findCompanyCommand is facilitated by the CompanyContainsFindKeywordsPredicate which implements Predicate<Company> and overrides the test and equal methods such that more fields can be searched at the same time.

Job Offers

The findJobOfferCommand is facilitated by the JobOfferContainsFindKeywordsPredicate which implements Predicate<JobOffer> and overrides the test and equal methods such that more fields can be searched at the same time.

Through the test method, it compares every value in the keywordsMap with the respective field of each entry and returns true if the any part of the searched value can be found in the entry’s field.

The test method is facilitated by the following operations:

  • StringUtil#isWithinRange - checks whether the the job offer has an AgeRange that satisfies the Age of the candidate.

  • StringUtil#isMoreThanOrEqualTo - checks whether the job offer has a salary offer that is higher than the candidate 's expected salary.

After which, the mechanism updates either of the respective list which is exposed in the Model interface as either Model#updateFilteredCandidateList, Model#updateFilteredCompanyList or Model#updateCompanyJobList.

Entering a prefix that is not recognized will throw a command exception.
The finding of all three entities (Candidate, Company, JobOffer) follow the same mechanism.

An example usage scenario and how the find mechanism behaves at each step is shown below.

Step 1. The user launched the application for the first time.

  1. UniqueCandidateList will be initialised with the list of candidates in RecruitBook

  2. UniqueCompanyList will be initialised with the list of saved companies in CompanyBook.

  3. UniqueCompanyJobList will be initialised with the list of saved job offers in CompanyBook.

Step 2. The user executes findc n/Alex p/91234567 command to find the candidates who is named Alex or candidates who has the phone number 91234567.

The following sequence diagram shows how the find operation works:

FindSequenceDiagram

Design Considerations

Aspect: How find feature executes
  • Alternative 1 (current choice): Having three variations of find feature for different entities.

    • Pros:

      • Greater distinction between the entities.

      • More direct and intuitive for users as candidate and company objects contain same prefixes such as phone, address and email address etc.

    • Cons:

      • More commands to deal with, same changes have to be made across all three commands.

      • It might not be that user-friendly for users who prefer an all-in-one find command.

  • Alternative 2: Have a central findManager that handles all finds.

    • Pros: Lesser commands to handle, makes application easier for user to use

    • Cons: Some fields are found in both candidate and company, making it difficult to distinguish between the two if the same prefix is entered.

Aspect: Data structure to support the find feature
  • Alternative 1 (current choice): Parses the user’s input into various arguments and compares each argument with each value in the object to test if it is contained in the object.

    • Pros:

      • Putting to and getting from a HashMap is O(1), making it quick to add value or retrieve value for each comparison.

      • User can input more than one field of the same prefix as a HashMap is used here.

    • Cons: It is messy to implement, especially when different checks have to be made for different fields.

  • Alternative 2: Creates a List for each prefix instead.

    • Pros: Easier to manage, test method should look neater.

    • Cons: Takes O(N) to iterate through the List, and does not check for duplicates. === Filter Feature ==== Current Implementation

The filter feature differs from the find feature based on the fact that if any of the searched parameter is fulfilled, the overridden test method for the find feature returns true. However, the overridden test method for filter is only asserted if all of the searched parameters are fulfilled.

Similar to the find mechanism, filter is implemented by creating a keywordsMap which stores the searched keywords in a HashMap. Based on the preceding prefixes of the user input, the tokenized argument is being stored as the value of the respective prefix key.

Through the test method, it compares every value in the keywordsMap with the respective field of each entry and returns true if the object contains all the searched fields.

The test method is facilitated by the following operations (similar to find feature):

  • StringUtil#isWithinRange

  • StringUtil#isMoreThanOrEqualTo

After which, the respective list which is exposed in the Model interface is being updated.

Entering a prefix that is not recognized will throw a command exception.
The filtering of all three entities (Candidate, Company, JobOffer) follow the same mechanism.

An example usage scenario and how the filter mechanism behaves at each step is shown below.

Step 1. The user launched the application for the first time.

  1. UniqueCandidateList will be initialised with the list of candidates in RecruitBook

  2. UniqueCompanyList will be initialised with the list of saved companies in CompanyBook.

  3. UniqueCompanyJobList will be initialised with the list of saved job offers in CompanyBook.

Step 2. The user executes filterc n/Alex e/alexyeoh@example.com command to filter the candidates who is named Alex and has the email alexyeoh@example.com.

The following sequence diagram shows how the find operation works:

FilterSequenceDiagram

Design Considerations

Aspect: Data structure to support the filter feature

Design considerations for filter command is largely similar to find command as they both use similar mechanism.

[Proposed] Find / Filter pruning feature

  • Proposed enhancement: Find / Filter pruning feature

    • Current implementation: Find or Filter command only returns an updated filteredList based on the UniqueList and the filteredList is not being committed thus the user is not able to view his/her previous searches.

    • What it does: The new proposed feature shall allow the user to perform a pruning search through which the results from the previous searches are also shown on the GUI.

    • Highlights: The new proposed find or filter has an interface which allows the user to start the find or filter feature, repeat it multiple times based on his/her needs and end it when the user is done. This interface contains various panels that starts from the MasterList at the extreme left. Following the first find or filter command, it updates the FilteredList and shows the result on the second panel. The user can carry on searching until he/she is done and exit the interface by using the cancel command.

    • How to implement it: By performing another find or filter command, it should only find or filter the entries from the previous FilteredList. This way, a pruning search can be done and this allows the user to take note of the results from his/her previous searches.