By: AY1920S2-CS2103-W15-2      Since: Feb 2020      Licence: MIT

1. Introduction

HireLah! is a productivity app designed to help busy interviewers manage multiple interview sessions in an orderly manner. During each interview session, HireLah! helps the user to keep track of interviewee information and interview rubrics in one central location, making the interview process more efficient.

HireLah! has the following main features:

  1. Manage multiple interview sessions.

  2. Manage interview rubrics for each interview session, including:

    1. Attributes to look out for in interviewees.

    2. Questions to ask interviewees.

    3. Metrics to rank interviewees based on their performance.

  3. Manage remarks and score entered by the user during an interview.

  4. Rank interviewees based on particular sets of attributes or a metric after interviews.

  5. Export interview transcripts as reference.

1.1. Purpose and Audience

This Developer Guide specifies the architecture, design and implementation of HireLah!, as well as our considerations while designing this app.

It is intended for developers, software testers, and people who would like to enhance this project in one way or another to understand HireLah! on a deeper level.

2. Setting up

Refer to the guide here.

3. Design

3.1. Architecture

ArchitectureDiagram
Figure 1. Architecture Diagram

The Architecture Diagram given above explains the high-level design of the App. Given below is a quick overview of each component.

The .puml files used to create diagrams in this document can be found in the diagrams folder. Refer to the Using PlantUML guide to learn how to create and edit diagrams.

Main has two classes called Main and MainApp. It is responsible for,

  • At app launch: Initializes the components in the correct sequence, and connects them up with each other.

  • At shut down: Shuts down the components and invokes cleanup method where necessary.

Commons represents a collection of classes used by multiple other components. The following class plays an important role at the architecture level:

  • LogsCenter : Used by many classes to write log messages to the App’s log file.

The rest of the App consists of four components.

  • UI: The UI of the App.

  • Logic: The command executor.

  • Model: Holds the data of the App in-memory.

  • Storage: Reads data from, and writes data to, the hard disk.

Each of the four components

  • Defines its API in an interface with the same name as the Component.

  • Exposes its functionality using a {Component Name}Manager class.

For example, the Logic component (see the class diagram given below) defines it’s API in the Logic.java interface and exposes its functionality using the LogicManager.java class.

LogicClassDiagram
Figure 2. Class Diagram of the Logic Component

How the architecture components interact with each other

The Sequence Diagram below shows how the components interact with each other for the scenario where the user issues the command add attribute leadership.

ArchitectureSequenceDiagram
Figure 3. Component interactions for add attribute leadership command

The sections below give more details of each component.

3.2. UI component

UiClassDiagram
Figure 4. Structure of the UI Component

API : Ui.java

The UI consists of a MainWindow that is made up of parts e.g.CommandBox, ResultDisplay, SessionPanel, InterviewPanel etc. All these, including the MainWindow, inherit from the abstract UiPart class.

The UI component uses JavaFx UI framework. The layout of these UI parts are defined in matching .fxml files that are in the src/main/resources/view folder. For example, the layout of the MainWindow is specified in MainWindow.fxml.

The UI component,

  • Executes user commands using the Logic component through the CommandExecutor functional interface.

  • After executing each command, performs command-specific view updates as instructed by the CommandResult returned by that command.

  • Listens for changes to Model data so that the UI can be updated with the modified data.

When the app is launched, SessionPanel is displayed to allow the user to manage interview sessions. When an interview session is selected, SessionPanel becomes hidden, and the InterviewPanel is displayed to allow the user to conduct interviews. This process is summarised in Figure 5, “Activity Diagram showing the toggling between SessionPanel and InterviewPanel”. The structure of the InterviewPanel is shown in Figure 6, “Structure of the InterviewPanel used to display an interview session”.

UiSwitchPanelActivityDiagram
Figure 5. Activity Diagram showing the toggling between SessionPanel and InterviewPanel
UiInterviewPanelClassDiagram
Figure 6. Structure of the InterviewPanel used to display an interview session

3.3. Logic component

LogicClassDiagram
Figure 7. Structure of the Logic Component

API : Logic.java

  1. Logic uses either the NormalParser or InterviewParser class to parse the user command, depending on the app phase stored in the Model.

  2. This results in a Command object which is executed by the LogicManager.

  3. The command execution can affect the Model (e.g. adding an attribute).

  4. The command execution may also call the storage to save the Model if the command modified the Model.

  5. The result of the command execution is encapsulated as a CommandResult object which is passed back to the Ui.

  6. The CommandResult object then instructs the Ui to perform certain actions, such as displaying the list of the current attribute. CommandResult is subclassed to provide polymorphism on the UI actions performed.

Given below is the Sequence Diagram for interactions within the Logic component for the execute("add attribute leadership") API call.

AddSequenceDiagram
Figure 8. Interactions Inside the Logic Component for the add attribute leadership Command
The lifeline for AddCommandParser should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram.
The exact details of how AddAttributeCommand gets the AttributeList from Model, then modifies the list, then passes the AttributeList to Storage is left out in this diagram.

3.4. Model component

ModelClassDiagram
Figure 9. Structure of the Model Component

API : Model.java

The Model,

  • stores a UserPref object that represents the user’s preferences.

  • stores the session data including questions, attributes, metrics, and interviewees including their interview transcripts.

  • stores the current app state, including whether the user has finalised the attributes and questions, the current phase that the app is in (pre-session, in the normal phase or in an interview), the current session and the current interviewee in focus, whether being interviewed or whose report is being viewed.

  • exposes an unmodifiable ObservableList<Attribute>, ObservableList<Question>, ObservableList<Metric>, ObservableList<Interviewee> that can be 'observed' e.g. the UI can be bound to this list so that the UI automatically updates when the data in the list change.

3.5. Storage component

StorageClassDiagram
Figure 10. Structure of the Storage Component

API : Storage.java

The Storage component,

  • contains the various classes of Storages to support the following features.

    • UserPrefsStorage saves UserPref objects in json format and read it back.

    • ModelStorage saves the Model data in json format and read it back.

    • IntervieweeStorage saves IntervieweeList to interviewee.json and read it back.

    • AttributeStorage saves AttributeList to attribute.json and read it back.

    • QuestionStorage saves QuestionList to question.json and read it back.

    • MetricStorage saves MetricList to metric.json and read it back.

    • TranscriptStorage saves Transcripts of individual interviewees to separate json files in /transcript

      • for example an interviewee with id = 1 has his/her transcript saved to transcript/1.json

IntervieweeStorageClassDiagram
Figure 11. Structure of the IntervieweeStorage Component

The IntervieweeStorage component, is responsible for saving an IntervieweeList. An Interviewee contains a Transcript which holds contain the RemarkList and a Hashmap of Attribute to score.

During the interview, the interviewee will rate certain desirable Attribute with a certain score, this is stored in the Hashmap.RemarkList contains all the Remarks for the Interviewee during the interview.

The interviewer may give a particular Remark based on certain Question, hence the RemarkList would depend on the QuestionList to check for its validity.

There is also a need to check for the validity of Hashmap by checking the Attribute given in the Hashmap against the AttributeList, which result in the dependency between JsonSerializableTranscript and AttributeList.

AttributeStorageClassDiagram
Figure 12. Structure of the AttributeStorage Component

