Refer to the Setting Up and Getting Started guide.
The Architecture Diagram above provides a high-level overview of the application's architecture.
Below, you'll find a concise summary of the main components and their interactions.
Main (comprising classes
Main
and MainApp
is responsible for launching and shutting down the application.
The bulk of the app's work is done by the following four components:
UI: Handles the interaction with User.Logic: Executes user commands.Model: Manages the in-memory data of the app.Storage: Handles reading and writing of data to
the hard disk.Commons encompasses a set of classes shared across
multiple components.
The Sequence Diagram below illustrates the interactions between components when the user issues the delete 1 command.
Each of the four primary components (as depicted in the diagram above),
interface bearing the same name as the
component.{Component Name}Manager
class that follows the corresponding API interface 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
adheres to the Logic interface. Other components interact with a given
component through its interface rather than the concrete class.
The reason for this practice is to decouple outside components from the
internal implementation of the component.
This decoupling is illustrated in the (partial) class diagram below.
For more comprehensive details on each component, please refer to the sections below.
API:
Ui.java
The UI component comprises a MainWindow composed of various parts, such as the
CommandBox, ResultDisplay, InternApplicationListPanel, StatusBarFooter,
and more.
All of these elements, including the MainWindow, inherit from the
abstract UiPartclass which encapsulates common characteristics among classes
representing different parts of the visible GUI.
The UI component leverages the JavaFx UI framework.
The layout of these UI parts are defined in matching .fxml files located in
src/main/resources/view.
For example, the layout of
the MainWindow
is specified
in MainWindow.fxml
The UI component,
Logic component.Model to update the UI
accordingly.Logic component, since the UI relies on
it for command execution.Model component, as it
displays InternApplication objects residing in the Model.API:
Logic.java
The class diagram below provides a partial view of the Logic component.
To illustrate the interactions within the Logic component, we'll use the
execute("delete 1") API call as an example in the sequence diagram below:
Note: The lifeline for DeleteCommandParser and DeleteCommand
should end at the destroy marker (X) but due to a limitation in PlantUML,
the lifeline extends to the end of the diagram.
The creation of the internApplication object has been omitted for brevity.
How the Logic component works:
Logic is called upon to execute a command, it is passed to
an InternTrackerParser object.
The InternTrackerParser then creates a specific parser (
e.g., DeleteCommandParser)
tailored to match and parse the command.Command object, specifically an object
of one of its subclasses (e.g. DeleteCommand).
This command is then executed by the LogicManager.Model when it is executed,
such as to delete an InternApplication object from the Model.CommandResult
object which is returned by Logic.In addition to the class diagram above, there are other classes (omitted from the class diagram above) within the Logic component that are used for parsing user commands:
How commands are parsed:
InternTrackerParser class
creates an XYZCommandParser
(where XYZ is a placeholder for the specific command name
e.g., AddCommandParser).
The XYZCommandParser then uses the other classes shown above to parse
the user command and create a XYZCommand object (e.g., AddCommand).
This XYZCommand is then returned as a Command object by
the InternTrackerParser.XYZCommandParser classes (
e.g., AddCommandParser, DeleteCommandParser, ...) inherit from
the Parser interface, allowing them to be treated similarly where possible,
especially during testing.API:
Model.java
The class diagram below provides an overview of the Model component:
The Model component has the following responsibilities:
InternApplication
objects.
These objects are stored in a UniqueApplicationList container.InternApplication objects, which is exposed to outsiders as an
unmodifiable ObservableList<InternApplication>.
This list can be observed, allowing the UI to automatically update
when its contents change (e.g. after a find or sort command).UserPref object that represents the user’s preferences. This is
exposed as a ReadOnlyUserPref object.Model does not depend on any of the other 3 components
(UI, Logic, Storage).
Since the Model represents data entities of the domain, it's designed
to stand independently of the other components.API:
Storage.java
The Storage component,
InternTrackerStorage and UserPrefStorage, which allows
it to be used as either one, depending on the functionality needed.Model component (because the Storage
component's job is to save/retrieve objects that belong to the Model).Classes that are used across multiple components are located within the
seedu.letsgethired.commons package.
These common classes served as shared utilities and functionalities that
contribute to the application's overall functionality.
For example, the seedu.letsgethired.commons.util.StringUtil class provides
commonly used string manipulation methods.
This section describes some noteworthy details on how certain features are implemented.
The add command enables users to add new internship application into the
Intern Tracker.
Adding a new internship application involves executing the AddCommand.
AddCommand is parsed by the AddCommandParser.AddCommandParser#parse() parses the user input and returns an AddCommand
object for execution.Given below is an example usage scenario outlining how the add command
behaves at each step.
Step 1. The user executes
add n/Jane Street r/Full Stack Developer c/Summer 2024
This command adds a new InternApplication into the InternTracker.
Note: Some fields for the add command are optional. For more information
on the add command, refer to
the User Guide.
Step 2. The AddCommandParser parses the arguments, ensuring that
compulsory fields are present and valid.
It then creates a new InternApplication object with all the provided fields
and returns an AddCommand object containing the
InternApplication object ready to be added to the Model.
Step 3. The AddCommand#execute() method is invoked by the LogicManager.
The AddCommand#execute() calls the Model#addInternApplication method to add
the newly created InternApplication object to the Model.
Step 4. The AddCommand#execute() method returns a new CommandResult
object that contains feedback and display messages for the user.
This result is then handed back to the LogicManager.
The sequence diagram below shows the process of adding a new internship application:
Note: The input for the AddCommand has been truncated for brevity.
Note: The lifeline for AddCommandParser and AddCommand
should end at the destroy marker (X)
but due to a limitation of PlantUML, the lifeline reaches the end of diagram.
The creation of the internApplication object has been omitted for brevity.
Aspect: Criteria for a identifying duplicate internship application entry:
COMPANY_NAME, ROLE and CYCLE) must be unique.
COMPANY_NAME The find command enables the users to search internship applications by
looking up a keyword in any of the fields associated with
an internship application.
Performing a Find operation involves executing the FindCommand.
FindCommand is parsed by the FindCommandParser.FindCommandParser#parse() parses the user input to return a FindCommand
object that will be executed.Given below is an example usage scenario and how the mechanism behaves at each step.
Step 1. The user keys in the command word to find an internship
application, find.
find n/Jane c/Summer
Note: At least one field to be searched and the respective keyword for searching should be provided.
Step 2.
The FindCommandParser will execute to get the field and keyword pairs
using the ArgumentTokenizer.
The parser creates a new CompanyContainsFieldKeywordsPredicate object,
which acts as a predicate that will be used to obtain a filtered list of
internship applications that have the specified keywords in respective fields.
The parser returns a FindCommand object with
the Predicate<InternApplication>, specifically the
CompanyContainsFieldKeywordsPredicate.
Step 3. The FindCommand#execute() method is invoked by the LogicManager.
The FindCommand calls the
Model#updateFilteredInternApplicationList() to update the filtered internship
application list using the
Predicate<InternApplication>, and then
the Model#getFilteredInternApplicationList() to obtain the filtered, sorted
internship application list.
Step 4. Finally, the FindCommand creates a CommandResult object that
contains feedback and displays the filtered internship application list to the
user.
The result is then returned to the LogicManager.
The sequence diagram below shows the process of finding internship applications.
Note: The lifeline for FindCommandParser and FindCommand
should end at the destroy marker (X)
but due to a limitation of PlantUML, the lifeline reaches the end of diagram.
The note command enables the users to add or delete notes to an internship application.
To add or delete a Note, the NoteCommand must be executed.
It is worth noting that the NoteCommand is implemented differently from the other Commands.
From the above class diagram, the NoteCommand is an abstract class that is
inherited by the NoteInsertCommand class
and the NoteDeleteCommand class. This is done so that
the NoteCommand#execute() method can behave accordingly while
still having both NoteCommand classes share the command word that is note.
The NoteCommand is parsed by
the NoteCommandParser. NoteCommandParser#parse() parses the user input to
return
either a NoteInsertCommand or a NoteDeleteCommand object that will be
executed.
Given below is an example usage scenario and how the mechanism behaves at each step for note addition.
Step 1. The user keys in the command word to add a note, note.
note 1 i/Need to revise Rust
This command appends the note to the internship application with the index 1.
Note: The INDEX for the note command is compulsory.
The i/ prefix is compulsory for adding a note, and cannot appear at the same
time as the o/ prefix for deleting a note.
For more information on the note command, refer to the
User Guide.
Step 2 The NoteCommandParser parses the arguments, ensuring that
the compulsory fields are present.
In particular, the parser checks that the i/ prefix is present and
the o/ prefix is absent.
The parser then returns a NoteInsertCommand object containing the Note
object ready to be added into Model
Step 3. The NoteCommand#execute() method is invoked by the LogicManager.
The NoteCommand#execute()
method creates a new InternApplication with the note appended to its
ArrayList of notes.
Step 4. The NoteCommand calls the Model#setInternApplication()
and Model#updateFilteredInternApplicationList()
methods to add the new internship application with the note to the model, and
replace the old internship application.
Step 5. The NoteCommand creates a CommandResult object that contains the
feedback and InternApplication to the user,
which is returned to the LogicManager.
The sequence diagram below shows the process of adding a note:
Note: The lifeline for NoteCommandParser and NoteInsertCommand
should end at the destroy marker (X)
but due to a limitation of PlantUML, the lifeline reaches the end of diagram.
The creation of the internApp and internAppToEdit objects have
been omitted for brevity.
Given below is an example usage scenario and how the mechanism behaves at each step for note deletion.
Step 1. The user keys in the command word to add a note, note.
note 1 o/2
This command deletes the note with index 2 from the internship application
with index 1.
Note: The INDEX for the note command is compulsory.
The o/ prefix is compulsory for deleting a note, and cannot appear at the same
time as the i/ prefix for adding a note.
For more information on the note command, refer to the
User Guide.
Step 2. The NoteCommandParser parses the arguments and ensures
that the compulsory fields are present.
In particular, the parser needs to check if the o/ prefix
is present and the i/ prefix is absent.
The parser then returns a NoteDeleteCommand object with the Index of the
object to be deleted from the Model.
Step 3. The NoteCommand#execute() method is called by the LogicManager.
The NoteCommand#execute()
method creates a new InternApplication with the corresponding note removed
from its ArrayList of notes.
Step 4. The NoteCommand calls the Model#setInternApplication()
and Model#updateFilteredInternApplicationList()
methods to add the new internship application with the note to the model, and
replace the old internship application.
Step 5. The NoteCommand creates a CommandResult object that contains
feedback and InternApplication to the user,
which is returned to the LogicManager.
The sequence diagram below shows the process of deleting a note.
Note: The lifeline for NoteCommandParser and NoteDeleteCommand
should end at the destroy marker (X)
but due to a limitation of PlantUML, the lifeline reaches the end of diagram.
The creation of the internApp and internAppToEdit objects have
been omitted for brevity.
The sort command enables the users to sort the internship applications by
a specific field.
Note: This implementation does not allow for sorting by multiple fields.
To introduce the sort feature, we make the following changes to the codebase:
Extension of the Model Interface: We enhance the Model interface to
include a new method:
Model#updateFilteredSortedInternApplicationList(Comparator<InternApplication> comparator)ModelManager Enhancements: In the ModelManager class, we wrap the
existing filteredInternApplications in a
JavaFX SortedList to create a new filteredSortedInternApplications field.
This new field, allows us to sort the intern applications to be displayed
based on the specified comparator.
Update existing methods:
Model#getFilteredInternApplicationList() is updated to return
the filtered and/or sorted intern application list.Note: JavaFX's SortedList class extends the ObservableList class, which
ensures that any changes made to either the FilteredList or the original
UniqueApplicationList will automatically propagate to the UI.
To understand how these changes are integrated into the application, refer to the sequence diagram below:
Note: The lifeline for SortCommandParser and SortCommand
should end at the destroy marker (X)
but due to a limitation of PlantUML, the lifeline reaches the end of diagram.
Aspect: How sorting is done
FilteredList in
a SortedList.
UniqueApplicationList.UniqueApplicationList in
the InternTracker.
UniqueApplicationList before saving the data to
preserve the initial order in which the intern applications are added.Aspect: Comparator
Comparator<InternApplication> object.
Comparator<InternApplication> object
for each sorting operation.equals() method
for Comparator only tests for referential equality.InternApplicationComparator class
The undo mechanism is facilitated by VersionedInternTracker. It
extends InternTracker and maintains an undo history internally as a
stack named savedStates.
Additionally, it implements the following operations:
VersionedInternTracker#commit()— Saves the current intern tracker state in
its history.VersionedInternTracker#undo()— Restores the previous intern tracker state
from its history.VersionedInternTracker#undo() is exposed in the Model interface
as Model#undoAction().
Given below is an example usage scenario and how the undo mechanism behaves at each step.
Step 1. The user launches the application.
The VersionedInternTracker will be initialized with an empty savedStates.
Step 2. The user executes delete 5 command to delete the 5th
internApplication
from the intern tracker.
The delete command calls Model#deleteInternApplication(), which
calls VersionedInternTracker#commit(),
capturing a copy of the current internApplications to savedStates before
executing the delete action.
Step 3. The user adds a new internship application.
add n/Google r/Software Engineer c/Summer 2024
The add command calls Model#add() which also calls
VersionedInternTracker#commit(),
adding a copy of the current internApplications to savedStates
before executing the add action.
Note: If a command execution fails, the
internApplications state will not be added to savedStates
(i.e. VersionedInternTracker#commit() will not be called).
Step 4. The user now decides that adding the internApplication was a
mistake,
and decides to undo that action
by executing the undo command. The undo command will
call Model#undoAction(), which pops the latest
internApplications state from savedStates and assigns it to the current
internApplications.
Note: If the size of savedStates is 0, meaning the stack is empty, then
there are no previous
internApplications states to restore. The undo command
calls VersionedInternTracker#undo(), which returns
False if there are no states to restore, and displays a message to the user that
the latest change has already been reached.
The following sequence diagram shows how the undo operation works:
Note: The lifeline for UndoCommand should end at the destroy marker (X)
but due to a limitation of PlantUML, the lifeline reaches the end of diagram.
Step 5. The user then decides to execute the command list. Commands that
do
not modify the intern tracker,
such as list, will usually not
call VersionedInternTracker#commit(), Model#undoAction()
Thus, the savedStates remains unchanged.
The following activity diagram summarizes what happens when a user executes a new command:
Aspect: How undo executes:
Alternative 1 (current choice): Saves the entire intern tracker.
Alternative 2: Implement an undo operation
for each individual command.
delete, it only saves the
internApplication being deleted).Command and an
implementation for each individual command.Aspect: How history is implemented:
Alternative 1: Using a list and pointer to implement version control
redo.Alternative 2 (current choice): Store the saved state in a stack
undo.redo operations.This feature allows the user to click on an InternApplicationCard in the
InternApplicationListPanelto display the details of the InternApplication.
The Card click mechanism is implemented by creating a GridPane beside
the InternApplicationListPanel
and a listener function to handle the event of a card click. The GridPane
notably comprises 1 TextArea for notes
and 5 TextFields for other details of an Intern Application
The following class is created:
SelectView - This class represents the panel responsible for displaying the
details of the card.The following methods are added:
SelectView#displayDetails(InternApplication internApplication) -
sets each details in the intern application in each corresponding TextField
or TextArea.SelectView#clearDetails() -
clears all contents in the SelectView's TextField or TextArea.InternApplicationListPanel#setSelectedItemListener() -
adds a listener method to the ListView model that calls
the SelectView#displayDetails(InternApplication internApplication)
whenever a different
item on the list is selectedInternApplicationListPanel#getSelectedItemIndex() -
returns the index of the currently selected item in the ListViewGiven below is an example usage scenario and how the mechanism behaves at each step.
Step 1. The user clicks on the intern application card he wants to view.
Step 2 The ChangeListener that was set into the ListView triggers from the
event and executes
a method to execute view INDEX where INDEX is the corresponds to the item's
relative index on the list.
Step 3. The Logic creates a CommandResult object from
the ViewCommand#execute(). The CommandResult contains
a String feedback and InternApplication to the user.
Step 4. The InternApplication in the CommandResult is then passed into
the
SelectView#displayDetails(InternApplication internApplication)) where each
field in the intern application is
displayed in its respective TextArea or TextField.
The following sequence diagram high level view of how the Card Click feature works:
Note: The internApplication object is present in the CommandResult.
The method call to obtain the internApplication object has been omitted for
brevity.
Aspect: What data type should displayDetails take in:
Alternative 1 (current choice): InternApplication Object.
InternApplication in
both InternApplicationListPanel and SelectViewAlternative 2: String containing all field data in the involved
InternApplication Object
InternApplicationList, SelectView,
and InternApplicationHere are the definitions of some terms which is used throughout the User Guide and Developer Guide.
| Term | Definition |
|---|---|
| Command Line Interface (CLI) | A type of user interface in which the user interacts with a system by typing commands into a terminal or console. |
| Graphical User Interface (GUI) | A type of user interface that allows users to interact with a system through graphical icons and visual indicators. |
| Hyperlink (link) | A reference in the webpage that allows users to directly access another location or file within the same or a different webpage. |
| Command Terminal | A software-based interface that provides an environment for users to interact with a computer's operating system or software by typing textual commands and receiving text-based output. |
| Sample Data | Pre-populated data used for demonstration purposes, enabling new users to see how the application functions with realistic examples. |
| Workflow | A systematic and repeatable pattern of activity that a user follows to accomplish a specific task. |
| Command | An input from the user that tells LetsGetHired which action to perform. |
| Parameter | A placeholder used in a command to represent a piece of information that needs to be provided when that command is executed. |
| JSON (JavaScript Object Notation) | A lightweight data-interchange format that is easy for humans to read and write and easy for machines to parse and generate. |
Target user profile:
Value proposition: provides a fast and organized way to see internships and its progress, optimized for users who prefer a CLI
Priorities: High (must have) - * * *, Medium (nice to have) - * *, Low
(unlikely to have) - *
| Priority | As a ... | I want to ... | So that I can... |
|---|---|---|---|
* * * | user | add internship applications | keep a record of my internship application |
* * * | user | see a list of internships that I have applied for | keep track of all companies/roles I have applied for |
* * * | user | view a specific internship application | easily access details about a specific internship application |
* * * | user | delete an internship application | remove internship applications I do not want to track anymore |
* * * | user | update the status of the internships that I have applied for | keep track of the progress of the roles I have applied for |
* * * | user | edit an internship application | update or change details for an internship application |
* * * | user | open the app with a click of a button or an exe/batch file | save time and easily access the internship tracker |
* * | user with many applications | quickly search for a application | efficiently find the entry I am looking for |
* * | conscientious user | attach notes to each application | jot down important information about the company or application process |
* * | organised user | sort my applications | easily get an organised view of my applications |
(For all use cases below, the System is the LetsGetHired application
and the Actor is the User, unless specified otherwise)
UC1: Add an internship application
MSS
User inputs the details of the internship application.
LetsGetHired adds the internship application to the list of internship applications and displays it.
Use case ends.
Extensions
1a. The command format is incorrect.
1a1. LetsGetHired notifies the user of the error.
1a2. User enters the correct details for the internship application.
Use case resumes from Step 2.
1b. The internship application already exists in the list of internship applications.
1b1. LetsGetHired notifies the user that the internship application already exists.
Use case ends.
UC2: View the list of internship applications
MSS
User requests to list all internship applications.
LetsGetHired displays all the internship applications.
Use case ends.
UC3: View an internship application
MSS
User requests to list all internship applications (UC2)
User requests to view a specific internship application.
LetsGetHired displays the specified internship application.
Use case ends.
Extensions
1a. LetsGetHired displays an empty list.
Use case ends.
2a. The command format is incorrect.
2a1. LetsGetHired notifies the user of the error.
Use case resumes from Step 2.
2b. The index of internship application entered does not exist.
2b1. LetsGetHired shows an error message.
Use case resumes from Step 2.
UC4: Delete an internship application
MSS
User requests to list all internship applications (UC2).
User requests to delete a specific internship application.
LetsGetHired deletes the specified internship application.
Use case ends.
Extensions
1a. The list is empty
Use case ends.
2a. The command format is incorrect.
2a1. LetsGetHired notifies the user of the error.
Use case resumes from Step 2.
2b. The index of internship application entered does not exist
2b1. LetsGetHired shows an error message.
Use case ends.
UC5: Search for an application
MSS
User requests for a search by specific criteria.
LetsGetHired shows a list of matching applications.
Use case ends.
Extensions
1a. The command format is incorrect.
1a1. LetsGetHired notifies the user of the error.
Use case resumes from Step 1.
UC6: Edit the details of an application
MSS
User requests to list all internship applications (UC2).
User provides new information to edit the chosen application.
LetsGetHired edits the application and displays it.
Use case ends.
Extensions
1a. The list is empty
Use case ends.
2a. The command format is incorrect.
2a1. LetsGetHired notifies the user of the error.
Use case resumes from Step 2.
2b. The index of internship application entered does not exist
2b1. LetsGetHired shows an error message.
Use case ends.
UC7: Add a note to an application
MSS
User requests to list all internship applications (UC2).
User provides note to add to specific application.
LetsGetHired adds the note to the application and displays the application.
Use case ends.
Extensions
1a. The list is empty.
Use case ends.
2a. The command format is incorrect.
2a1. LetsGetHired notifies the user of the error.
Use case resumes from Step 2.
2b. The index of internship application entered does not exist.
2b1. LetsGetHired shows an error message.
Use case ends.
UC8: Delete a note on an application
MSS
User requests to view a specific application (UC3).
User requests to delete a specific note from the application.
LetsGetHired deletes the note from the application and displays the updated application.
Use case ends.
Extensions
1a. The application has no notes.
Use case ends.
2a. The command format is incorrect.
2a1. LetsGetHired notifies the user of the error.
Use case resumes from Step 2.
2b. The index of internship application entered does not exist.
2b1. LetsGetHired shows an error message.
Use case ends.
2c. The given note index is invalid.
2c1. LetsGetHired shows an error message.
Use case resumes from step 2.
UC9: Sort Applications
MSS
User requests to sort the applications by provided category and order.
LetsGetHired sorts and displays the sorted applications.
Use case ends.
Extensions
1a. Provided category or order is invalid
1a1 LetsGetHired shows an error message and shows the valid categories and orders to choose from.
Use case ends.
11 or above
installed.Given below are instructions to test the app manually.
Note: These instructions only provide a starting point for testers to work on; testers are expected to do more exploratory testing.
Initial launch
Download the jar file and copy into an empty folder
Type the following command in your terminal:
java -jar letsgethired.jar
Expected: Shows the GUI with a set of sample internship applications. The window size may not be optimal.
Saving window preferences
Resize the window to an optimum size. Move the window to a different location. Close the window.
Re-launch the application by typing the following command in your terminal:
java -jar letsgethired.jar
Expected: The most recent window size and location is retained.
InternApplicationPrerequisites: Launch the app
Test case: add n/Optiver r/Quantitative Trader c/Summer 2024
Expected: The InternApplication is added to the list.
The added internship application is displayed in the select view.
Test case: add n/Jump Trading r/Quantitative Researcher c/Summer 2024 s/Deleted
Expected: No InternApplication is added to the list. Error message is displayed.
Other incorrect add commands to try: add, add ..., where (... are parameters with invalid values or
missing required parameters)
Expected: Similar to previous.
InternApplicationPrerequisites: List all InternApplications using the list command.
Multiple InternApplications in the list.
Test case: edit 1 r/Software Engineer c/Summer 2024
Expected: The first InternApplication in the list is edited and the Role is set to Software Engineer and
the Cycle is set to Summer 2024. The edited internship application is displayed in the select view.
Test case: edit 0
Expected: No InternApplication is edited. Error message is displayed.
Test case: edit s/Deleted
Expected: No InternApplication is edited. Error message is displayed.
Other incorrect edit commands to try: edit, edit ..., edit x where (... are parameters with invalid values
and x is larger than the list size)
Expected: Similar to previous.
note in an InternApplicationPrerequisites: List all InternApplications using the list command.
Multiple InternApplications in the list.
Test case: note 1 i/Prepare for behavioural questions
Expected: A new Note is added to the first InternApplication in the list.
The internship application with the new note is displayed in the select view.
Test case: note 0 i/Prepare for machine learning questions
Expected: No Note is added to any InternApplication. Error message is displayed.
Other incorrect note commands to try: note, note x i/Prepare for behavioural questions where
(x is larger than the list size)
Expected: Similar to previous.
note from an InternApplicationPrerequisites: List all InternApplications using the list command.
Multiple InternApplications in the list.
Test case: note 1 o/1
Expected: The first Note from the first InternApplication in the list is deleted.
The internship application with the deleted note is displayed in the select view.
Test case: note 0 o/1
Expected: No Note is deleted from any InternApplication. Error message is displayed.
Test case: note 1 o/0
Expected: No Note is deleted from any InternApplication. Error message is displayed.
Other incorrect note commands to try: note, note x o/1, note 1 o/y where (y is larger than the number
of notes in the first InternApplication in the list and x is larger than the list size)
Expected: Similar to previous.
InternApplicationPrerequisites: List all InternApplications using the list command.
Multiple InternApplications in the list.
Test case: view 1
Expected: The first InternApplication in the list is displayed in the select view.
Test case: view 0
Expected: No InternApplication is displayed in the select view. Error message is displayed.
Other incorrect view commands to try: view, view x (where x is larger than the list size)
Expected: Similar to previous.
InternApplicationPrerequisites: List all InternApplications using the list command.
Multiple InternApplications in the list.
Test case: find n/Jane Street c/Summer 2024 r/Software Engineer
Expected: All the InternApplications with either the Company name containing Jane Street and Role
containing Software Engineer and Cycle containing Summer 2024 are displayed in the list view.
Test case: find
Expected: All InternApplications are displayed in the list view. Error message is displayed.
InternApplicationsPrerequisites: List all InternApplications using the list command.
Multiple InternApplications in the list.
Test case: sort n/a
Expected: All the InternApplications are displayed in the list view in sorted order by Company in ascending order.
Test case: sort s/d
Expected: All the InternApplications are displayed in the list view in sorted order by Status in descending order.
Test case: sort c/n
Expected: All the InternApplications are displayed in the list view. Error message is displayed.
Other incorrect sort commands to try: sort, sort ..., where (... are parameters with invalid values
or more than one parameter)
Expected: Similar to previous.
InternApplicationPrerequisites: List all InternApplications using the list command.
Multiple InternApplications in the list.
Test case: delete 1
Expected: First InternApplication is deleted from the list.
Details of the deleted internship application shown in the status message.
Test case: delete 0
Expected: No InternApplication is deleted. Error message is displayed.
Other incorrect delete commands to try: delete, delete x (where x is larger than the list size)
Expected: Similar to previous.
Prerequisites: Execute some command that modifies any InternApplication - add, edit, note or delete,
or modifies the list of internship applications - find.
Test case: undo
Expected: Undoes the modification to the InternApplication and the list of internship applications.
Test case: undo, without any command being executed before the undo
Expected: No change to any InternApplication or the list of internship applications.
LetsGetHired saves your data locally after any command you execute.
Dealing with a missing data folder
Prerequisites: On app launch, if no data folder is detected within the same directory as the jar file.
Test case: Run any command and a new data folder containing a letsgethired.json file will be generated.
Test case: If you do not run any command and quit the app, no data folder or file will be generated.
Dealing with a missing data file (letsgethired.json)
Prerequisites: On app launch, if there is an empty data folder within the same directory as the jar file.
Test case: Run any command and a letsgethired.json file will be generated within the data folder.
Test case: If you do not run any command and quit the app, no data file will be generated.
Dealing with a corrupted data file (letsgethired.json)
Prerequisites: On app launch, if the letsgethired.json file in the data folder within the same directory as the jar file is corrupted.
Test case: Run any command and the contents of the letsgethired.json file will be overwritten to a json file with no data.
In crafting LetsGetHired, a lot of thought was put into delivering a user-centric application that simplifies internship application tracking. We prioritized user experience with a revamped GUI and enhanced internship application organization through features like sort and find. We also provided users the flexibility to attach helpful information to entries, through the introduction of notes.
Designing organizational features in LetsGetHired, such as the Find and Sort commands, presented a notable advancement beyond the capabilities of AB3. While AB3 exclusively features a basic Find function that searches for entries based on matching keywords to names in the address book, in LetsGetHired, the Find command empowers users to conduct searches across various fields associated with internship applications simultaneously. Additionally, we took it one step further, enhancing the Find command in LetsGetHired to accommodate partial matches, giving our users more flexibility and freedom.
The introduction of the Sort command in LetsGetHired stands as another milestone in organizational design. LetsGetHired enables users to sort their internship applications in ascending or descending order based on any field. This functionality provides users with the ability to customize the organization of their application.
We undertook a substantial overhaul of the GUI in LetsGetHired, distinguishing it from the interface of AB3. LetsGetHired embraces a visually appealing GUI that facilitates in-depth exploration of application details through a select view. This transition required intricate design decisions to seamlessly integrate additional functionalities for detailed application viewing and adding of notes that demand larger screen real estate. In our commitment to user experience, we also interactivity with the GUI through an ability to view applications from the list view by clicking on the corresponding card.
Notes play an integral part in LetsGetHired, allowing users to add many pieces of information associated with an internship application. We deliberated on how notes should be created, viewed, deleted and integrated into LetsGetHired's existing and future functionalities, such as searching for an application by notes. This addition allowed us to introduce another dimension to LetsGetHired, adding depth and nuance to the application management experience.
Current Implementation: In the current version of our application, when a
user inputs a command with missing compulsory fields, the application responds
with a generic error message: Invalid Command Format!. This is followed by the
correct usage of the command. While this approach informs the user of an error,
it lacks specificity in identifying the exact cause of the error, particularly
which compulsory field(s) are missing.
Planned Enhancement: We aim to improve user experience and error feedback by implementing a more detailed error reporting system. This enhancement will enable the application to not only detect that an invalid command has been entered but also identify and highlight the specific missing compulsory fields.
Proposed Changes:
Error Detection Algorithm: Modify the command parsing algorithm to include checks for each compulsory field. This will enable the system to pinpoint which field(s) the user failed to provide.
User Feedback Enhancement: When a command is identified as invalid due to
missing fields, the application will generate a tailored error message. This
message will specifically list the missing compulsory field(s), guiding the
user to correct the specific mistake. For example, if a user forgets to input
the CYCLE field in a command, the error message would
be: Invalid Command Format! Missing field: CYCLE. This message will be
followed by the correct usage of the command.
Expected Benefits:
Current Implementation: In the current version of our application, when a
user inputs an unrecognized command, the system simply displays a
message: Unknown Command. This response, while accurate, does not assist the
user in understanding why the command was unrecognized or how to correct it.
Planned Enhancement: We plan to introduce a more intuitive error handling mechanism for unknown commands, akin to the approach used in Git. This enhancement will involve suggesting commands similar to the user's input, which can be particularly useful in cases where the user has made a typing error.
Proposed Changes:
Command Suggestion Algorithm: Implement an algorithm that detects and
suggests similar commands when an unknown command is entered. For example, if
a user mistakenly types ad instead of add, the system will suggest the
correct command: Unknown Command: 'ad'. Did you mean 'add'?.
Synonym Recognition: Enhance the command parsing logic to recognize
synonyms or commonly used alternatives for certain commands. For instance, if
a user types search or filter instead of find, the application could
respond with a suggestion: Unknown Command: 'search'. Do you mean 'find'?.
Expected Benefits:
Current Implementation: In the current version of our application, when a new internship application is added to our list, it is placed at the bottom. This positioning often renders the new entry outside the user's current view, requiring them to manually scroll down to locate the latest addition.
Planned Enhancement: We are planning to enhance the user experience by changing how newly added internship applications are displayed. The key improvement will be automatically scrolling the list to bring the newly added application into view immediately. Additionally, we are considering placing new entries at the top of the list rather than at the bottom.
Proposed Changes:
Automatic Scrolling: Modify the list view functionality to automatically scroll to the position of the newly added internship application. This ensures that the latest entry is immediately visible to the user without requiring manual navigation.
List Ordering Modification: Change the default order of the list to display new applications at the top. This approach aligns with common user expectations, where the most recent items are readily accessible.
Expected Benefits:
Current Implementation: In the current version of our application, the
application only allows sorting of internship applications by
ONE field at a time using parameters such as c/a for sorting by cycles in
ascending order or n/d for sorting by company names in descending order.
Planned Enhancement: Enable sorting by multiple fields to enhance the flexibility of data organization. This improvement addresses the limitation of the current sorting functionality, allowing users to sort data by more than one criterion at a time. For example, users should be able to sort first by cycle in ascending order and then by company name in ascending order using the following command:
sort c/a n/a
This means that if 2 internship applications have the same cycle, for example
Summer 2024, they will be sorted by company name in ascending order
(Apple before Google).
Proposed Changes:
Note: The InternApplicationComparator class already contains a
createCompositeComparator() method that can be used to combine multiple
InternApplication comparators into a single comparator.
ArgumentTokenizer to parse the order of prefixes.SortCommandParser to allow for multiple sorting criteria.Expected Benefits:
Current Implementation: In the current version of our application, users are able to undo changes made using the Undo command. This allows users to revert formerly destructive commands, for a more forgiving and beginner-friendly experience. We see a redo function as a natural progression from undo, where users will be given greater agency in managing their internship applications.
Planned Enhancement: We plan to implement a Redo command that will allow users to redo commands that were undone. This change empowers users to have greater flexibility in managing their internship applications by enabling users to toggle between app states with ease.
Proposed Changes:
Undone States History: Store undone states in a separate history, similar to how past states are stored currently.
Redo Command : Introduce a new command : Redo, that will redo a command that was previously undone or notify the user that there are no commands to redo.
Expected Benefits:
Current Implementation: In the current version of our application, when a user sorts by a particular field, there will be no way for the user to revert to the initial sort order. The only way to revert to the default sort order is by restarting the app.
Planned Enhancement: We plan to introduce a way for users to revert the list to its default sort order. This enhancement may be particularly useful for users who which to see the list sorted in the order they added the intern application entries in.
Proposed Changes:
Add new Id field into InternApplication class: The idea behind this change
is to mimic the identifier key that is present in most SQL databases. This way,
we will be able to seamlessly sort the InternApplications according to their ID
which is the order in which they are added.
New Id Class: The Id class will encapsulate the identifier key integer for
the corresponding InternApplication.
The class will also have a static counter variable to count the total number of
intern applications that is added while the app is running. This helps to ensure
that none of the InternApplication objects has duplicate key values.
Id#generateUseableId() is a factory method responsible for generating an ID key
that is not used by any intern applications yet.
It is also worth noting that the Id value will not be passed into the
serialised JSON format as we wish for the keys to be dynamically assigned at every
run of the application. This way, it is unlikely for integer overflow in the Id
value.
SortCommand: The SortCommand class will be changed to behave differently
whenever the user enters sort default into the CommandBox. The SortCommandParser
will see that none of the prefixes are present in the input. After which, it will
check the preamble. If the preamble contains the string "default", the SortCommand
will execute the sort logic to sort by the Id class.
Expected Benefits:
Current Implementation: The current version of our application does not support the feature of editing a particular note in the note list. The only operations we offer for note management is adding and deleting notes as those two are most crucial.
Planned Enhancement: We plan to make further enhancements to facilitate editing of notes. This feature will be useful for users as it saves them the hassle of deleting a note and re-adding it to keep their notes updated.
Proposed Changes:
New NoteEditCommand Class: Create a new class called NoteEditCommand.
Similar to the NoteInsertCommand and NoteDeleteCommand, the
NoteEditCommand will inherit from the NoteCommand class and behave in
accordance to edit a particular note. The class will require 3 parameters
in the constructor: The index of the application, the index of the note,
and the String input note that the user wants to store.
Additional function in InternApplication Class: An additional function
is required to represent the behavior that we want in note editing. Namely,
InternApplication#editNote() will take in 2 parameters: The index of the
note, and the string of input note to be stored. The function makes a copy
of its immutable list of notes into a mutable one and swaps the Note in the
specified index input with a newly constructed Note from the input string.
The function then returns a new InternApplication with the updated notes.
NoteCommandParser Changes: The current version of our app throws an
exception when both PREFIX_NOTE_DELETE and PREFIX_NOTE_INSERT is detected.
The proposed change to make way for note editing is to remove the thrown
exception line in place of a NoteEditCommand object.
Expected Benefits:
Current Implementation: The current implementation of sorting by status results in a behavior where the statuses are sorted in lexicographical order.
Planned Enhancement: We plan to change the way Status is sorted to make the sort logic more meaningful. (e.g. Rejected and Accepted internships are lower than all the other statuses because they are "completed" applications with no further follow-ups)
Proposed Changes:
Status compareTo Method: Rather than comparing the 2 strings
lexicographically, we compare the enum representation of the strings from both
objects.
Status StatusEnum nested class: We propose to rearrange the enums such that
the statuses reflect the chronological order in an internship application process.
The order of importance is as follows:
Pending > Assessment > Interview > Offered > Accepted > Rejected
Expected Benefits:
Status is sorted, it will now show the more urgent
applications to be followed up on to the user either on the top or at the bottom
depending on whether the user sorted it in ascending or descending order.