Developer Guide
- Acknowledgements
- Setting up, getting started
- Design
- Implementation
- Documentation, logging, testing, configuration, dev-ops
-
Appendix: Requirements
- Product scope
- User stories
-
Use cases
- Use case 01: Delete a applicant
- Use case 02: Adding an applicant
- Use case 03: Editing position
- Use case 04: Viewing help
- Use case 05: Viewing detail help for a specific command
- Use case 06: Filtering data
- Use case 07: Sorting data
- Use case 08: Passing interview
- Use case 09: Failing interview
- Use case 10: Accepting interview
- Use case 11: Rejecting interview
- Use case 12: Exporting data
- Use case 13: Clearing data
- Non-Functional Requirements
- Glossary
- Appendix: Instructions for manual testing
Acknowledgements
- This project is based on the AddressBook-Level3 project by SE-EDU.
Setting up, getting started
Refer to the guide Setting up and getting started.
Design

.puml
files used to create diagrams in this document can be found in the diagrams folder. Refer to the PlantUML Tutorial at se-edu/guides to learn how to create and edit diagrams.
Architecture
The Architecture Diagram given above explains the high-level design of the App.
Given below is a quick overview of main components and how they interact with each other.
Main components of the architecture
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 methods where necessary.
Commons
represents a collection of classes used by multiple other components.
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.
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 delete -a 1
.
Each of the four main components (also shown in the diagram above),
- defines its API in an
interface
with the same name as the Component. - implements its functionality using a concrete
{Component Name}Manager
class (which follows the corresponding APIinterface
mentioned in the previous point.
For example, the Logic
component defines its API in the Logic.java
interface and implements its functionality using the LogicManager.java
class which follows the Logic
interface. Other components interact with a given component through its interface rather than the concrete class (reason: to prevent outside component’s being coupled to the implementation of a component), as illustrated in the (partial) class diagram below.
The sections below give more details of each component.
UI component
The API of this component is specified in Ui.java
The UI consists of a MainWindow
that is made up of parts e.g.CommandBox
, ResultDisplay
, ApplicantListPanel
, StatusBarFooter
etc. All these, including the MainWindow
, inherit from the abstract UiPart
class which captures the commonalities between classes that represent parts of the visible GUI.
The UI
component uses the 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
Note that ApplicantListPanel
, PositionListPanel
, and InterviewListPanel
will all exists simultaneously in the UI
component, but only one will be visible to the user as controlled by tabs in MainWindow
.
The UI
component,
- executes user commands using the
Logic
component. - changes the selected tab automatically according to the
DataType
inCommandResult
from theLogic
component. - listens for changes to
Model
data so that the UI can be updated with the modified data. - keeps a reference to the
Logic
component, because theUI
relies on theLogic
to execute commands. - depends on some classes in the
Model
component, as it displays theApplicant
,Position
andInterview
objects residing in theModel
.
Logic component
API : Logic.java
Here’s a (partial) class diagram of the Logic
component:
How the Logic
component works:
- When
Logic
is called upon to execute a command, it uses theHireLahParser
class to parse the user command. - In the case of commands that is common to all data types (e.g.
add
,edit
,delete
,list
), an intermediate parser may be used to select the specific parser for the data type. - This results in a
Command
object (more precisely, an object of one of its subclasses e.g.,AddApplicantCommand
) which is executed by theLogicManager
. - The command can communicate with the
Model
when it is executed (e.g. to add a applicant). - The result of the command execution is encapsulated as a
CommandResult
object which is returned back fromLogic
.
The Sequence Diagram below illustrates the interactions within the Logic
component for the execute("delete -a 1")
API call.

DeleteCommandParser
should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram.
Here are the other classes in Logic
(omitted from the class diagram above) that are used for parsing a user command:
How the parsing works:
- When called upon to parse a user command, the
HireLahParser
class creates anXYZCommandParser
(XYZ
is a placeholder for the specific command name e.g.,AddCommandParser
) which uses the other classes shown above to parse the user command and create aXYZCommand
object (e.g.,AddCommand
) which theHireLahParser
returns back as aCommand
object. - All
XYZCommandParser
classes (e.g.,AddCommandParser
,DeleteCommandParser
, …) inherit from theParser
interface so that they can be treated similarly where possible e.g, during testing.
Model component
API : Model.java
In the Model
, ModelManager
contains three different DataType
– Applicant
, Position
and Interview
, each with their own UniqueXYZList
contained in HireLah
. The class diagrams for each DataType
are separated below for better clarity.
Applicant
class diagram:
Position
class diagram:
Interview
class diagram:
Note that the Interview
class contains Applicant
and Position
.
The Model
component,
- stores all the data i.e., all
Applicant
,Position
, andInterview
objects (which are contained inUniqueApplicantList
,UniquePositionList
, andUniqueInterviewList
objects respectively). - stores the currently ‘selected’
Applicant
,Position
, andInterview
objects (e.g., results after a list command with filter applied) as a separate filtered list which is exposed to outsiders as unmodifiable Java’s Observable List (i.e.,ObservableList<Applicant>
,ObservableList<Position>
andObservableList<Interview>
for the different types) 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. - stores a
UserPref
object that represents the user’s preferences. This is exposed to the outside as aReadOnlyUserPref
objects. - does not depend on any of the other three components (as the
Model
represents data entities of the domain, they should make sense on their own without depending on other components)
Storage component
API : Storage.java
The Storage
component,
- can save both HireLah data, which consists of
Applicants
,Interviews
andPositions
; and user preference data in json format, and read them back into corresponding objects. - inherits from both
HireLahStorage
andUserPrefsStorage
, which means it can be treated as either one (if only the functionality of only one is needed). - depends on some classes in the
Model
component (because theStorage
component’s job is to save/retrieve objects that belong to theModel
)
Common classes
Classes used by multiple components are in the seedu.address.commons
package.
Implementation
This section describes some noteworthy details on how certain features are implemented.
Applicant feature
Proposed Implementation
An applicant in HireLah is represented by Applicant
. Applicant
is implemented by refactoring Persons
.
Additionally, Applicant
implements two new attributes which are represented by the following two new classes:
-
Gender
— M refers to male, and F refers to female. Only the value M or F is allowed. -
Age
— Numerical representation of the age of the applicant. Only values with two digits or more are allowed.
Gender
and Age
class highly resemble other existing attribute classes such as Address
, Email
, Name
, and
Phone
.
These classes are contained in the applicant
package which belongs to the model
package.
Applicant is implemented this way as for HireLah, we require new attributes such as Gender
and Age
to aid in the
recruitment process. the Person
class did not contain such attributes.
Adding Gender and Age as tags using the existing functionality is not ideal as we do not want these attributes to be optional.
A new Applicant
class had to be created to support the functionality. It is also not ideal to keep the existing
Person
class as it should not be instantiated by users in HireLah.
Hence it made sense to refactor Person
to Applicant
and to extend and build on the existing functionalities to
support the needs of HireLah.
Position feature
Implementation
A position in HireLah is represented by Position
. Position
is implemented with the following attributes:
-
PositionName
— refers to the name of the job opening. Can allow any characters, but must have at least one alphanumeric character. Length is restricted to a maximum of 100 characters. -
Description
— refers to the description of the position. Can allow any characters, but must have at least one alphanumeric character. Length is restricted to a maximum of 200 characters. -
PositionOpenings
— refers to the number of openings in the position. Can allow only numbers of 1 to 5 digits. -
PositionOffers
— refers to the number of outstanding offers handed out for the position. Number of offers is initialized as 0 when a position is created. Number of offers cannot be directly mutated, and is only altered through commands ofpass
,accept
,reject
. -
Set<Requirement>
— refers to a set of requirements that is required for anApplicant
to be considered for thePosition
. There can be any number of requirements for thePosition
.
These classes are contained in the position
package which belongs to the model
package.
Position is implemented this way as for HireLah, as we need these informations, in order to aid recruiters in keeping track of crucial job-related information in the hiring process.
Design considerations:
Aspect: Ensuring that number of applicants offered a job does not exceed the number of job openings
-
Alternative 1 (current choice):
PositionOffers
is implemented in a way that disallow users from directly mutating the underlying value.PositionOffers
is only mutated through various commands listed under section Tracking Interview Status.- Pros: Number of
PositionOffers
is guaranteed to tally with number of “passed interviews”. - Cons: Difficulty in implementing due to coupling with the
Interview
class. Actions that mutateInterview
may cause changes toPositionOffers
. It will also be more difficult for users to correct the erroneous commands, as they cannot directly decrement or incrementPositionOffers
.
- Pros: Number of
-
Alternative 2 Allowing users to manually set their own number of offers.
- Pros: Greater flexibility for users to update and keep track of the number of offers handed out.
- Cons: Users will have to exercise their own diligence in ensuring that number of offers handed out tallies with the number of “passed interview”.
Tracking Interview Status
Implementation
Currently, there are 5 possible status for interviews which represents where an applicant is in the hiring pipeline.
-
Pending
- Interview has been created / scheduled, applicant yet to go for interview. -
Passed - waiting for applicant
- Applicant has passed the interview. A job offer is automatically extended to the applicant at this stage. -
Failed
- Applicant has failed the interview. -
Accepted
- Applicant has accepted the job offer. Applicant job role will be updated in Applicants tab. -
Rejected
- Applicant has rejected the job offer.
The activity diagram below shows the workflows between different interview status and corresponding updates to Position
and Applicant
classes.
Design considerations:
Aspect: When an applicant is considered to be matched with a job:
-
Alternative 1 (current choice): An applicant must accept a passed interview before the applicant is hired for that position.
- Pros: A more accurate modelling of real-world hiring processes, whereby an applicant may actually be accepted for multiple roles, and has to choose one role to accept.
- Cons: Have to track number of position offers currently given out with respect to number of open positions, preventing a scenario where multiple people accept the offer but there is a shortage of actual position openings. More complex model which may be bug-prone.
-
Alternative 2: An applicant is considered to be hired after passing the interview.
- Pros: A simplified way of matching, reduces complexity of interview and coupling between Interview and Positions.
- Cons: Does not model real-world interview processes accurately, forces applicant to accept the first job which they pass the interview for.
Aspect: Number of interviews per applicant allowed for each unique role:
-
Alternative 1 (current choice): An applicant can only schedule one interview for each unique position they apply for.
- Pros: A simplified model that reduces complexity of when to hand out job offers, reducing bugs.
- Cons: May not model the real-world hiring process accurately where some roles require multiple interviews.
-
Alternative 2: An applicant can schedule multiple interviews for a unique position they apply for.
- Pros: A more accurate modelling of real-world hiring processes.
- Cons: Increased complexity of hiring process. Need to keep track of different number of interviews required for every unique position and where each applicant is at which stage e.g “Finished HR interview” / “Finished Online Assessment”, which may result in more bugs.
Adding of Data
Implementation
Adding of different data types is currently done through ModelManger
, which implements the methods in interface Model
.
There are 3 levels to the parsing of the add command from user input.
-
HireLahParser
identifies it as anadd
command. -
AddCommandParser
identifies the exact data type that is to be added, through theflag
of the user input. -
AddXYZCommandParser
identifies the fields to be added for the specific datatype, and creates andAddXYZCommand
.
The sequence diagram below shows how the parsing of add -i
works.
Note that the lifeline for AddCommandParser
and AddInterviewCommandParser
should end at the destroy marker (X) but due to
a limitation of PlantUML, the lifeline reaches the end of diagram. Logic for execution of AddInterviewCommand
is omitted.
Design considerations:
Aspect: How to add different data types:
-
Alternative 1 (current choice): Have a general add command.
- Pros: User-friendly since users only have to remember a singular command.
- Cons: Requires additional levels of parsers to be created.
-
Alternative 2: An individual command for each data type that can be added (eg.
addappl
,addintvw
)- Pros: Fewer levels of parsers is required.
- Cons: We must ensure that the implementation of each individual command are correct. Many commands to remember for a new user.
Deleting of Data
Implementation
The implementation of deleting data is similar to adding data, where deleting of different data types is done through ModelManger
, which implements the methods in the Model
interface.
The parsing of a delete command from user input is also done through the 3 levels system, with HireLahParser
, DeleteCommandParser
, and DeleteXYZCommandParser
which eventually creates the DeleteXYZCommand
.
However, when deleting an applicant or a position, an additional step of cascading to delete interview is required. Since every interview is associated with an applicant and a position, we cannot have an interview exist without the corresponding applicant or position. Hence, it is important to delete the associated interview(s) when deleting an applicant or a position.
Design considerations:
Aspect: How to cascade when deleting applicant/position to delete interview:
-
Alternative 1 (current choice): Loop through all interviews in
DeleteXYZCommand
- Pros: Less coupling as a data type does not store another data type as an attribute.
- Cons: May be less efficient as we have to loop through the whole list of interviews everytime when deleting applicant/position.
-
Alternative 2: Keep relevant list of interviews for each applicant and position.
- Pros: More efficient when deleting since all the associated interviews are already available.
- Cons: Increased coupling between applicant, position, and interview which make it more bug-prone.
Filtering of Data
Implementation
The implementation of filtering data is done as an extension of the list -X
command, which takes in optional parameters that will trigger the filtering of data to display if given. The filtering of data is done similar to the find
command in AB3, which is now deprecated in HireLah. It applies a predicate to the filteredXYZ
filtered lists in the ModelManager
, which the UI
will pick up and display the latest filtered list of the data to the user.
To support different filters for different data types, each filter is a predicate class in the Model
component. For example, to support filtering applicants by gender, there is a ApplicantGenderPredicate
in the Model
component under applicant
. The predicate implements Java’s Predicate<Applicant>
interface for filtered lists.
Here is the sequence diagram for a filter command:
The Sequence Diagram below illustrates the interactions within the classes for the execution of list -a f/name a/Bob
command.
Design considerations:
Aspect: Should the filter feature be a separate command by itself?
-
Alternative 1: Implement filter as a separate
filter -X
command.- Pros: May be more intuitive for new users to pick up. Can also potentially make the parsing of filter-related arguments less complicated.
- Cons: Multiple commands doing similar things because
filter
is essentiallylist
with different predicates applied to the filtered lists. Listing all data is also a predicate itself.
-
Alternative 2 (current choice): Implement filter as part of the
list -X
command (by taking in more parameters).- Pros: No two commands doing the similar things, which may lead to chunks of repeated code under the two commands.
- Cons: May be confusing for new users, need to explain it well in user guide and help window. Also, will have to parse filter-related arguments together with other arguments in
list -X
command (such as for sorting), which may cause the parsing to be more complicated.
Sorting of Data
Implementation
The implementation of sorting data is done as an extension of the list -X
command, which takes in optional
parameters that will trigger the sorting of data to display if given. The sorting is done by directly sorting
the data in UniqueXYZList
, which uses ObservableList<XYZ>
to contain the data. It applies a comparator to
UniqueXYZList
in HireLah
, then applies the given predicate (if none, then use show all predicate) to filteredXYZ
filtered lists in ModelManager
, which the UI
will pick up and display the data to the user.
To support different sorting for different data types, each type of data sort is a comparator class in the Model component.
For example, for applicants, we will sort by their name, hence, there is a ApplicantNameComparator in the Model component
under applicant. The comparator implements Java’s Comparator
The Sequence Diagram below illustrates the interactions within the classes for the execution of list -a s/asc
command.
Design considerations:
Aspect: How to sort data without affect the original dataset
-
Alternative 1 (current choice): Sort the
UniqueXYZList
and display the data using filtered lists predicate- Pros:
- Less chance of error occurs when modify the displayed data.
-
UI
can displayed the sorted data immediately. -
export -X
can export the data according to their sorting order.
- Cons: Decrease cohesion, as we need to depend on
HireLah
.
- Pros:
-
Alternative 2: Directly sort the
filteredXYZ
filtered lists inModelManager
by passing it to sorted lists.- Pros: Increase cohesion, as method only used attributes in
ModelManager
. - Cons:
- Increased the complexity of the relevant code, as we need to double passing, which make it more bug-prone.
-
UI
won’t able to display the new filtered lists, and need to connect again toUI
components.
- Pros: Increase cohesion, as method only used attributes in
Exporting of Data
Implementation
Exporting of different data types is currently done through ModelManger
, which implements the methods in interface Model
.
There are 2 levels to the parsing of the add command from user input.
-
HireLahParser
identifies it as anexport
command. -
ExportCsvCommandParser
identifies the exact data type that need to be exported, through theflag
of the user input , and returns the respectiveExportXYZCsvCommand
.
The Sequence Diagram below illustrates the interactions within the classes for the execution of export -p
command.
Design considerations:
Aspect: What export format should be used:
-
Alternative 1 (current choice): Export to CSV file
- Pros:
- Versatile since CSV file can be used by non-technical user.
- Suitable for manipulating
Applicant
,Interview
andPosition
data.
- Cons: Requires additional method to transform
Model
into CSV output
- Pros:
-
Alternative 2: Export to individual Json file
- Pros: Able to reuse code as Json already implemented by
Storage
- Cons: Not versatile as required non-user to have knowledge about Json.
- Pros: Able to reuse code as Json already implemented by
Documentation, logging, testing, configuration, dev-ops
Appendix: Requirements
Product scope
Target user profile:
- Has a need to manage a significant number of applicants to technology companies
- Prefer desktop apps over other types
- Can type fast
- Prefers typing to mouse interactions
- Is reasonably comfortable using CLI apps
- Needs to view where each applicant is in the hiring pipeline
Value proposition:
- Manage applicants faster than a typical mouse/GUI driven app
- Schedule interviews for different applicants and match them to different positions
- End to end seamless administration for talent management
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 user | see usage instructions of all commands | know what are the commands available and how to use them |
* * * |
recruiter | add a new applicant | keep track of all the applicants |
* * * |
recruiter | edit an applicant | update the latest information of applicants |
* * * |
recruiter | delete an applicant | remove applicants that have left the hiring pipeline |
* * * |
recruiter | add a new interview | potentially match an applicant to a job |
* * * |
recruiter | edit an interview | update the latest information of interviews |
* * * |
recruiter | delete an interview | remove interviews that are cancelled |
* * * |
recruiter | add a new position | keep track of all the job positions |
* * * |
recruiter | edit a position | update the latest information of positions |
* * * |
recruiter | delete a position | remove positions which are not available anymore |
* * * |
recruiter | view the applicants in my contact | access their information and contact them |
* * * |
recruiter | view the positions I am recruiting for | know what are the positions available |
* * * |
recruiter | view the interviews I have | know my schedule and plan my work day |
* * |
recruiter | filter the displayed data | find the information I am looking for easily |
* * |
recruiter | pass an interview that was successful | proceed to offer the applicant the position |
* * |
recruiter | fail an interview that was unsuccessful | proceed to end the hiring process for the applicant |
* * |
recruiter | mark an interview as accepted by the applicant | update that the applicant has accepted the offer |
* * |
recruiter | mark an interview as rejected by the applicant | update that the applicant has rejected the offer |
* * |
recruiter | export the data in the application | share the information with other recruiters |
* |
expert user | access previous commands I made | send multiple similar commands without having to type the whole command |
Use cases
(For all use cases below, the System is the HireLah Application
and the Actor is the user
, unless specified otherwise)
Use case 01: Delete a applicant
MSS
- User requests to list applicants
- HireLah shows a list of applicants
- User requests to delete a specific applicant in the list
-
HireLah deletes the applicant
Use case ends.
Extensions
-
2a. The list is empty.
Use case ends.
-
3a. The given index is invalid.
-
3a1. HireLah shows an error message.
Use case resumes at step 2.
-
Use case 02: Adding an applicant
MSS
- User requests to add applicant with specific parameters.
- HireLah shows list including new applicant.
Use case ends.
Extensions
- 1a. HireLah detects specified parameters are incorrect.
- 1a1. HireLah shows an error message.
Use case resumes at step 1.
- 1a1. HireLah shows an error message.
Use case 03: Editing position
MSS
- User requests to list positions
- HireLah shows a list of positions
- User chooses to edit a position based on the index from the visible list, and provide the fields to edit.
- HireLah refreshes the list of positions to display the newly edited position.
Use case ends.
Extensions
- 3a. The given index is not a valid index in the list.
- 3a1. HireLah informs user that the index is not valid.
Use case ends.
- 3b. The new position name provided is the same as another position.
- 3b1. HireLah informs user that the new position name is not valid.
Use case ends.
Use case 04: Viewing help
MSS
- User requests to view help
- HireLah shows a list of commands and its briefly description
Use case ends.
Use case 05: Viewing detail help for a specific command
MSS
- User open the list of commands and general description (UC4).
- User chooses a specific command and view its detail description.
- HireLah displays the detail description of that command
Use case ends.
Extensions
- 2a. The given command is not a valid command.
- 2a1. HireLah informs user that HireLah don’t have the command.
Use case ends.
- 3b. The new position name provided is the same as another position.
- 3b1. HireLah informs user that the new position name is not valid.
Use case ends.
Use case 06: Filtering data
MSS
- User requests to list data with filter applied.
- HireLah refreshes the list of data to display with only data that matches the filter given.
Use case ends.
Extensions
- 1a. No data in HireLah fits the filter given.
- 1a1. HireLah informs user that no data is found.
Use case ends.
- 1b. The filter type given is invalid.
- 1b1. HireLah informs user that the filter type given is invalid.
Use case ends.
Use case 07: Sorting data
MSS
- User requests to list data with sorting applied.
- HireLah refreshes the list of data to display with data that have been sorted.
Use case ends.
Extensions
- 1a. No data of a given type in HireLah.
- 1a1. HireLah display an empty list.
Use case ends.
- 1b. The sort argument given is invalid.
- 1b1. HireLah informs user that the sort argument given is invalid.
Use case ends.
Use case 08: Passing interview
MSS
- User requests to list interviews.
- HireLah shows a list of interviews.
- User choose to pass an interview based on the index from the visible list.
- HireLah refreshes the list of interviews to display the newly passed interview.
Use case ends.
Extensions
- 1a. No interview data in HireLah.
- 1a1. HireLah display an empty list.
Use case ends.
- 3b. The given interview index is not a valid index in the list.
- 3b1. HireLah informs user that the index is invalid.
Use case ends.
- 3c. The chosen interview is not at
Pending
status. - 3c1. HireLah informs user that only pending interview can be passed
Use case ends.
Use case 09: Failing interview
MSS
- User requests to list interviews.
- HireLah shows a list of interviews.
- User choose to fail an interview based on the index from the visible list.
- HireLah refreshes the list of interviews to display the newly failed interview.
Use case ends.
Extensions
- 1a. No interview data in HireLah.
- 1a1. HireLah display an empty list.
Use case ends.
- 3b. The given interview index is not a valid index in the list.
- 3b1. HireLah informs user that the index is invalid.
Use case ends.
- 3c. The chosen interview is not at
Pending
status. - 3c1. HireLah informs user that only pending interview can be passed
Use case ends.
Use case 10: Accepting interview
MSS
- User requests to list interviews.
- HireLah shows a list of interviews.
- User choose to accept an interview based on the index from the visible list.
- HireLah refreshes the list of interviews to display the newly accepted interview.
Use case ends.
Extensions
- 1a. No interview data in HireLah.
- 1a1. HireLah display an empty list.
Use case ends.
- 3b. The given interview index is not a valid index in the list.
- 3b1. HireLah informs user that the index is invalid.
Use case ends.
- 3c. The chosen interview is not at
Pass
status. - 3c1. HireLah informs user that only passed interview can be passed
Use case ends.
Use case 11: Rejecting interview
MSS
- User requests to list interviews.
- HireLah shows a list of interviews.
- User choose to reject an interview based on the index from the visible list.
- HireLah refreshes the list of interviews to display the newly rejected interview.
Use case ends.
Extensions
- 1a. No interview data in HireLah.
- 1a1. HireLah display an empty list.
Use case ends.
- 3b. The given interview index is not a valid index in the list.
- 3b1. HireLah informs user that the index is invalid.
Use case ends.
- 3c. The chosen interview is not at
Pass
status. - 3c1. HireLah informs user that only passed interview can be passed
Use case ends.
Use case 12: Exporting data
MSS
- User requests to list data with optional sort or filter argument.
- HireLah shows a list of data.
- User chooses to export the data.
- HireLah exports the current displayed data into a CSV file.
Use case ends.
Extensions
- 1a. No data in HireLah.
- 1a1. HireLah display an empty list.
Use case ends.
- 4b. User chooses to open the CSV file and open again.
- 4b1. HireLah informs user that the user need to close the CSV before exporting.
Use case ends.
Use case 13: Clearing data
MSS
- User requests to clear data.
- HireLah clear all data.
Use case ends.
Non-Functional Requirements
- Should work on any mainstream OS as long as it has Java
11
or above installed. - HireLah should respond within two seconds after any command is entered.
- Should be able to hold up to 1000 applicants, positions, and interviews each without a noticeable sluggishness in performance for typical usage.
- The data in the app should be easily transferable to another computer without losing any information.
- A user with above average typing speed for regular English text (i.e. not code, not system admin commands) should be able to accomplish most of the tasks faster using commands than using the mouse.
- The system should be usable by a novice which has not used other CLI application for recruitment tracking.
- A new user should be able to pick up how to use HireLah within 20 minutes of usage.
- HireLah must boot up within 10 seconds on a device under a normal load.
- HireLah is not required to make any direct communication with the applicants.
Glossary
- Mainstream OS: Windows, Linux, Unix, OS-X
- Recruiter: A Human Resource professional that manages applicants, interviews and positions in the application
- Applicant: A candidate looking for a job.
- Interview: A scheduled meeting time for an Applicant to try for a Position.
- Position: A job opportunity for candidates.
Appendix: Instructions for manual testing
Given below are instructions to test the app manually.

Launch and shutdown
-
Initial launch
-
Download the jar file and copy into an empty folder
-
Double-click the jar file Expected: Shows the GUI with a set of sample data. The window size may not be optimum.
-
-
Saving window preferences
-
Resize the window to an optimum size. Move the window to a different location. Close the window.
-
Re-launch the app by double-clicking the jar file.
Expected: The most recent window size and location is retained.
-
Adding Data
- Adding an applicant to HireLah
- Prerequisites: Ensure that cursor is on command box. Current applicant list does not contain any other applicants with the same name, phone number, or email, stated in Test Case #1.
- Test case:
add -a n/Jonathan p/98564231 e/jonathan@example.com ag/23 a/73 Geylang Rd, S532948 g/M t/NUS Graduate
Expected: New applicant is added to the bottom of the list. Details of the applicant shown in response box. GUI toggles to display applicant list. - Test case:
add -a n/Jonathan p/91234567 e/notjonathan@example.com ag/23 a/73 Geylang Rd, S532948 g/M t/NUS Graduate
Expected: No applicant is added to the applicant list. Error message informs user that the applicant already exists. - Test case:
add -a n/NotJonathan p/98564231 e/notjonathan@example.com ag/23 a/73 Geylang Rd, S532948 g/M t/NUS Graduate
Expected: No applicant is added to the applicant list. Error message informs user that phone number is in used by “Jonathan”. - Test case:
add -a n/NotJonathan p/91234567 e/jonathan@example.com ag/23 a/73 Geylang Rd, S532948 g/M t/NUS Graduate
Expected: No applicant is added to the applicant list. Error message informs user that email is in used by “Jonathan”.
- Adding a position to HireLah
- Prerequisites: Ensure that cursor is on command box. Current position list does not contain any other positions with the same position name stated in Test Case #1.
- Test case:
add -p p/Junior Software Developer o/3 d/One of the highest compensation in the market. Work is remote. r/Golang r/Cloud Computing
Expected: New position is added to the bottom of the list. Details of the position shown in response box. GUI toggles to display position list. - Test case:
add -p p/Junior Software Developer o/5 d/Not the same description. r/C++ r/Java
Expected: No position is added to the position list. Error message informs user that position already exists.
- Adding an interview to HireLah
- Prerequisites: Ensure that cursor is on command box. At least one applicant and position in the application. No interview scheduled for applicant and the particular position mentioned in all test cases below.
- Test case:
add -i 1 p/1 d/2022-04-11 12:00
Expected: New interview is added to the bottom of the list. Applicant’s name, date of interview, position’s name and interview status is shown in response. GUI toggles to display interview list. - Test case:
add -i 1 p/1 d/2022-04-12 12:00
Expected: No interview is added to the interview list. Error message informs user that applicant already has an interview scheduled for that position. - Test case:
add -i 1 p/2 d/2022-04-11 12:30
Expected: No interview is added to the interview list. Error message informs user that applicant has an existing scheduled interview that clashes in timing.
Deleting Data
-
Deleting an applicant while all applicants are being shown
-
Prerequisites: List all applicants using the
list -a
command. Multiple applicants in the list. -
Test case:
delete -a 1
Expected: First applicant is deleted from the list. Details of the deleted applicant shown together with the number of deleted interview(s). Uselist -i
to verify that the interview(s) involving the deleted applicant no longer exists. -
Test case:
delete -a 0
Expected: No applicant is deleted. Error details shown. -
Other incorrect delete applicant commands to try:
delete -a
,delete -a x
(where x is larger than the list size)
Expected: Similar to previous.
-
-
Deleting an applicant while the applicant list is filtered
-
Prerequisites: Filter the applicants using the
list -a f/name a/xxx
command (where xxx is an existing applicant name). At least one applicant in the list. -
Test case:
delete -a 1
Expected: First applicant is deleted from the list. Details of the deleted applicant shown together with the number of deleted interview(s). Uselist -i
to verify that the interview(s) involving the deleted position no longer exists. -
Test case:
delete -a 0
Expected: No applicant is deleted. Error details shown.
-
- Deleting a position
-
Prerequisites: List positions using the
list -p
command, may choose to apply a valid filter. Multiple positions in the list. -
Test case:
delete -p 2
Expected: Second position is deleted from the list. Details of the deleted position shown together with the number of deleted interview(s). -
Test case:
delete -p 0
Expected: No position is deleted. Error details shown. -
Other incorrect delete position commands to try:
delete -p
,delete -p x
(where x is larger than the list size)
Expected: Similar to previous.
-
- Deleting an interview
-
Prerequisites: List interviews using the
list -i
command, may choose to apply a valid filter. Multiple interviews in the list. -
Test case:
delete -i 1
Expected: First interview is deleted from the list. Details of the deleted interview shown. -
Test case:
delete -i 0
Expected: No interview is deleted. Error details shown. -
Other incorrect delete position commands to try:
delete -i
,delete -i x
(where x is larger than the list size)
Expected: Similar to previous.
-
- Delete without any flag specified
-
Test case:
delete
Expected: No data is deleted. “No flag” error shown. -
Test case:
delete 2
Expected: No data is deleted. “No flag” error shown.
-
Filtering Data
- Filtering applicants
-
Prerequisites: List all applicants using the
list -a
command. Multiple applicants in the list. -
Test case:
list -a f/name a/xxx
where xxx is a valid name of an applicant in the list.
Expected: The list refreshes showing only applicants whose name matches the name given. Shows message of how many applicants are listed. -
Test case:
list -a f/name a/xxx
where xxx is not a name of any applicant in the list.
Expected: An empty applicant list is shown. -
Test case:
list -a f/name
Expected: The applicant list does not refresh. Error message shown. -
Other incorrect filter applicant commands to try:
list -a f/abc a/abc
,list -a a/John
Expected: Similar to previous.
-
- Filtering positions
-
Prerequisites: List all positions using the
list -p
command. Multiple positions in the list. -
Test case:
list -p f/name a/xxx
where xxx is a valid name of a position in the list.
Expected: The list refreshes showing only positions with name that matches the name given. Shows message of how many positions are listed. -
Test case:
list -p f/name a/xxx
where xxx is not a name of any position in the list.
Expected: An empty position list is shown. -
Test case:
list -p f/name
Expected: The position list does not refresh. Error message shown. -
Other incorrect filter applicant commands to try:
list -p f/abc a/abc
,list -p a/Software
Expected: Similar to previous.
-
- Filtering interviews
-
Prerequisites: List all interviews using the
list -i
command. Multiple interviews in the list. -
Test case:
list -i f/date a/yyyy-mm-dd
where yyyy-mm-dd is a valid date of an interview in the list.
Expected: The list refreshes showing only interviews with date that falls the date given. Shows message of how many interviews are listed. -
Test case:
list -i f/date a/yyyy-mm-dd
where yyyy-mm-dd is a date of any interview in the list.
Expected: An empty interview list is shown. -
Test case:
list -i f/date
Expected: The position list does not refresh. Error message shown. -
Other incorrect filter interview commands to try:
list -i f/abc a/abc
,list -i a/2022-05-05
Expected: Similar to previous.
-
Sorting Data
- Sorting applicants
-
Prerequisites: List all applicants using the
list -a
command. At least two applicants in the list. -
Test case:
list -a s/asc
Expected: The list refreshes showing the list of all applicants sorted by their names in ascending order (if not already). -
Test case:
list -a s/abc
Expected: An error message is shown.
-
- Sorting positions
-
Prerequisites: List all positions using the
list -p
command. At least two positions in the list. -
Test case:
list -p s/asc
Expected: The list refreshes showing the list of all positions sorted by their names in ascending order (if not already). -
Test case:
list -p s/abc
Expected: An error message is shown.
-
- Sorting interviews
-
Prerequisites: List all interviews using the
list -i
command. At least two interviews in the list. -
Test case:
list -i s/asc
Expected: The list refreshes showing the list of all interviews sorted by their date in ascending order (if not already). -
Test case:
list -i s/abc
Expected: An error message is shown.
-
Saving data
-
Saving newly added/edited data
- Add/edit any data in the app (applicant / position / interview).
- Restart the app by exiting and opening the jar file.
Expected: Any changes made to the data is retained.
-
Dealing with missing data file
- Exit the app and delete the storage file at
/data/HireLah.json
. - Re-launch the app by opening the jar file.
Expected: The app launches with sample data.
- Exit the app and delete the storage file at
-
Dealing with corrupted data file
- Exit the app and open the storage file at
/data/HireLah.json
. - Remove a comma
,
from the file. - Re-launch the app by opening the jar file.
Expected: The app launches with no data. Gives warning in log.
- Exit the app and open the storage file at