All the Attribute are being stored as a list which is saved in a json file. When converting the json file back their Attribute Object, the JsonSerializableAttributes and JsonAdaptedAttributes classes are being deployed.

The other types of storages contains the identical structure similar to AttributeStorage , they are being omitted.

3.6. Common classes

Classes used by multiple components are in the hirelah.commons package.

4. Implementation

This section describes some noteworthy details on how certain features are implemented.

4.1. Session Feature

HireLah! differs from AddressBook significantly in that a single user will likely have many sessions, as compared to just owning a single address book. The app thus provides means of managing multiple sessions from within the app itself, instead of having to change preferences.json to create a new session or switch between sessions.

4.1.1. Proposed Implementation

Having multiple sessions and changing between them from within the app means that HireLah! cannot load data from storage on app startup.

Instead, when the app starts, the ModelManager does not have its components (IntervieweeList, AttributeList, etc.) loaded, only UserPrefs, and the AppPhase is set to PRE_SESSION.

UI displays the SessionPanel which shows the available sessions in the "sessionsDirectory" folder.

In PRE_SESSION phase, logic uses the PreSessionParser which accepts commands to open an existing session or create a new one.

Once a session is chosen, the command calls Storage#loadSession which creates new Storage components for the new session (IntervieweeStorage, AttributeStorage etc.) that save to the correct session directory. loadSession then calls Storage#initModelManager, which loads new Model components (IntervieweeList, AttributeList etc.), then replaces the current ModelManager components. AppPhase is then set to NORMAL at which the app starts its usual behavior (adding interviewees etc.).

Finally after refreshing the ModelManager, then a new UI InterviewPanel is created that observes the new Model components. Since the Model’s components have been replaced (a different set of ObservableLists), the UI can only be created at this point else the UI would be data binding to the wrong lists.

The following activity diagram shows the sequence of initialization of components when a session is opened.

SessionActivityDiagram

From the NORMAL phase, the close session command can be given, which simply un-sets the current session in Model and returns the AppPhase to PRE_SESSION. Thus the app is ready to open a new session, by resetting the storage components and the Model components, then creating a new UI InterviewPanel again.

4.1.2. Design Considerations

Aspect: How sessions are stored in the app
  • Alternative 1 (current choice): Do not store information about sessions in Model. Directly read available sessions from the /data directory (or whatever the user set the "sessionsDirectory" to in preferences.json). Scan the directory again every time the SessionPanel is displayed.

    • Pros: Information about the available directories is always synchronized with the filesystem. It is possible to copy a session from somewhere else into the "sessionsDirectory" and the app will detect it.

    • Cons: Simplistic - app naively treats all directories in the "sessionsDirectory" directory as sessions and displays them as available sessions to the user. If a folder is created externally with invalid data, it will also be treated as a session, only failing when the user tries to load it.

  • Alternative 2: Model contains a SessionList which tracks what sessions have been created or deleted.

    • Pros: User cannot create/delete sessions outside the app, changes to the sessions (new session/delete session) can be tracked within the app itself rather than repeatedly making IO calls to the filesystem.

    • Cons: There is no "single source of truth" as both the file system and the app have a list of sessions, and it is not straightforward to ensure both are synchronized, eg. if a session data directory is deleted on the file system, the app will not be aware of it.

Aspect: How session data is loaded and saved
  • Alternative 1 (current choice): Load session only when a command is given to open a session from a directory.

    • Pros: Most user friendly, managing sessions is performed through the same CLI. Memory efficient - data is loaded only exactly when needed.

    • Cons: Complex to implement

  • Alternative 2: Load all data for all sessions into memory when the app starts, open session merely selects the current session in focus and displays UI with current session data.

    • Pros: Straightforward to implement (All data can be loaded on app starting, need not change implementation from AddressBook). Switching between sessions is very straightforward.

    • Cons: Will be memory intensive as all data even from non-active sessions and past sessions will be loaded. As HireLah! may include large amounts of data in interview Transcripts, loading all the Transcripts from previous sessions will likely negatively impact startup timing. Furthermore, it is unlikely that an interviewer needs to access previous interview sessions data in a current interview, making a lot of the memory consumption wasteful.

    • Relevance consideration: It is not often that an interviewer would need to switch between sessions while interviewing for a specific thing, for example a role in the company.

  • Alternative 3: Require the user to configure the session to load before app starts up, in preferences.json

    • Pros: Simplest to implement, yet memory efficient as only the relevant data is loaded

    • Cons: Not user friendly - functionality cannot be performed within the app. User cannot discover the functionality on how to start a new session without consulting the user guide.

4.2. State Validity and Finalise Feature

4.2.1. Description

HireLah! can process numerous different inputs from the user, starting from adding an interviewee, adding a metric, opening the report of an interviewee, etc. However, not all inputs are valid at any point of time. So, we need to make sure that the right commands are accepted at the right phase. In addition, we also need to check that the input received is also valid such that the Model component of our application is always in a valid state.

A feature in our application that supports this state validity is the Finalise feature, the feature used to finalise the attributes and questions of an interview session, after the user has finished their CRUD operations to the attributes and questions. After finalising, the user can no longer change the attributes and questions of this interview session.

4.2.2. Implementation

Validity of our application state is achieved through three ways, which includes:

  • Separation of the application into 3 different phases

  • Command validation by the Parser and Model component

  • Implementation of Finalise feature

Separation of the application into 3 different phases

There are 3 different phases in our application, pre-session, normal, and interview phase. At any point of time, our application is in one of these 3 states, and this information is stored inside the model, and it can be retrieved by calling model.getAppPhase(). The reason behind the separation of the application into 3 different phases is because we need to prevent the user from entering invalid commands at any point of time. For example, you cannot start interviewing person B while you are interviewing person A. You need to end your interview with person A then you can interview person B.

When the application had just opened, it will immediately enter into the pre-session phase, where the user are not allowed to do anything except creating a new session or opening other previously-made sessions.

When the user had entered into a session, the application enter the normal phase. In this phase, the user can prompt the application to execute all of the features in the application, except opening a new session and adding interview-related information specific to an interviewee (e.g. adding a remark to person A).

When the application is in the normal phase and the user decided to interview a particular interviewee, the application will enter to the interview phase. During this phase, the user are only allowed to execute commands related to the interview process of an interviewee, which includes adding remark, scoring the attribute and adding remarks as the answer to a particular question, and toggling view between attributes, questions, or metrics.

The implementation of these 3 different phases is achieved through the presence of 3 different parsers in our application. After retrieving the current phase of the application from the Model, the Logic component will then decide which parser of these 3 should be used to parse the input. Through this, we make sure that only appropriate and valid commands at a particular phase are accepted at any point of time.

Given below are several examples of usage scenarios when the user prompts for some commands at a certain phase of the application:

Scenario 1. When the user provides a command which is not recognized by the parser that is associated with the current phase of the application, the respective parser will throw a ParseException, informing the user that this command is unknown. Suppose the app is currently at the PreSession phase, and the user tries to add a new interviewee, add interviewee Jane Doe.

SessionScenario1SequenceDiagram

Scenario 2 (Ideal Scenario). When the user provides a command which is recognized by the parser that is associated with the current phase of the application, the respective parser will parser the command and execute the respective CommandResult to the model. For an example, see Figure 8, “Interactions Inside the Logic Component for the add attribute leadership Command”.

Command Validation by the Parser and Model component

