PROJECT: Infinity Book


Overview

Infinity Book (IB) is an address book application for tech recruiters who prefer to use a desktop application to manage their candidates.

IB provides recruiters with an end-to-end recruitment solution, from searching for candidates,to adding job postings and saving their resumes and interviews.

Summary of contributions

  1. Major enhancement: Job Postings

    • What it does: Allows the recruiter to add a job posting along with preferred location, skills, tags and position title. These jobs can be matched to candidate automatically, or edited, listed, searched and deleted.

    • Justification: This feature makes all the information in the Infinity Book useful to a recruiter by providing a direct method to match and access relevant data for their job.

    • Highlights:

      • For meaningful implementation of job matching, this enhancement adds a skills field to both Person and Job. This field details the skills possessed by a candidate and those required by the job.

      • This enhancement also modifies the structure of the model and data handling in the entire application has been modified to suit a Job data list in addition to Person. The implementation effected many changes to the testing tools of the Infinity Book as well.

      • Job matching is performed in a flexible manner, allowing the recruiter to ignore some fields.

  2. Minor enhancement: Auto-correct and auto-complete

    • What it does: Allows the recruiter to auto-complete and auto-correct command words automatically.

    • Justification: This feature allows the recruiter to interact with the command line with increased accuracy and speed.

    • Highlights:

      • Auto-correct finds and corrects misspelt command words at one edit distance even in copy pasted commands without affecting arguments.

      • Auto-complete cycles through all possible completion on multiple key press.

  3. Code contributed: [Functional code] [Test code]

    • Other contributions:

      • Project management:

        • Managed releases v1.3 and v1.4.1 ( 2 releases ) on GitHub

      • Enhancements to existing features:

        • Updated the add and edit command to support the skills field(Pull request #157)

      • Documentation:

        • Did cosmetic tweaks to existing contents of the User Guide: #174, #56, #160

      • Community:

        • Reported bugs and suggestions for other teams in the class (examples: 148, 147, 154, 155)

        • Opened non-trivial issues for improvement: #54, #55

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.

Job Postings

In line with the vision of offering end to end support, Infinity Book offers recruiters a very efficient way to keep track of job vacancies and match candidates to these positions.

This section details commands for managing job postings.

Add Job Posting

Want to add a newly available job vacancy to IB and match candidates to this role? Add a job posting using the postjob command.

Format: postjob j/JOB TITLE l/LOCATION t/[TAGS] s/SKILLS

Examples: postjob j/Backend Engineer l/Singapore t/FreshGrad s/Java

Job postings are matched to candidates on the basis of location, skills and tags. To neglect any of these during matching, set the field to 'ALL'.
postjob.JPG
Figure 1. PostJob Command adds Jobs into the Job Postings panel as shown.

Match Job Command

To match an existing job posting to potential candidates, use the matchjob command to filter out candidates for the chosen job.

Job matching is done on the basis of location, skills and tags. To disregard a parameter during matching, set it to 'ALL' using postjob or editjob.

Format: matchjob INDEX

Example: matchjob 1

matchJob.JPG
Figure 2. MatchJob command filters the Candidates as per Job, as shown above.

Auto-complete and auto-correct

To enhance your experience with the Command Line Interface(CLI), Infinity Book comes with built in auto-correct and auto-complete. This section explains how you can use these features to speed up your CLI experience.

Auto-complete

Auto completes command words being typed into Infinity Book.

To auto-complete a command word:

  1. Type in atleast the first character of your command word.

  2. Press TAB until your desired command word appears in the command box.

Entered text must match (case sensitive) the start of the desired command.
If no matches are available, no change is made to the input text.

Example:

  • li + TAB : Completes command word to list.

  • LI + TAB : Reports no completions found.

Use TAB repeatedly to loop through the list as many times as you need.

Auto-correct

Auto correct spell checks command words being typed into Infinity Book.

To auto-correct a command word:

Entered text must be within one edit-distance of the desired command, by removal, addition or swapping of adjacent characters
If no corrections are available, no change is made to the input text.
  1. Type in a possibly incorrect version of the command word.

  2. Press SPACE and watch the command word auto-corrected immediately.

If a copy-pasted command may contain a spelling error in the command word, press SPACE to correct the command word without affecting the arguments entered.

Example:

  • lsit + SPACE : Corrects command word to list.

  • lit + SPACE : Corrects command word to list.

  • liist + SPACE : Corrects command word to list.

  • lllist + SPACE : Does not make any correction.

While copy pasting commands with spelling errors, the SPACE key will not be available for use to insert spaces in the command while editing.

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.

Job Postings [Since v1.3]

Recruiters may have several job openings available with varying required skills, location and tags. These are represented in the Infinity Book as Job Postings. Job postings may be added or removed at any time. Existing job postings can be listed, searched, edited and deleted. Any existing job postings may be matched with the list of candidates to filter potential matches.

Job Operations and Logic

Operations performed on jobs follow the sequence of operations described in the diagram below.

  1. Command input is received by the UI component.

  2. The command execution is handled by the Logic component.

  3. The changes to data are effected by the Model component.

  4. The new Infinity Book data is saved by the Storage component.

This sequence of events is summarized in the following sequence diagram.

SequenceDiagramJobPosting
Figure 3. A high level sequence diagram showing events triggered by the postjob command.

The following job posting commands are implemented extending UndoableCommand and Command:

extends UndoableCommand extends Command

PostJobCommand
EditJobCommand
DeleteJobCommand
MatchJobCommand

ListJobCommand
FindJobCommand

The following diagram details the class relationship for Commands.

CommandsStructure
Figure 4. UML Diagram depicting the class relationship between command classes.

Adding Job Postings

Adding job postings to Infinity Book is performed by the PostJobCommand. The sequence of events triggered while adding a job posting are shown in the diagram below:

PostJobCommandSequenceDiagram
Figure 5. Adding a job posting is executed as shown above.

The PostJobCommand#executeUndoableCommand triggers addition of the Job to UniqueJobList in AddressBook#add The following code snippet demonstrates the prevention of duplicates in the UniqueJobList

    public void add(Job toAdd) throws DuplicateJobException {
        requireNonNull(toAdd);
        if (contains(toAdd)) {
            throw new DuplicateJobException();
        }
        internalList.add(toAdd);
    }

Matching Job Postings

Matching job postings to candidates in the Infinity Book is performed by the MatchJobCommand.

The sequence of events triggered while matching a job posting are shown in the diagram below:

matchJobSequenceDiagram
Figure 6. matchjob uses predicate based filtering similar to findjob and listjobs

The MatchJobCommand selects a Job object by matching the index with the last shown job list. A PersonMatchesJobPredicate is used to find matches, by looking for matches between tags, location and skills fields of the Job and Person.

Search parameters can be excluded from search when they are set to 'ALL'. Under these circumstances only the other parameters will influence the search.

The following code snippet shows how Location can be excluded from the search. Other two parameters are handles similarly.

public boolean test(Person person) {

        // .. code to set up and assign locationMatch, skillsMatch and tagsMatch
        locationMatch = isLocationMatchSatisfied(locationMatch);
        //.. similarly for skillsMatch and tagsMatch

        return locationMatch && skillsMatch && tagsMatch;
 }
 private boolean isLocationMatchSatisfied(boolean locationMatch) {
         if (notLocationBound) {
             locationMatch = true;
         }
         return locationMatch;
 }

The PersonListPanel is populated with a list of candidates who match the job according to the set parameters.



Auto-correct and Auto-complete [since v1.4]

Infinity Book enhances the user’s interaction with the application, with built in auto-correct and auto-complete. Command words that are typed in are examined for spelling errors and completions upon SPACE and TAB press respectively.

To include completion and correction support for a new command, simply add it into commandDictionary in CommandCorrection#createDictionary() as shown in code snippet.

public static void createDictionary() {
        commandDictionary = new HashSet<>();

        // .. add other command words
        commandDictionary.add(PostJobCommand.COMMAND_WORD);
}

Auto-complete Implementation

The user input is recorded in CommandBox, and upon TAB keypress, the CommandBox#navigateToCompletedCommand() method looks for command words containing the entered string as the first substring.

AutocompleteActivityDiagram
Figure 7. This activity diagram demonstrates the high level behavior of the autocomplete feature.

When CommandCorrection#updateSuggestionsList() method is called, it searches through all command words for suitable matches.

When multiple matches are available, the TAB keypress is counted, and the command box cycles through all suggestions. When no suggestions are available, the existing text is left unchanged.

Since the text in the command box is altered with each TAB press, a brief history is maintained containing the most recent suggestion made by auto-complete and original user input. Here, the user has pressed the TAB key multiple times, but expects completions based on his input, not the recent suggestion that fills the command box.

The following code snipped demonstrates the use of the suggestion history to choose the text to complete.

    public static String updateTextToComplete(String textToComplete) {
        if (textToComplete.compareTo(recentSuggestion.trim()) == 0) {
            return recentInput;
        } else {
            return textToComplete;
        }
    }

Auto-correct Implementation

Auto-correct searches command word input for potential one edit distance errors, including missed,swapped and stray characters.

Two details about the implementation are noteworthy:

  1. For seamless background operation, command words that are not recognized are automatically analysed for spelling errors on SPACE key press.

  2. In cases where commands with spell errors are copy-pasted into the command box, SPACE key press separates the command word from arguments, and corrects the command word without altering the rest of the command.

Upon being triggered, CommandBox#navigateToLikelyInput() method returns the likely correction using the mentioned heuristics.

When multiple suggestions are available, corrections obtained by removing stray character, and adding missing character are prioritized, in that order. This is in line with belief that these are the most common kinds of errors.

The following code snippet demonstrates this ability clearly.

   public static String extractCommandWord(String commandText) {
           String trimmedCommandText = commandText.trim();
           String[] wordsInCommandText = trimmedCommandText.split(" ");
           commandParameters = trimmedCommandText.replace(wordsInCommandText[0], "");
           return wordsInCommandText[0];
       }
The following section contains optional contributions demonstrating technical writing capability.

Appendix: Additional Contributions

User Guide

Q: How do I check if Infinity Book is compatible with my computer?
A: Infinity Book is compatible with Windows, Mac OS and Ubuntu with Java 1.8.0_60 or later installed. Compatibility with other UNIX distributions is not guaranteed.

To check your Java Version:

  • MAC OS/ OS-X Users:

    1. Open Spotlight using Command + Space

    2. Search for Terminal and open the application

    3. In the terminal, copy paste the following command without enclosing double quotes to find your Java version: "/Library/Internet\ Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/bin/java -version"

  • Windows users:

    1. Open Run using Windows Key + R

    2. Type cmd and press enter to open Command Prompt

    3. In Command Prompt, enter the following command without enclosing double quotes to find your Java version: "java -showversion"

  • Ubuntu users:

    1. Open Terminal using Ctrl + Alt + T

    2. In the terminal copy paste the following command without enclosing double quotes to find your Java vesion: "java -v"


Listing all jobs : listjobs

  • Description: Shows a list of all jobs posted in the Infinity Book.

  • Format: listjobs

Finding jobs by Job Title, Location, and tags: findjob

Finds jobs whose job titles, locations, or tags contain any of the given keywords.

Format: find KEYWORD [MORE_KEYWORDS]

  • The search is case insensitive. e.g backend will match Backend.

  • The order of the keywords does not matter. e.g. Engineer Backend will match Backend Engineer.

  • Only job’s title, location and tags are searched.

  • Only full words will be matched e.g. Eng will not match Engineer.

  • Jobs matching at least one keyword will be returned (i.e. OR search). e.g. Engineer will return Backend Engineer, Frontend Engineer

Example: findjob Backend Geylang
Returns Backend Engineer, Frontend Engineer, and Backend Tester whose job titles and locations match with the given keywords.

findjob
Figure 8. Job list after finding with keywords backend and geylang.

Delete Job Command

Want to remove a job posting from IB after creating? IB provides a deletejob command to delete any existing job posting from memory.

Format: deletejob INDEX

Examples: deletejob 1

deletejob.JPG
Figure 9. deletejob deletes the job posting at the specified index in the most recent listing from Figure as shown.

Index to be used as displayed in the panel.


Edit Job Command

Want to change the parameters of a job after creating? IB provides the flexibility to edit an existing job posting through the editjob command.

Format: editjob [-add-tag/-delete-tag] INDEX [j/JOBTITLE] [l/LOCATION] [s/SKILLS] [t/TAG]

Specifying -add-tag or -delete-tag causes editjob command to specifically add or delete the specified tag for the index specified tag. If unspecified, the tag list is over-written by the newly specified set of tags. This implementation mirrors the edit command.

Examples: editjob 1 j/Backend Engineer l/Singapore
editjob 1 -delete-tag j/Backend Engineer l/Singapore

At least one field must be provided for the edit command to function as expected.
editjob.JPG
Figure 10. editjob edits the first job posting as marked in diagram.

Developer Guide

Implementation Specifics

Model Component

Job postings are maintained in the Model in a UniqueJobList, enforcing uniqueness among the stored individual job postings.

UniqueJobListUML
Figure 11. UML diagram showing representation of UniqueJobList in Infinity Book.

Individual job postings are represented by the Job object with attributes Job Title, Location, Skills and Tags. The class relationship is shown in Figure 2 below.

JobUMLDiagram
Figure 12. UML diagram showing representation of Job in Infinity Book.

In addition, the Person and Job class have been modified to maintain Skills as an additional field to offer better functionality during candidate-job matching. The add and edit commands reflect these changes as well.

Together, this modifies the Model to the state shown in the following diagram.

ModelWithJobUML
Figure 13. A complete picture of the model as maintained by Infinity Book.
Storage Component

Job postings are stored in XmlAdaptedJob objects, which maintain a class relationship as shown in this diagram.

JobStorageDiagram
Figure 14. Job objects are saved using XmlAdaptedJob objects as shown above.

An example job stored in this format is reproduced below:

<jobs>
        <jobTitle>Backend Engineer</jobTitle>
        <location>Geylang</location>
        <skills>Java,SQL</skills>
        <tagged>SEIntern</tagged>
        <tagged>ATAP</tagged>
</jobs>
UI Component

The main window contains a JobListPanel, which contains individual jobs represented using JobListCards. JobListCards represent the fields in each Job using Labels and flowPanes.


Editing Job Postings

Editing job postings in the Infinity Book is performed by the EditJobCommand. The sequence of events triggered while editing a job posting are shown in the diagram below:

EditJobCommandSequenceDiagram
Figure 15. Editing a job posting is executed as shown above.

The EditJobCommand#executeUndoableCommand triggers editing of a existing Job in UniqueJobList in AddressBook#add The EditJobCommand ensures that the index specified refers to a valid index in the most recent listing of jobs. Editing jobs to cause duplicates in the UniqueJobList is prevented by throwing a DuplicateJobException.

The following code snippet demonstrates the prevention of duplicates and index checking in the UniqueJobList after editing

    public void setJob(Job target, Job editedJob) throws DuplicateJobException, JobNotFoundException {
        requireNonNull(editedJob);
        int index = internalList.indexOf(target);
        if (index == -1) {
            throw new JobNotFoundException();
        }
        if (!target.equals(editedJob) && internalList.contains(editedJob)) {
            throw new DuplicateJobException();
        }
        internalList.set(index, editedJob);
    }

To completely specify the changes to the Job object specified by EditJobCommand, an EditJobCommandDescriptor is parsed from the command, and used to update changes in the Model. Completing these operations ensures the new Job object is updated in the Infinity Book.


Delete Job Postings

Deleting job postings in the Infinity Book is performed by the DeleteJobCommand. The sequence of events triggered while deleting a job posting are shown in the diagram below:

DeleteJobCommandSequenceDiagram
Figure 16. Deleting a job posting is executed as shown above.

The DeleteJobCommand selects a Job object by matching the index with the last shown job list, and checks the index as shown in the following code snippet.

 protected void preprocessUndoableCommand() throws CommandException {
        List<Job> lastShownList = model.getFilteredJobList();
        if (targetIndex.getZeroBased() >= lastShownList.size()) {
            throw new CommandException(Messages.MESSAGE_INVALID_JOB_DISPLAYED_INDEX);
        }

        jobToDelete = lastShownList.get(targetIndex.getZeroBased());

The changes to the UniqueJobList are enacted by AddressBook#removeJob, which completes the removal of the object and triggers Storage to update the data.



Listing Job Postings

Listing all job postings in the Infinity Book is performed by the FindJobCommand. The sequence of events triggered while listing all job postings are shown in the diagram below:

listjobcommandSequenceDiagram
Figure 17. Sequence diagram above shows the sequence of events triggered on execution of listjobs

The ListJobCommand selects displays all Job objects from UniqueJobList in the JobListPanel.


Finding Job Postings

Finding job postings by keywords in the Infinity Book is performed by the FindJobCommand. The sequence of events triggered while finding a job posting are extremely similar to listing all job postings as in Figure above, differing only in the specifics of the predicate used.

The FindJobCommand selects Job objects to display by matching the keyword with the Job Title, Location or Tags, and lists all matches in the JobListPanel.