By the separation of the application into 3 different phases, we had make sure that the input that is accepted at any particular point if time are input that are appropriate at the current application phase. However, this does not guarantee that this input will be valid according to the current state of the Model. For example, if the application is currently at the normal phase, it will be able to accept the command to interview an interviewee. However, if this interviewee has been interviewed before, doing an interview to the same person should not be allowed.

Assuming that the prompt inserted by the user is accepted at the current phase of the application, given below are several examples of usage scenarios:

Scenario 1. When the user provides a command that is recognized by the current phase of the app but it is missing compulsory fields , the respective parser will check against it and throw ParseException, informing that the prompt is incomplete. For an example, see [Scenario-1-Best-Interviewee-Feature].

Scenario 2. When the user provides a complete and valid command that is recognized by the current phase of the application but is not valid for the current state, the Model will check the command and throw a CommandException, informing the user that this command is invalid for the current state. For an example, see [Scenario-2-Best-Interviewee-Feature].

Scenario 3 (Ideal Scenario). When the user provides a complete and valid command that is recognized by the current phase of the application and is valid for the current state. For an example, see [Scenario-Ideal-Best-Interviewee-Feature].

Finalise Feature

Even with all of these implementations of command accepting according to the current phase and command checking in a particular phase, there is another possibility of invalid state in our application, which happens through the modification of the interview session’s attributes and questions. For example, a metric which takes in attribute leadership and integrity has been created. Later, the user can possibly delete the attribute leadership. This makes the metric create not valid anymore.

Thus, we need a feature that can indicate that the interview session has been finalised, which means that all CRUD operations to the attributes and questions of this interview session is disallowed. CRUD operations to the attributes and questions are originally accepted in the normal phase and if the CRUD operation is valid. However, if the application has entered the finalised state, this disablement happens regardless of the validity of the phase and command.

The finalised state can be achieved through the Finalise Command when the user inputs the word finalise. Before the application is finalised the user is not allowed to hold any interview with any interviewee, create any metric and find any best interviewees. If the application has reached finalised state, the user are allowed to do so.

Assuming that the user is currently on the normal phase, the phase which accepts CRUD operations for the attributes and questions, and assuming that the given CRUD operation is valid (e.g. delete attribute leadership and attribute leadership was there previously), given below are several examples of usage scenarios when the user prompts are related to Finalise Feature:

Scenario 1. If the application has not been finalised finalised and the user tries to interview an interviewee, interview Jane Doe, the Normal Parser will parse the input and create an instance of StartInterviewCommand. The LogicManager will try to execute this StartInterviewCommand toward the model, but because it has not been finalised, it will throw a CommandException error.

FinaliseScenario1SequenceDiagram

Scenario 2. If the application has been finalised and the user tries to do add a new attribute, add attribute leadership, the Normal Parser will parse the input and create an instance of AddAttributeCommand. The LogicManager will try to execute this AddAttributeCommand toward the model, but because it has been finalised, it will throw a CommandException error.

FinaliseScenario2SequenceDiagram

Scenario 3 (Ideal Scenario). If the application has been finalised and the user tries to interview an interviewee, interview Jane Doe, the Normal Parser will parse the input and create an instance of StartInterviewCommand. The LogicManager will execute this StartInterviewCommand toward the model, and the result is returned.

FinaliseScenario3SequenceDiagram

Scenario 4 (Ideal Scenario). If the application has not been finalised and the user tries to do add a new attribute, add attribute leadership, the Normal Parser will parse the input and create an instance of AddAttributeCommand. The LogicManager will execute this AddAttributeCommand towards the model and the result is returned.

FinaliseScenario4SequenceDiagram

The following activity diagram shows the sequence of activities happening after finalise command.

FinaliseActivityDiagram

4.2.3. Design Considerations

Aspect: Maintaining the consistency of application state
  • Alternative 1 (current choice): Have finalise command and disallow CRUD operation to attributes and questions

    • Pros: There will no be any invalid values or states, like an attribute score assigned to null.

    • Cons: Once the user decide to finalise, the user can no longer edit the attributes and questions. THe user will need to create a new session if the user wants to.

  • Alternative 2: Do not have a finalise command. User can perform CRUD operation to attributes and questions at any time, including after interview has been done or some metrics have been created. Deleted attributes and questions will be removed from any part of the application, and newly created attributes will have null score and newly created questions will be assigned to no answers.

    • Pros: More flexibility for the user if the user wants to change the attributes and questions.

    • Cons: The user might not be aware about the consequence of deleting one attribute or question, which might lead to deletion of the all the metrics that uses this attribute `, removal of all `remarks associated as the answer of a question. As new attribute are assigned to null score, these interviewees could not be compared with the others with regards to this feature when the user is using the best interviewee feature. User might need to assign the score value of this newly added attribute to every single interviewees that has been interviewed before this addition, which is a tedious and unfriendly operation.

  • Alternative 3: Do not have a finalise command. User can perform CRUD operation to attributes and questions at any time, including after interview has been done or some metrics have been created. Deleted attributes and questions will be removed from any part of the application, and newly created attributes will have a default score and newly created questions will be assigned to no answers.

    • Pros: More flexibility for the user if the user wants to change the attributes and questions.

    • Cons: The user might not be aware about the consequence of deleting one attribute or question, which might lead to deletion of the all the metrics that uses this attribute `, removal of all `remarks associated as the answer of a question. As new attribute are assigned to default score, the result of comparison between this interviewee and the others might not be accurate anymore.

4.3. Find Best Interviewees Feature

4.3.1. Description

When an interviewer wants to take a decision on hiring interviewees, it will be cumbersome for the interviewer to take a look of the interviewees' score, to take a decision, especially when it comes to a large scale hiring pool. Therefore, HireLah! provides a Find Best Interviewees feature to show the top interviewees, depending on how many employees the company need, and what kind of employees does the company desire.

4.3.2. Implementation

The Find Best Interviewee feature is facilitated by the BestCommand. It has the following fields:

  • numberOfInterviewees: The number of interviewees that the interviewer wants to hire

  • paramPrefix: The prefix of the parameter that wants to be used as a comparator between interviewees.

  • paramType: The type of parameter that wants to be used by the interviewer. The possible values are the following: OVERALL, METRIC, and ATTRIBUTE.

Given below are several examples of usage scenarios when the user prompts for Best Interviewees:

Scenario 1. When the user provides a command with incomplete compulsory fields (e.g. number of interviewees), the BestCommandParser will throw ParseException, informing that the size provided is not an integer because the parser takes the preamble of the command to get the value for numberOfInterviewees.

FindBestScenario1SequenceDiagram

Scenario 2. When the user provides a command with valid fields, yet there are no interviewees that has been interviewed, a CommandException is thrown instead, informing that there is no interviewee that has been interviewed, thus no result can be shown.

FindBestScenario2SequenceDiagram

Scenario 3. When the user provides a command with multiple parameters that want to be used for a comparator, a ParseException is thrown instead, informing that the user has provided more than 1 parameter.

FindBestScenario3SequenceDiagram

Scenario 4 (Ideal Scenario). Here is the Sequence Diagram for FindBestCommand for an ideal case (minor method calls are omitted):

FindBestSequenceDiagram
Getting the best interviewees from Model

To obtain the list of best interviewees, the BestCommand has a private method called getBest which takes in a model, a comparator, and size. The getBest method retrieves the best interviewees using an Iterator design pattern. It does the following:

  • Retrieve intervieweeList and bestNIntervieweeList from model

  • Clear the current bestNIntervieweeList

  • Since the comparator only compares interviewees that have been interviewed, a filter operation needs to be done to filter out interviewees that have not been interviewed

  • Sort the filtered interviewees based on the comparator

  • Insert the first size interviewees to the bestNIntervieweeList

There are cases where getBest method does not reflect exactly the number of interviewees that the user entered:

  • The number of interviewees that has been interviewed is less than the number of interviewees the user prompted. In this case, all the interviewed interviewees will be shown, in a sorted order based on their score. Therefore, the number of interviewees shown will be less than what the user entered.

  • There are ties between interviewees at the cut-off position. For example, a case where the fifth interviewee, and the sixth interviewee have the same scores, while the user prompts for the best 5 interviewees. In this case, the sixth interviewee will also be shown. Therefore, the number of interviewees shown will be more than what the user entered.

Below is the activity diagram to summarize and show how getBest method works:

GetBestActivityDiagram

4.3.3. Design Considerations

Aspect: How to display the best interviewees
  • Alternative 1 (current choice): Clears the current content of best interviewees, then add the best interviewees one by one.

    • Pros: Easy to implement.

    • Cons: Have a slightly lower execution time.

  • Alternative 2: Creates a new ObservableList for the best interviewee list, then change the Model’s best interviewees list to point to this list, and the MainWindow’s BestIntervieweeListPanel.

    • Pros: Have a slightly faster theoretical execution time.

    • Cons: The implementation is slightly trickier compared to alternative 1 since it involves multiple components of the app.

4.4. Updating UI elements after user commands

4.4.1. Description

A lot of things goes on during the interview process. As such, HireLah! needs to handle different types of input commands from the user and update the GUI accordingly in response. AddressBook3, which HireLah! is based on, uses the CommandResult class to achieve this. Based on our design of HireLah! however, there are three types of command outcomes that the user’s input may give:

  1. Toggle to see a different list of information, for example toggling from the SessionPanel, which lists out the information of all interview sessions created on HireLah!, to InterviewPanel, which shows the details of one interview session.

  2. Scroll to a particular entry in a list. This is required for the goto command, which allows the user to see an interviewee’s remarks at a particular timestamp by scrolling the RemarkList to a particular index.

  3. Simply printing out a message in the ResultDisplay to show the user.

4.4.2. Implementation

In order to handle all three types of command outcomes, we have decided to extend the original CommandResult class to produce two new subclasses: ToggleCommandResult, which handles type 1 outcomes, and NavigationCommandResult, which handles type 2 outcomes. The original CommandResult class is used to handle type 3 outcomes.

In addition, we have implemented the ToggleView enum, which is returned as an attribute in ToggleCommandResult to inform the UI on the UI component to toggle to.

Given below is a class diagram to summarise the characteristics of these three CommandResult classes, as well as the ToggleView enum:

CommandResultClassDiagram

4.4.3. Design Considerations

Aspect: How to design and update the UI components

ToggleCommandResult also signals that the relevant UI component needs to be updated, and decisions have to be made on how the implicated UI components should be updated

  • Alternative 1: Reinitialise the entire UI after every command

    • Pros: This will definitely update the changes required of the UI accordingly, as the new UI can be built to reflect the current state of the Model.

    • Cons: This method is extremely inefficient, and may slow down the application considerably when the user has entered a lot of information.

  • Alternative 2: Update only the UI component affected if necessary, for eg IntervieweeListPanel

    • Pros: This is a lot more efficient compared to Alternative 1.

    • Cons: Some commands, such as :end which ends an interview with an interviewee needs multiple UI components to be updated, such as IntervieweeListPanel, RemarkList and SessionInformationCard, and this method only updates IntervieweeListPanel as this command returns the ToggleView enum INTERVIEWEE.

Current Implementation: We have taken a compromise between the two approaches. UI components that are often updated together are grouped together, such as IntervieweeListPanel and SessionInformationCard, such that they are always updated together. In addition, we made use of Observable classes to reduce the number of times an UI component needs to be reinitialised.

4.5. Saving of the Interviewee

4.5.1. Description

The Interviewee class contains various fields, one of the more troublesome fields to save is the Transcript of the Interviewee as it contains the RemarkList and a Hashmap of Attribute to score, which is stored as Double. Additionally, Interviewee can only have Transcript once they have been interviewed and when the model is finalised. Hence, our group decided to split the saving of the Transcript from other fields of the the Interviewee such as the name of the Interviewee.

Furthermore, since each interviewee contains their own Transcript, which contains a list of remarks which may potentially become very long (if an interview lasts for an hour, there could be hundreds or thousands of remarks), it would harm performance if every change to the interviewee list required saving of each interviewee and their entire transcript.

Note that this is also unnecessary since the only time a transcript is changed and thus saved is during an interview. The saving of the transcript can thus be effectively decoupled from the interviewee class.

4.5.2. Implementation

To achieve this, we make use of the proxy class JsonAdaptedInterviewee which acts as a data carrier between the interviewee stored in json and the actual Interviewee class. This class can be constructed from an Interviewee, and has a toModelType method which converts it back to a Interviewee.

JsonAdaptedInterviewee does not store the transcript object. Instead it contains a boolean flag "transcript", which indicates if a interviewee has a transcript. This allows toModelType to load said transcript if present from a different file, thus restoring the orignal Interviewee, without having to save the interviewee together with the transcript.

4.6. Logging

We are using java.util.logging package for logging. The LogsCenter class is used to manage the logging levels and logging destinations.

  • The logging level can be controlled using the logLevel setting in the configuration file (See Section 4.7, “Configuration”)

  • The Logger for a class can be obtained using LogsCenter.getLogger(Class) which will log messages according to the specified logging level

  • Currently log messages are output through: Console and to a .log file.

Logging Levels

  • SEVERE : Critical problem detected which may possibly cause the termination of the application

  • WARNING : Can continue, but with caution

  • INFO : Information showing the noteworthy actions by the App

  • FINE : Details that is not usually noteworthy but may be useful in debugging e.g. print the actual list instead of just its size

4.7. Configuration

Certain properties of the application can be controlled (e.g user prefs file location, logging level) through the configuration file (default: config.json).

5. Documentation

Refer to the guide here.

6. Testing

Refer to the guide here.

7. Dev Ops

Refer to the guide here.

Appendix A: Product Scope

Target user profile:

  • an interviewer, or anyone who needs to conduct interviews

  • has a need to manage and a large number of interviewees, their resumes and interview transcripts in an organized manner.

  • prefer desktop apps over other types

  • can type fast

  • prefers typing over mouse input

  • is reasonably comfortable using CLI apps

Value proposition: manage contacts faster than a typical mouse/GUI driven app

Appendix B: User Stories

Priorities: High (must have) - * * *, Medium (nice to have) - * *, Low (unlikely to have) - *

Priority As a …​ I want to …​ So that I can…​

* * *

New Interviewer

See usage instructions

Learn to use HireLah!

* * *

Interviewer

Create a new interview session

Initialise the interviewee, their details, attributes and questions specific to this interview session.

* * *

Interviewer

Add a new interviewee to an interview session

Keep track of interviewees applying for a job opening

* * *

Forgetful Interviewer

View the list of interviewees and their interview status

Remember their names and interview those who have not been interviewed

* * *

Interviewer

Delete an interviewee from an interview session

Remove interviewees who withdrew their job application

* *

Interviewer

Update the information of interviewees

Ensure that I have the most up to date information about the interviewees

* *

Interviewer

Add the interviewees' resumes in the app

Not need to manage the resumes externally, possibly missing out on some interviewees and making it more difficult to access

* * *

Interviewer

Make a list of attributes

Remind myself of what to look out for in the interviewees while interviewing them

* * *

Interviewer

Modify the list of attributes

Update the interview session’s rubrics as needed

* * *

Interviewer

Make a list of questions to ask

Ask each interviewee the same set of questions

* * *

Fickle minded Interviewer

Modify the list of questions

Make necessary changes if I decide I want to ask different questions.

* *

Busy Interviewer

Have an easy way to refer to each interviewee

Do not have to remember the full name / ID of each interviewee

* * *

Interviewer

Finalise the attributes and questions for an interview session

Assess all interviewees fairly based on the same attributes and asked the same questions

* * *

Interviewer

See the list of attributes and questions during an interview

Refer back to the list of attributes and questions and assess all interviewees according to these exact parameters.

* * *

Interviewer

Record the remarks of my interviewees during the interview session

Recall details that happened during the interview

* * *

Interviewer

Indicate when a question was asked during the interview

Assess and review the interviewee’s answers to a particular question

* * *

Interviewer

Score the interviewee for each attribute during the interview

Have some basis to compare interviewees later.

*

Interviewer

Have an audio recording for every interview session

Refer back to it to minimize missing details

* * *

Interviewer

Open the interview transcript of an interviewee after interviewing him/her

Recall my impressions of the interviewee when making decisions on who to select.

* *

Interviewer

Easily find the remarks I made at some time during the interview

Not need to slowly scroll through the entire transcript.

* * *

Interviewer

Jump to the point where each question was asked

Focus on the important parts of the interview.

* * *

Interviewer

Find the best few interviewees based on their scores for the attributes

Narrow down the selection when making the decision.

* * *

Interviewer

Find the best few interviewees based on an attribute

Narrow down the selection when making the decision.

* * *

Interviewer

Find the best few interviewees based on a custom metric

Value certain attributes over others and give the most weightage to the most critical characteristics.

*

Interviewer

Play audio of a recording of an interviewee’s interview session at a given time

Recall what the interviewee said.

*

Interviewer

Visualise the score of attributes of all interviewees

To make easy visual comparisons.

* *

Interviewer

Export the full report of each interviewee

Share the information with others.

* *

Interviewer

App to be password protected

Protect sensitive information from prying eyes

* *

Experienced Interviewer

Perform all tasks from the keyboard

Not waste time moving between the cursor and the keyboard, especially while taking notes.

Appendix C: Use Cases

(For all use cases below, the System is the HireLah! and the Actor is the User, unless specified otherwise)

Use case: UC01 - Create new Session

MSS

  1. User chooses to create a new Interview Session

  2. User provides a name for the Session (eg. CEO Interview)

  3. HireLah! creates the new Session and saves it

  4. HireLah! automatically opens the Session (UC02)

    Use case ends.

Extensions

  • 2a. User provides an invalid name or an existing session name.

    • 2a1. HireLah! shows an error message.

      Use case resumes at step 1.

Use case: UC02 - Open existing Session

MSS

  1. User chooses to open a previous Interview Session

  2. User provides the name of previous session (eg. CEO Interview)

  3. HireLah! restores data from the session from memory

    Use case ends.

Extensions

  • 2a. No such previous session exists.

    • 2a1. HireLah! shows an error message.

      Use case resumes at step 2.

Use case: UC03 - Delete session

MSS

  1. User chooses to delete a session.

  2. User provides the name of the session to delete.

  3. HireLah! deletes all the session data of the given session. Use case ends.

Extensions

  • 2a. No such previous session exists.

    • 2a1. HireLah! shows an error message.

      Use case resumes at step 2.

Use case: UC04 - Add Interviewee

Precondition

  1. User has opened a session (UC02)

MSS

  1. User chooses to create a new Interviewee.

  2. User provides a name, and an alias (optional) for the Interviewee.

  3. HireLah! creates the new Interviewee and saves it.

    Use case ends.

Extensions

  • 2a. An interviewee with the exact name already exists

    • 2a1. HireLah! shows an error message.

      Use case resumes at step 2.

  • 2b. The alias given already refers to another interviewee (either the name or alias)

    • 2b1. HireLah! creates the new Interviewee without the alias.

    • 2b2. HireLah! displays an error message regarding the repeated alias.

      Use case ends.

Use case: UC05 - Delete Interviewee

Precondition

  1. User has opened a session (UC02)

MSS

  1. User decides which Interviewee that wants to be deleted from the list.

  2. User provides either the full name, the alias, or the ID.

  3. HireLah! deletes the interviewee with the following details provided.

    Use case ends.

Extensions

  • 2a. There is no interviewee with the given identifier.

    • 2a1. HireLah! shows an error message.

      Use case resumes at step 2.

Use case: UC06 - Update Interviewee

Precondition

  1. User has opened a session (UC02)

MSS

  1. User chooses to edit an interviewee.

  2. User provides either the full name, the alias, or the ID.

  3. User provides the updated fields, either name, alias or both.

  4. HireLah! updates the interviewee information.

    Use case ends.

Extensions

  • 2a. There is no interviewee with the given identifier.

    • 2a1. HireLah! shows an error message.

      Use case resumes at step 2.

  • 3a. Either the given new name or alias is invalid (a duplicate, or an illegal value)

    • 3a1. HireLah! shows an error message.

      Use case resumes at step 2.

Use case: UC07 - Add Attribute

Precondition

  1. User has opened a session (UC02)

  2. User has not finalised the session attributes and questions (UC15)

MSS

  1. User chooses a name for the attribute.

  2. HireLah! adds the attribute with a given name to the list.

    Use case ends.

Extensions

  • 2a. There is already an attribute with the identical name

    • 2a1. HireLah! shows an error message.

      Use case resumes at step 1.

Use case: UC08 - Delete Attribute

Precondition

  1. User has opened a session (UC02)

  2. User has not finalised the session attributes and questions (UC15)

MSS

  1. User indicates which attribute to delete, either by full name or by a unique prefix.

  2. HireLah! removes the attribute with the given prefix from the list.

    Use case ends.

Extensions

  • 2a. There is no attribute with the given prefix.

    • 2a1. HireLah! shows an error message.

      Use case resumes at step 1.

  • 2b. There are multiple attributes with the same given prefix.

    • 2b1. HireLah! shows an error message.

      Use case resumes at step 1.

Use case: UC09 - Update Attribute

Precondition

  1. User has opened a session (UC02)

  2. User has not finalised the session attributes and questions (UC15)

MSS

  1. User indicates the attribute to edit, either by its full name or by a unique prefix.

  2. User gives the updated name of the attribute.

  3. HireLah! updates the attribute with the given name.

    Use case ends.

Extensions

  • 1a. There is no attribute with the given prefix.

    • 1a1. HireLah! shows an error message.

      Use case resumes at step 1.

  • 1b. There are multiple attributes with the same given prefix.

    • 1b1. HireLah! shows an error message.

      Use case resumes at step 1.

  • 2a. The updated attribute name already exists.

    • 2a1. HireLah! shows an error message.

      Use case resumes at step 1.

Use case: UC10 - Add Question

Precondition

  1. User has opened a session (UC02)

  2. User has not finalised the session attributes and questions (UC15)

MSS

  1. User chooses to add a question and types out the full question.

  2. HireLah! adds the question with the given to the list.

    Use case ends.

Extensions

  • 1a. There is already a question with the identical description.

    • 1a1. HireLah! shows an error message.

      Use case resumes at step 1.

Use case: UC11 - Delete Question

Precondition

  1. User has opened a session (UC02)

  2. User has not finalised the session attributes and questions (UC15)

MSS

  1. User enters the index of the question that the user wants deleted.

  2. HireLah! removes the question with the given index from the list.

    Use case ends.

Extensions

  • 1a. The index given is not within the valid range.

    • 1a1. HireLah! shows an error message.

      Use case resumes at step 1.

Use case: UC12 - Update Question

Precondition

  1. User has opened a session (UC02)

  2. User has not finalised the session attributes and questions (UC15)

MSS

  1. User enters an index of the question and the updated question.

  2. HireLah! updates the description of the question with the given index.

    Use case ends.

Extensions

  • 1a. The index given is not within the valid range.

    • 1a1. HireLah! shows an error message.

      Use case resumes at step 1.

Use caseL UC13 - Upload Interviewee Resume

Precondition

  1. User has opened a session (UC02)

MSS

  1. User chooses to upload the resume of the interviewee the user specifies.

  2. User provides the path to the resume file.

  3. HireLah! remembers this path.

    Use case ends.

Extensions

  • 1a. HireLah! cannot find the user specified whether by id, alias or full name.

    • 1a1. HireLah! displays an error message.

      Use case resumes at step 1.

  • 2a. The file specified by the path does not exist.

    • 2a1. HireLah! displays an error message.

      Use case resumes at step 1.

  • 2b. No file is specified.

    • 2b1. HireLah! shows the User files to choose from.

    • 2b2. User chooses a file.

      If User cancels the file choosing dialog, HireLah! displays an error message. Else Use case resumes at step 3.

Use caseL UC14 - Open Interviewee Resume

Precondition

  1. User has opened a session (UC02)

MSS

  1. User chooses to open the resume of a specified interviewee.

  2. HireLah! opens the resume.

    Use case ends.

Extensions

  • 1a. The identifier provided is not the id, alias or full name of any interviewee.

    • 1a1. HireLah! displays an error message.

      Use case resumes at step 1.

  • 1b. The identified interviewee does not have a resume uploaded (UC13)

    • 1b1. HireLah! displays an error message.

      Use case resumes at step 1.

Use case: UC15 - Finalize Questions and Attributes

Precondition

  1. User has opened a session

Guarantees

  1. Attribute list and Question list cannot be changed after finalizing

MSS

  1. User chooses to finalize the current list of questions and attributes Use case ends

Use case: UC16 - Interview an Interviewee

Precondition

  1. User has finalized questions and attributes for the session (UC15).

MSS

  1. User gives name or alias or id of Interviewee to interview

  2. HireLah! displays the interview questions

  3. User writes remarks while conducting the interview

  4. HireLah! saves the remark and the time during the interview when the remark was made

  5. User records answers to the interview questions (UC17)

  6. User scores interviewee on each attribute (UC18)

  7. User chooses to end the interview

    Use case ends.

Extensions

  • 1a. Name, alias or id does not refer to any interviewee.

    • 1a1. HireLah! shows an error message.

      Use case resumes at step 1.

  • 1b. Interviewee specified has already been interviewed.

    • 1b1. HireLah! shows an error message.

      Use case ends.

  • 7a. User has not scored the interviewee in all attributes

    • 7a1. HireLah! shows an error message.

      Use case resumes from step 6.

Use case: UC17 - Record Question Answer

Precondition

  1. User is interviewing an interviewee (UC16).

MSS

  1. User indicates question to record answers for

  2. User takes notes of the answer to the question

  3. HireLah! saves the remark and the time during the interview when the remark was made

    Use case ends.

Extensions

  • 1a. Question number is invalid (too large, or less than 1)

    • 1a1. HireLah! shows an error message.

      Use case ends.

Use case: UC18 - Score Interviewee

Precondition

  1. User is interviewing an interviewee (UC16).

MSS

  1. User indicates attribute to score

  2. User indicates score to give

  3. HireLah! overwrites any previous score given with the new score

    Use case ends.

Extensions

  • 1a. Attribute does not exist.

    • 1a1. HireLah! shows an error message.

      Use case ends.

  • 2a. Score given is not a number

    • 2a1. HireLah! shows an error message.

      Use case resumes from step 1.

  • 2b. Score given is out of the range of allowed values (0-10).

    • 2b1. HireLah! shows an error message.

      Use case resumes from step 1.

Use case: UC19 - Working with an Interviewee Report

Precondition

  1. User has stopped an interview session(UC16) with any interviewee.

MSS

  1. User chooses the interviewee that wants to be examined.

  2. User opens the interviewee transcript, containing the remarks that are added during the interview.

  3. User may navigate by questions and time (UC20) to view their remarks for those questions or at that time.

  4. User closes the interviewee report when he/she is done.

    Use case ends.

Extensions

  • 1a. User has not started an interview (UC16) with this interviewee.

    • 1a1. HireLah! shows an error message.

      Use case ends.

  • 1b. There is no interviewee with a given details (alias, ID, or fullname).

    • 1b1. HireLah! shows an error message.

      Use case resumes from step 1.

Use case: UC20 - Navigating through the Interview report

Precondition

  1. User is viewing an interview report (UC19).

MSS

  1. User provides the time or question number for which he/she wishes to see the remarks made during that period of the interview

  2. HireLah! scrolls the interview report to the remark made at the moment specified.

    Use case ends.

Extensions

  • 1a. Time provided is too large (beyond the end time)

    • 1a1. HireLah! scrolls to the end of the interview.

      Use case ends.

  • 1b. Question number provided does not correspond to a question that was answered.

    • 1b1. HireLah! shows an error message.

      Use case ends.

C.1. Use case: UC21 - Choose Best Interviewees

Precondition

  1. User has interviewed at least 1 interviewee (UC16).

MSS

  1. User indicates the metric (average, best by single attribute, or user-defined weightage) to sort interviewees by

  2. User indicates the number of top interviewees to show

  3. HireLah! displays the sorted and filtered list of top candidates

    Use case ends.

Extensions

  • 1a. The indicated metric does not exist

    • 1a1. HireLah! shows an error message.

      Use case resumes from step 1.

  • 2a. The indicated number of interviewees to show is larger than the number of interviewees

    • 2a1. HireLah! sorts and displays all interviewed interviewees in sorted order.

      Use case ends.

  • 3a. There are ties amongst the interviewees.

    • 3a1. HireLah! includes all ties, even if it exceeds the number specified in step 2.

      Use case ends.

Use case: UC22 - Add Metric

Precondition

  1. User has finalized questions and attributes for the session (UC15).

MSS

  1. User chooses the name of the metric and the weight of each attribute

  2. HireLah! adds the metric to the list.

    Use case ends.

Extensions

  • 1a. Any attribute specified is not in the attribute list.

    • 1a1. HireLah! shows an error message.

      Use case resumes from step 1.

  • 1b. Any weight provided is an invalid number.

    • 1b1. HireLah! shows an error message.

      Use case resumes from step 1.

  • 1c. The name specified is already used for another metric.

    • 1c1. HireLah! shows an error message.

      Use case resumes from step 1.

Use case: UC23 - Delete Metric

Preconditions

  1. User has finalized questions and attributes for the session (UC15).

MSS

  1. User indicates the metric to delete by its name, or a unique prefix.

  2. HireLah! deletes the metric with the given prefix.

    Use case ends.

Extensions

  • 1a. There is no metric with the given prefix

    • 1a1. HireLah! shows an error message.

      Use case ends.

  • 1b. There are multiple metrics with the given prefix

    • 1b1. HireLah! shows an error message.

      Use case ends.

Use case: UC23 - Update Metric

MSS

  1. User indicates the metric to edit by its name or a unique prefix.

  2. User provides a new name, or an updated list of weights for attributes.

  3. HireLah! updates the metric with the new name and/or the new weights.

    Use case ends.

Extensions

  • 1a. There is no metric with the given prefix

    • 1a1. HireLah! shows an error message.

      Use case ends.

  • 1b. There are multiple metrics with the given prefix

    • 1b1. HireLah! shows an error message.

      Use case ends.

  • 2a. The new name is invalid (uses illegal characters or is a duplicate)

    • 2a1. HireLah! shows an error message.

      Use case ends.

  • 2b. Any attribute specified cannot be found or the weight is not a valid number.

    • 2b1. HireLah! shows an error message.

      Use case ends.

Appendix D: Non Functional Requirements

  1. Should work on any mainstream OS as long as it has Java 11 or above installed.

  2. Should be able to load a session containing up to 1000 interviewees and their interview transcripts within 3 seconds.

  3. Each command should be intuitively named so the interviewer can get productive with the app without constantly referencing the User Guide.

  4. The application should be easy to use even for interviewers who have never used command-line programs before.

  5. The UI design of the application should be intuitive to interviewers to navigate between the different phases of the application.

  6. The application should not be larger than 100Mb.

  7. The application should save data after every command and not require interviews to save it manually.

  8. The application not cause interviewers to lose all their progress if the app crashes in the middle of an interview. The user should be able to continue the interview where they left off after restarting the app.

  9. Our code should allow other developers to add new features in the application easily.

Appendix E: Glossary

Mainstream OS

Windows, Linux, Unix, OS-X

Private contact detail

A contact detail that is not meant to be shared with others

Appendix F: Instructions for Manual Testing

Given below are instructions to test the app manually.

These instructions only provide a starting point for testers to work on; testers are expected to do more exploratory testing.

F.1. Launch and Shutdown

  1. Initial launch

    1. Download the jar file and copy into an empty folder

    2. Double-click the jar file
      Expected: Shows the GUI with an empty session screen.

  2. Shutdown

    1. Type exit in the command line.
      Expected: The app is closed, with all the data saved.

F.2. Create, Open and Close Session

  1. Test case: new session ceo
    Expected: It will create a session named ceo and the GUI switches to the normal mode.

  2. Test case: new session ceo then close session
    Expected: It will create a session named ceo and the GUI switches to the normal mode, then after executing the second command, it closes the session and goes to the session screen.

F.3. Create Interviewees, and Attributes

  1. Prerequisites: The app is in a session and the session is not finalized yet.

  2. Test case: add interviewee Jane
    Expected: An interviewee named Jane is added to the interviewee list.

  3. Test case: add interviewee Dr. Bro the 3rd -aka Bro
    Expected: An interviewee named Dr. Bro the 3rd with alias Bro is added to the interviewee list.

  4. Test case: add attribute nonalphanums123 Expected: An error message is shown that the attribute cannot be added because it contains non alphabets.

  5. Test case: add attribute leadership Expected: An attribute named leadership is added to the list

  6. Test case: add attribute Expected: An error message showing that the format is invalid.

  7. Test case: add interviewee Expected: An error message showing that the format is invalid.

F.4. Delete Interviewees, and Attributes

  1. Prerequisites: The session only have an interviewee named Jane with alias Doe, and id 1, and an attribute named leadership, and the session is not finalized yet.

  2. Test case: delete interviewee Bob
    Expected: An error message is shown, stating that there is no interviewee identified with Bob.

  3. Test case: delete interviewee Doe
    Expected: The interviewee is deleted from the list.

  4. Test case: delete attribute tenacity
    Expected: An error message is shown, stating that there is no attribute named tenacity

  5. Test case: delete attribute lea
    Expected: The attribute leadership is deleted because lea is a unique prefix for leadership.

  6. Test case: delete attribute Expected: An error message showing that the format is invalid.

  7. Test case: delete interviewee Expected: An error message showing that the format is invalid.

F.5. Edit Interviewees, and Attributes

  1. Prerequisites: The session only have an interviewee named Jane with alias Doe, and id 1, and an attribute named leadership, and the session is not finalized yet.

  2. Test case: edit interviewee Bob -n Bobby
    Expected: An error message is shown, stating that there is no interviewee identified with Bob.

  3. Test case: edit interviewee Doe -n John
    Expected: Changes the name of the interviewee from Jane to John.

  4. Test case: edit interviewee Doe -aka brother
    Expected: Changes the alias of the interviewee from Doe to brother.

  5. Test case: edit interviewee 1 -n Bob -aka Bobby
    Expected: Changes the name of the interviewee from Jane to Bob, and the alias from Doe to Bobby

  6. Test case: edit attribute tenacity -a dignity
    Expected: An error message is shown because the attribute tenacity does not exist.

  7. Test case: edit attribute lea -a dignity
    Expected: The attribute leadership is changed to dignity because lea is a unique prefix for leadership in this case.

  8. Test case: edit attribute Expected: An error message showing that the format is invalid.

  9. Test case: edit interviewee Expected: An error message showing that the format is invalid.

F.6. Create Questions

  1. Prerequisites: The session is not finalized yet.

  2. Test case: add question what is this question?
    Expected: A question with a deescription what is this question? will be added to the question list.

F.7. Edit Questions

  1. Prerequisites: The session is not finalized yet and there is one question in the session with a description how are you?

  2. Test Case: edit question 1 -q what ya doin?
    Expected: The question’s description will be changed to what ya doin?.

  3. Test Case: edit question -1 -q what ya doin?
    Expected: An error message is shown because there is no question with number -1.

F.8. List Interviewees, Questions, and Attributes

  1. Prerequisites: The app is already in a session

  2. Test case: attributes
    Expected: Shows all the attributes that have been added in the session. They are shown at the right panel of the GUI.

  3. Test case: questions
    Expected: Shows all the questions that have been added in the session. They are shown at the right panel of the GUI.

  4. Test case: interviewees
    Expected: Shows all the interviewees that have been added in the session. They are shown at the left panel of the GUI.

F.9. Upload Resume

  1. Prerequisites: There is an interviewee named Bob, with alias Bobby and id 1, and his resume located at path.

  2. Test case: upload 5
    Expected: An error message will be shown, stating that there is no interviewee that haa 5 as an identifier.

  3. Test case: upload 1
    Expected: A window will pop up, that allows to choose a file that serves as Bob’s resume.

  4. Test case: upload 1 -p unidentifiedpath
    Expected: An error message will be shown, because there is no file at the given path.

  5. Test case: upload 1 -p path
    Expected: The file at path will be served as the resume of Bob.

F.10. Open Resume

  1. Prerequisites: There are two interviewees, one has an alias Alice, and a resume has been uploaded under her name, and the other is named Bob, and there is no resume under him yet.

  2. Test case: resume Alice
    Expected: A window pops up, showing the resume of Alice.

  3. Test case: resume Bob
    Expected: An error message is shown because there is no resume uploaded for Bob yet.

F.11. Interviewing

  1. Prerequisites: The session has been finalized and there is an interviewee named Jane.

    1. Test case: interview Bob
      Expected: An error message will be shown, because there is no interviewee that is identified as Bob.

    2. Test case: interview Jane
      Expected: The GUI will switch to interview screen, and the app enters the Interview Phase.

  2. Prerequisites: The app is in interview mode with an interviewee named Jane, has her resume uploaded and there is an attribute named leadership, and a question with a description how do you do?.

    1. Test case: this girl is very good
      Expected: The sentence will be added as a remark. The GUI will show the remark with the corresponding timestamp.

    2. Test case: :set agility 4
      Expected: An error message will be shown since there is no attribute with name agility.

    3. Test case: :set leadership 11
      Expected: An error message will be shown since the score that can be added is between 0 to 10 inclusive.

    4. Test case: :set lea 6
      Expected: The score of attribute leadership will be set to 6 since lea is a unique prefix for leadership.

    5. Test case: start q10
      Expected: An error message will be shown since there is no question with number 10.

    6. Test case: start q1
      Expected: The GUI will show the starting point of the question 1.

    7. Test case: :attributes
      Expected: The right panel of the GUI will show all the attributes that have been added, which in this case shows one attribtue, which is leadership.

    8. Test case: :metrics
      Expected: The right panel of the GUI will show all the metrics that have been added, which in this case is empty.

    9. Test case: :questions
      Expected: The right panel of the GUI will show all the questions that have been added, which in this case, is a question how do you do?.

    10. Test case: :resume
      Expected: A window will pop up, showing the resume of Jane.

    11. Test case: :end
      Expected: An error message will be shown since there is an attribute that has not been scored.

    12. Test case: :set lea 6 then :end
      Expected: First, the score of attribute leadership will be set to 6. Then, the interview is ended and the GUI shows the normal screen.

F.12. Dealing with Interviewee’s Report

  1. Prerequisites: There are two interviewees, Alice who has been interviewed, and Bob who has not been interviewed yet.

    1. Test case: open Bob
      Expected: An error message will be shown since Bob has not been interviewed.

    2. Test case: close report
      Expected: An error message will be shown since currently the app is not opening any report.

    3. Test case: open Alice
      Expected: The GUI will show the report of Alice, which is identical to the interview screen, showing the remarks that have been added, as well as the scores that have been added.

    4. Test case: open Alice then close report
      Expected: The GUI will show the report of Alice, similar to the previous case. Then, after executing the close report command, the GUI will switch back to the normal screen.

    5. Test case: report Bob
      Expected: An error message will be shown, because Bob has not been interviewed yet.

    6. Test case: report Alice
      Expected: A success message will be shown, specifying the directory where the PDF file is exported. The PDF file can be found at the specified directory.

  2. Prerequisites: The app is opening Alice’s report. The report has several remarks, and there are 2 questions, the first question was asked during the interview, and the second one was not. The interview is done within 10 minutes.

    1. Test case: goto q100
      Expected: An error message will be shown, indicating that there are only 2 questions in the interview session.

    2. Test case: goto q2
      Expected: An error message will be shown, indicating that the second question was not answered during the interview.

    3. Test case: goto q1
      Expected: The remark panel of the GUI will navigate to the first remark after the first question is started.

    4. Test case: goto 0.00
      Expected: The remark panel of the GUI will navigate to the very first remark.

    5. Test case: goto 5.00
      Expected: The remark panel of the GUI will navigate to the first remark after the fifth minute.

    6. Test case: goto 15.00
      Expected: The remark panel of the GUI will navigate to the very last remark.

F.13. Create, Edit, Delete, and List Metrics

  1. Prerequisites: The app has been finalized, with three attributes: one, two, and three.

    1. Test case: add metric extreme
      Expected: An error message will be shown, indicating that it misses the attribute and weight details.

    2. Test case: add metric extreme -a four -w 0.5
      Expected: An error message will be shown, indicating that there is no attribute four.

    3. Test case: add metric extreme one -a two
      Expected: An error message will be shown, indicating that it misses the attribute and weight details because there is no w weight assigned to attribute two.

    4. Test case: add metric extreme one -a two -w 0.4 -a on -w 0.6
      Expected: A metric with name extreme will be created with weight 0.6 assigned to one since on is a unique prefix for one, and 0.4 assigned to two.

  2. Prerequisites: Same as point 1, with an addition of existing metric named extreme with the same attribute to weight as case 1d.

    1. Test case: edit metric extreme
      Expected: An error message will be shown, indicating that it misses the attribute and weight details.

    2. Test case: edit metric extreme -n soft
      Expected: The metric name is changed from extreme to soft.

    3. Test case: edit metric extreme -a two
      Expected: An error message will be shown, indicating that it misses the attribute and weight details because there is no w weight assigned to attribute two.

    4. Test case: edit metric extreme -a two -w 0.9
      Expected: The weight of attribute two in metric extreme will be changed to 0.9.

    5. Test case: edit metric extreme -a thr -w 0.5
      Expected: It introduces the weight for attribute three to be assigned to weight 0.5 to metric extreme. The rest remains unchanged.

    6. Test case: delete metric dictator
      Expected: An error message will be shown, indicating that there is no metric dictator.

    7. Test case: delete metric extr
      Expected: The metric extreme is being deleted because extr is a unique prefix for metric extreme.

    8. Test case: metrics
      Expected: The right panel of thee GUI will show all the metrics that have been created. In this case, the metric extreme.

F.14. Find Best

  1. Prerequisites: The session has been finalized, with the following interviewed interviewees details:
    Name: Alice
    Attributes to score: [one: 5, two: 4, three: 3]
    Name: Bob
    Attributes to score: [one: 2, two: 4, three: 5]
    Name: Charlie
    Attributes to score: [one: 4, two: 7, three: 4]

    1. Test case: interviewee -best
      Expected: An error message is shown, showing that the command format is invalid.

    2. Test case: interviewee -best 5
      Expected: All 3 interviewed interviewees are listed in sorted order based on their overall score (Charlie, Alice, Bob). The output message indicates that there are only 3 interviewed interviewees.

    3. Test case: interviewee -best 2 -a tw
      Expected: All 3 interviewed interviewees are listed in sorted order based on their score for attribute two (Charlie, Alice, Bob). Both Alice and Bob are shown because they have the same score. The output message also indicates that there are ties, which leads to show more than 2 interviewees.

  2. Prerequisites: In addition to the prerequisites stated in point 1, there is a metric named extreme with the following weightage: [one: 0.4, two: 0.3]

    1. Test case: interviewee -best 2 -m extr
      Expected: Charlie and Alice will be shown in the best interviewees list.