Developer Guide
- Acknowledgements
- Setting up, getting started
- Design
- Implementation
- Documentation, logging, testing, configuration, dev-ops
- Appendix: Requirements
-
Appendix: Instructions for manual testing
- Launch and shutdown
- Display help
- Listing all internships
- Viewing statistics
- Exiting application
- Adding an internship
- Deleting an internship
- Updating status of an internship
- Adding tags to an internship
- Deleting tags from an internship
- Selecting an internship
- Editing an internship
- Adding a task to an internship
- Deleting a task from an internship
- Adding a remark to an internship
- Sending an email
- Clearing data
- Filtering internships by company name
- Filtering internships by position name
- Filtering internships by tags
- Filtering internships by status
- Sorting internships
- Saving data
Acknowledgements
- The feature
remark
(including the code) was reused with some changes from AB-3’s Tutorial: Adding a Command. - The format of the Developer Guide was inspired by the Developer Guide of the past project ArchDuke.
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 the 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 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
, InternshipListPanel
, 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
The UI
component,
- executes user commands using the
Logic
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 displaysInternship
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 theInTrackParser
class to parse the user command. - This results in a
Command
object (more precisely, an object of one of its subclasses e.g.,AddCommand
) which is executed by theLogicManager
. - The command can communicate with the
Model
when it is executed (e.g. to add an internship). - 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 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
InTrackParser
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 theInTrackParser
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
The Model
component,
- stores the internship application data i.e., all
Internship
objects (which are contained in aUniqueInternshipList
object). - stores the currently ‘selected’
Internship
objects (e.g., results of a search query) as a separate filtered list which is exposed to outsiders as an unmodifiableObservableList<Internship>
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)
Tag
list in the InTrack
, which Internship
references. This allows InTrack
to only require one Tag
object per unique tag, instead of each Internship
needing their own Tag
objects.Storage component
API : Storage.java
The Storage
component,
- can save both internship application data and user preference data in json format, and read them back into corresponding objects.
- inherits from both
InTrackStorage
andUserPrefStorage
, 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.intrack.commons
package.
Implementation
This section describes some noteworthy details on how certain features are implemented.
Add internship application feature
About this feature
The add internship application feature allows users to quickly add an internship application in the tracker via the
command add c/COMPANY p/POSITION e/EMAIL w/WEBSITE s/SALARY [t/TAG]...
.
How it is implemented
The add
command is facilitated by the AddCommand
and the AddCommandParser
. It uses the ArgumentTokenizer#tokenize(String argString, Prefix... prefixes)
to extract the relevant inputs for each field. A new Internship
object is then created with the corresponding company name, position, email, website, salary and tag.
The status field, by default, will be set to Progress
. The InTrack#addInternship(Internship target)
which is exposed in the Model
interface as
Model#addInternship(Internship target, Internship editedInternship)
is called to add the new Internship
object to the list of internship applications.
Parsing user input
- The user inputs the
add
command. - The
InTrackParser
processes the input and creates a newAddCommandParser
. - The
AddCommandParser
then callsArgumentTokenizer#tokenize(String argString, Prefix... prefixes)
to extract the relevant inputs for each field. If any prefix is absent but compulsory or invalid, aParseException
would be thrown. - The respective
Name
,Position
,Email
,Website
,Salary
andTag
constructors then check for the validity of parsed inputs. If any of the parsed inputs are absent but compulsory or invalid, aParseException
would be thrown. - The
AddCommandParser
then creates theAddCommand
based on the processed input.
Command execution
- The
LogicManager
executes theAddCommand
. - The
AddCommand
then creates a newInternship
object with the corresponding parsed inputs for each field. - The
AddCommand
then callsInTrack#addInternship(Internship target, Internship editedInternship)
to add the newInternship
object to the list of internship applications.
Displaying of result
- Finally, the
AddCommand
creates aCommandResult
with a success message and returns it to theLogicManager
to complete the command execution. The GUI would also be updated with the change of status.
The following sequence diagram shows how the add
command works:
The following activity diagram shows what happens when a user executes a add
command:
Design considerations
Aspect: Command to add status of an internship application
Most internship applications added by users would still be in progress, so a default “Progress” status is provided for
each new Internship
instead of requiring the user to provide one initially, saving time. As such, there is no need for
a prefix for the Status
field.
Update internship application status feature
About this feature
The update internship application status feature allows users to quickly update the status of an internship application
in the tracker via the command status INDEX STATUS
, where INDEX
must be a positive integer within the list and
STATUS
must be either o
(for Offered), p
(for in Progress) or r
(for Rejected).
How it is implemented
The status
command is facilitated by the StatusCommand
and the StatusCommandParser
. It uses the List#get(int index)
on the list of internship applications returned from the Model#getFilteredInternshipList()
to get the target Internship
object to be updated. A new Internship
object is then created with the new status. The
InTrack#setInternship(Internship target, Internship editedInternship)
which is exposed in the Model
interface as
Model#setInternship(Internship target, Internship editedInternship)
is called to replace the target Internship
object
with the updated one.
Parsing user input
- The user inputs the
status
command. - The
InTrackParser
processes the input and creates a newStatusCommandParser
. - The
StatusCommandParser
then callsParserUtil#parseIndex(String oneBasedIndex)
to check for the validity ofINDEX
. IfINDEX
is absent or invalid, aParseException
would be thrown. - The
StatusCommandParser
then checks for the validity ofSTATUS
. IfSTATUS
is absent or invalid, aParseException
would be thrown. - The
StatusCommandParser
then creates theStatusCommand
based on the processed input.
Command execution
- The
LogicManager
executes theStatusCommand
. - The
StatusCommand
calls theModel#getFilteredPersonList()
andList#get(int index)
to get the targetInternship
object to be updated based on the providedINDEX
. - The
StatusCommand
then creates a newInternship
object with the same variables as the target one except with the new status. - The
StatusCommand
then callsInTrack#setInternship(Internship target, Internship editedInternship)
to replace the targetInternship
object with the updated one.
Displaying of result
- Finally, the
StatusCommand
creates aCommandResult
with a success message and returns it to theLogicManager
to complete the command execution. The GUI would also be updated with the change of status.
The following sequence diagram shows how the status
command works:
The following activity diagram shows what happens when a user executes a status
command:
Design considerations
Aspect: Command to update status of an internship application
Most internship applications added by users would still be in progress, so a default “Progress” status is provided for
each new Internship
instead of requiring the user to provide one initially, saving time. As such, there is no need for
a prefix for the Status
field and the edit
command will not work in this case. Having a separate status
command
allows for the format to be kept short and simple which further increases the ease of updating the status of internship
applications.
Add internship application task feature
About this feature
The add internship application task feature allows users to add a task associated to an internship application
in the tracker via the command addtask TASK_NAME /at TASK_TIME
, where TASK_NAME
must not be an empty string, and
TASK_TIME
must be in the format dd-MM-yyyy HH:mm
.
How it is implemented
The addtask
command is facilitated by the AddTaskCommand
and AddTaskCommandParser
. It uses the
internship applications returned from the Model#getSelectedInternship()
to
get the target Internship
object to be updated. A new Internship
object is then created with the new Task
updated
in the List<Task>
. The InTrack#setInternship(Internship target, Internship editedInternship)
which is exposed in the
Model
interface as Model#setInternship(Internship target, Internship editedInternship)
is called to replace the
target Internship
object with the updated one.
Parsing user input
- The user inputs the
addtask
command. - The
InTrackParser
processes the input and creates a newAddTaskCommandParser
. - The
AddTaskCommandParser
then checks for the validity ofTASK_NAME
andTASK_TIME
. If eitherTASK_NAME
orTASK_TIME
is absent or invalid, aParseException
would be thrown. - The
AddTaskCommandParser
then creates theAddTaskCommand
based on the processed input. - The
AddTaskCommand
throws aCommandException
if no internship was selected.
Command execution
- The
LogicManager
executes theAddTaskCommand
. - The
AddTaskCommand
calls theModel#getSelectedInternship()
to get the targetInternship
object to be updated based on the selected internship application. - The
AddTaskCommand
then creates a newInternship
object with the same variables as the target and adds the new task to theList<Task>
. - The
AddTaskCommand
then callsInTrack#setInternship(Internship target, Internship editedInternship)
to replace the targetInternship
object with the updated one.
Displaying of result
- Finally, the
AddTaskCommand
creates aCommandResult
with a success message and returns it to theLogicManager
to complete the command execution. The GUI would also be updated with the new task added.
The following sequence diagram shows how the addtask
command works:
The following activity diagram shows what happens when a user executes a addtask
command:
Add internship remark feature
About this feature
The add internship remark feature allows users to add a remark to his/her internship interview information via the command
remark r/
.
How it is implemented
The implemented remark
command is facilitated by RemarkCommand
and RemarkCommandParser
. It enables users to add a Remark to their internship information.
It uses the get(0)
on the list of internships received from getSelectedInternshipList()
which is exposed to the Model
interface as Model#getSelectedInternshipList()
to
get an Internship Object. A new Internship object is then created with the new remark. Then theInTrack#setInternship(Internship target, Internship editedInternship)
which is exposed in the Model interface as
Model#setInternship(Internship target, Internship editedInternship)
, is used to replace the old Internship panel with the new one.
Given below is how the remark mechanism behaves at each step.
Parsing User input
-
The user inputs the
remark
command and ther/
prefix and finally theREMARK_CONTENT
that he/she wants to add. -
The ‘InTrackParser’ then parses the user input and checks if the command word and arguments are correct before creating a new
RemarkCommandParser
. -
The
RemarkCommandParser
then parses the user input and checks if the input variables are correct by checking for the presence of the prefixes. It also checks whether the command is in the correct format. The correct format of the input isr/REMARK_CONTENT
. AParseException
will be thrown if the format is incorrect. -
If the format is correct,
RemarkCommandParser
will create aRemarkCommand
based on the given inputs.
Command execution
-
The
LogicManager
executes theRemarkCommand
. -
The
RemarkCommand
obtains a list ofInternship
s via thegetSelectedInternshipList()
method which is exposed to theModel
interface asModel#getSelectedInternshipList()
. -
The
RemarkCommand
obtains theInternship
object that the user wants to add the remark to via theget(0)
method from list ofInternship
s. ACommandException
will be thrown if an internship is not selected. -
The
RemarkCommand
then creates a newInternship
object with the same variables as the oldInternship
except for theREMARK_CONTENT
that the user has input. -
RemarkCommand
then call theModel#setInternship(internshipToEdit, editedInternship)
to replace the oldInternship
with the newInternship
with the newRemark
Displaying of result
- Finally, the
RemarkCommand
creates aCommandResult
with a success message and returns it to theLogicManager
to complete the command execution. The GUI would also be updated on this change in the internship list and update the display of theInternship
respectively.
The following sequence diagram shows how the remark
command works:
The following activity diagram summarises what happens when a user executes the remark
command:
Design considerations
Aspect: Command to add remark to an internship application
When a user has just added an internship application, he probably has not been to the internship interview yet,
so he would not have any remarks or notes to take about the interview process yet. Thus, the default remark
field will
be empty for each new Internship
instead of requiring the user to provide one initially, saving time.
Find internship application by company name feature
About this feature
The find internship application by company name feature allows users to query the list of added internship applications
for applications that match the desired company name via the command findc COMPANY_NAME
, where COMPANY_NAME
must not
be an empty string.
How it is implemented
The findc
command is facilitated by the FindNameCommand
, FindNameCommandParser
and the NameContainsKeywordsPredicate
.
It uses Model#updateFilteredInternshipList(Predicate<Internship> predicate)
to apply the NameContainsKeywordsPredicate
in order to produce a filtered list containing only entries whose names correspond to COMPANY_NAME
.
Parsing user input
- The user inputs the
findc
command. - The
InTrackParser
processes the input and creates a newFindNameCommandParser
. - The
FindNameCommandParser
then trims the input to remove whitespace. If the input is an empty string, aParseException
would be thrown. - The
FindNameCommandParser
then creates the newFindNameCommand
based on the processed input.
Command execution
- The
LogicManager
executes theFindNameCommand
. - The
FindNameCommand
calls theModel#updateFilteredInternshipList(Predicate<Internship> predicate)
to update the current internship list to only show internship applications matching the providedCOMPANY_NAME
.
Displaying of result
- Finally, the
FindNameCommand
creates aCommandResult
containing the number of matching internship applications and returns it to theLogicManager
to complete the command execution. The GUI would also be updated with the change in list.
The following sequence diagram shows how the findc
command works:
The following activity diagram shows what happens when a user executes a findc
command:
Sort internship feature
About this feature
The sort internship feature allows users to sort the list of internship application via the given parameter in the given
order via the command sort SORT_TYPE SORT_ORDER
, where SORT_TYPE
can either be time
or salary
, and SORT_ORDER
can either be a
or d
.
How it is implemented
The sort
command is facilitated by the SortCommand
, SortSalaryCommand
, SortTimeCommand
, and SortCommandParser
.
It enables users to sort the list of internship applications either by salary or by time and by ascending or descending
order.
Given below is how the sort mechanism behaves at each step.
Parsing User input
- The user inputs the
sort
command. - The
InTrackParser
processes the input and creates a newSortCommandParser
. - The
SortCommandParser
then checks the validity ofSORT_TYPE
. IfSORT_TYPE
is invalid or absent, aParseException
would be thrown. - The
SortCommandParser
then creates eitherSortTimeCommand
orSortSalaryCommand
based on the processed input.
Command execution
Sort by salary:
- The
LogicManager
executes theSortSalaryCommand
. - The
SortSalaryCommand
checks if theSORT_ORDER
isa
ord
. - If the
SORT_ORDER
isa
, thenModel#ascendSortSalary()
is called. If theSORT_ORDER
isd
, thenModel#descendSortSalary()
is called.
Sort by time:
- The
LogicManager
executes theSortTimeCommand
. - The
SortTimeCommand
checks if theSORT_ORDER
isa
ord
. - If the
SORT_ORDER
isa
, thenModel#ascendSortTime()
is called. If theSORT_ORDER
isd
, thenModel#descendSortTime()
is called.
The following sequence diagram shows how the sort
command works:
The following activity diagram shows what happens when a user executes a sort
command:
[Proposed] Undo/redo feature
Proposed Implementation
The proposed undo/redo mechanism is facilitated by VersionedInTrack
. It extends InTrack
with an undo/redo history, stored internally as an inTrackStateList
and currentStatePointer
. Additionally, it implements the following operations:
-
VersionedInTrack#commit()
— Saves the current internship tracker state in its history. -
VersionedInTrack#undo()
— Restores the previous internship tracker state from its history. -
VersionedInTrack#redo()
— Restores a previously undone internship tracker state from its history.
These operations are exposed in the Model
interface as Model#commitInTrack()
, Model#undoInTrack()
and Model#redoInTrack()
respectively.
Given below is an example usage scenario and how the undo/redo mechanism behaves at each step.
Step 1. The user launches the application for the first time. The VersionedInTrack
will be initialized with the initial internship tracker state, and the currentStatePointer
pointing to that single internship tracker state.
Step 2. The user executes delete 5
command to delete the 5th internship in the internship tracker. The delete
command calls Model#commitInTrack()
, causing the modified state of the internship tracker after the delete 5
command executes to be saved in the inTrackStateList
, and the currentStatePointer
is shifted to the newly inserted internship tracker state.
Step 3. The user executes add c/Google …
to add a new internship. The add
command also calls Model#commitInTrack()
, causing another modified internship tracker state to be saved into the inTrackStateList
.
Model#commitInTrack()
, so the internship tracker state will not be saved into the inTrackStateList
.
Step 4. The user now decides that adding the internship was a mistake, and decides to undo that action by executing the undo
command. The undo
command will call Model#undoInTrack()
, which will shift the currentStatePointer
once to the left, pointing it to the previous internship tracker state, and restores the internship tracker to that state.
currentStatePointer
is at index 0, pointing to the initial InTrack state, then there are no previous InTrack states to restore. The undo
command uses Model#canUndoInTrack()
to check if this is the case. If so, it will return an error to the user rather
than attempting to perform the undo.
The following sequence diagram shows how the undo operation works:
UndoCommand
should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram.
The redo
command does the opposite — it calls Model#redoInTrack()
, which shifts the currentStatePointer
once to the right, pointing to the previously undone state, and restores the internship tracker to that state.
currentStatePointer
is at index inTrackStateList.size() - 1
, pointing to the latest internship tracker state, then there are no undone InTrack states to restore. The redo
command uses Model#canRedoInTrack()
to check if this is the case. If so, it will return an error to the user rather than attempting to perform the redo.
Step 5. The user then decides to execute the command list
. Commands that do not modify the internship tracker, such as list
, will usually not call Model#commitInTrack()
, Model#undoInTrack()
or Model#redoInTrack()
. Thus, the inTrackStateList
remains unchanged.
Step 6. The user executes clear
, which calls Model#commitInTrack()
. Since the currentStatePointer
is not pointing at the end of the inTrackStateList
, all internship tracker states after the currentStatePointer
will be purged. Reason: It no longer makes sense to redo the add c/Google …
command. This is the behavior that most modern desktop applications follow.
The following activity diagram summarizes what happens when a user executes a new command:
Design considerations:
Aspect: How undo & redo executes:
-
Alternative 1 (current choice): Saves the entire internship tracker.
- Pros: Easy to implement.
- Cons: May have performance issues in terms of memory usage.
-
Alternative 2: Individual command knows how to undo/redo by
itself.
- Pros: Will use less memory (e.g. for
delete
, just save the internship being deleted). - Cons: We must ensure that the implementation of each individual command are correct.
- Pros: Will use less memory (e.g. for
Documentation, logging, testing, configuration, dev-ops
Appendix: Requirements
Product scope
Target user profile:
- has a need to manage a significant number of internship applications
- prefers desktop apps over other types
- can type fast
- prefers typing to mouse interactions
- is reasonably comfortable using CLI apps
Value proposition:
- Manage internship applications faster than a typical mouse/GUI driven app
- Manage multiple internships and provide comparisons between them for better decision-making
- Easily customizable and personalizable to manage internships applications
- Easy viewing for deadlines
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 | learn how to use the App |
* * * |
user | view a list of current internship applications | - |
* * * |
user | add a new internship application | - |
* * * |
user | delete an internship application | remove entries that I no longer need |
* * * |
forgetful user | obtain the information of the company | contact them if I have any queries |
* * * |
organized user | color code tags for different interviews and statuses | sort and prioritize my interview data |
* * * |
user applying to many internships | search for a specific company via keywords | easily find the information I am looking for |
* * * |
user applying to many internships | make my own tags | sort my applications better |
* * * |
user applying to internships progressively | edit individual application information at any time | make sure the information stays relevant |
* * * |
frequent user | the commands to be simple and memorable | access my information quickly and easily |
* * |
user | mark internship applications as completed | clearly see my progress |
* * |
user | view internship periods of different companies | more informed about my applications |
* * |
new user | purge all current data | get rid of experimental data I used for exploring the app |
* * |
user applying to many internships | sort application deadlines by time and priority | take note of upcoming deadlines |
* * |
user applying to many internships | record down the dates of the interviews | avoid interview clashes |
* * |
user who just started his interviews | record my mistakes made during interviews | reflect on t hem |
* * |
user applying to many internships | receive reminders about upcoming interviews and deadlines | not miss any important dates |
* * |
user applying to technical internships | view different stages of my interview such as HR and technical stages | see what phase of the interviews I am at |
* * |
user applying to technical internships | filter through my internships by job role | to keep track of the roles I have applied for |
* * |
user applying to many internships | prioritize the companies I am keen on | compare the options I have |
* * |
frequent user | compare internship statistics such as internship lengths | make a more informed choice |
* |
potential user | see the app populated with sample data | see what the app is like while it is in use |
* |
user | unmark completed internship applications | clearly see my progress |
* |
user applying to many internships | sort the salaries of each company | compare the options I have |
* |
user applying to many internships | archive the interviews I have been rejected from | avoid cluttering the app with data and also refer to them later on |
* |
frequent user | search for applications through case sensitive searching | find and sort my internships more easily |
* |
frequent user | have a customizable GUI | have more visible information on my applications |
* |
frequent user | send feedback to the developers of the application | make them optimize the app more |
Use cases
(For all use cases below, the System is the InTrack
and the Actor is the user
, unless specified otherwise)
Use case: UC01 - View usage instructions
MSS
-
User requests to view usage instructions.
-
InTrack displays the usage instructions.
Use case ends.
Use case: UC02 - View all internship applications
MSS
-
User requests to list all internship applications.
-
InTrack displays a list of all internship applications.
Use case ends.
Use case: UC03 - Add a new internship application
MSS
-
User requests to add a new internship application to the list.
-
InTrack adds the new internship application.
Use case ends.
Extensions
-
1a. The given command has an invalid format.
-
1a1. InTrack shows an error message.
Use case ends.
-
-
1b. The given internship application already exists in InTrack.
-
1b1. InTrack shows an error message.
Use case ends.
-
Use case: UC04 - Delete an internship application
MSS
-
User views list of internship applications (UC02).
-
User requests to delete a specific internship application in the list.
-
InTrack deletes the internship application.
Use case ends.
Extensions
-
2a. The given index is invalid.
-
2a1. InTrack shows an error message.
Use case resumes at step 2.
-
Use case: UC05 - Update the status of an internship application
MSS
-
User views list of internship applications (UC02).
-
User requests to update the status of a specific internship application in the list.
-
InTrack updates the status of the internship application.
Use case ends.
Extensions
-
2a. The given index is invalid.
-
2a1. InTrack shows an error message.
Use case resumes at step 2.
-
-
2b. The given status is invalid.
-
2b1. InTrack shows an error message.
Use case resumes at step 2.
-
Use case: UC06 - Add a tag to an internship application
MSS
-
User views list of internship applications (UC02).
-
User requests to add a tag to a specific internship application in the list.
-
InTrack adds the tag to the internship application.
Use case ends.
Extensions
-
2a. The given index is invalid.
-
2a1. InTrack shows an error message.
Use case resumes at step 2.
-
-
2b. The given tag is invalid.
-
2b1. InTrack shows an error message.
Use case resumes at step 2.
-
-
2c. The given tag already exists in the internship application.
-
2c1. InTrack shows an error message.
Use case resumes at step 2.
-
Use case: UC07 - Delete a tag from an internship application
MSS
-
User views list of internship applications (UC02).
-
User requests to delete a tag from a specific internship application in the list.
-
InTrack deletes the tag from the internship application.
Use case ends.
Extensions
-
2a. The given index is invalid.
-
2a1. InTrack shows an error message.
Use case resumes at step 2.
-
-
2b. The given tag is invalid.
-
2b1. InTrack shows an error message.
Use case resumes at step 2.
-
-
2c. The given tag does not exist in the internship application.
-
2c1. InTrack shows an error message.
Use case resumes at step 2.
-
Use case: UC08 - Select an internship application
MSS
-
User views list of current internship applications (UC02).
-
User requests to select a specific internship application in the list.
-
InTrack selects the internship application and displays its full details.
Use case ends.
Extensions
-
2a. The given index is invalid.
-
2a1. InTrack shows an error message.
Use case resumes at step 2.
-
Use case: UC09 - Edit an internship application
MSS
-
User selects an internship application (UC08).
-
User requests to edit the selected internship application.
-
InTrack edits the selected internship application.
Use case ends.
Extensions
-
2a. The given command has an invalid format.
-
2a1. InTrack shows an error message.
Use case resumes at step 2.
-
-
2b. The edited internship application already exists in InTrack.
-
2b1. InTrack shows an error message.
Use case resumes at step 2.
-
Use case: UC10 - Add a task to an internship application
MSS
-
User selects an internship application (UC08).
-
User requests to add a task to the selected internship application.
-
InTrack adds the task to the selected internship application.
Use case ends.
Extensions
-
2a. The given command has an invalid format.
-
2a1. InTrack shows an error message.
Use case resumes at step 2.
-
Use case: UC11 - Delete a task from an internship application
MSS
-
User selects an internship application (UC08).
-
User requests to delete a task from the selected internship application.
-
InTrack deletes the task from the selected internship application.
Use case ends.
Extensions
-
2a. The given task index is invalid.
-
2a1. InTrack shows an error message.
Use case resumes at step 2.
-
Use case: UC12 - Add a remark to an internship application
MSS
-
User selects an internship application (UC08).
-
User requests to add a remark to the selected internship application.
-
InTrack adds the remark to the selected internship application.
Use case ends.
Extensions
-
2a. The given command has an invalid format.
-
2a1. InTrack shows an error message.
Use case resumes at step 2.
-
Use case: UC13 - Clear all internship applications
MSS
-
User requests to clear all internship applications.
-
InTrack clears all internship applications.
Use case ends.
Use case: UC14 - Find internship applications
MSS
-
User requests to find internship applications.
-
InTrack finds and displays the internship applications that match the given input parameters.
Use case ends.
Use case: UC15 - Filter internship applications by status
MSS
-
User requests to filter internship applications by status.
-
InTrack filters and displays the internship applications with the given status.
Use case ends.
Extensions
-
1a. The given status is invalid.
-
1a1. InTrack shows an error message.
Use case ends.
-
Use case: UC16 - Sort internship applications
MSS
-
User requests to sort internship applications.
-
InTrack sorts the internship applications via the given parameter in the given order.
Use case ends.
Extensions
-
1a. The given parameter is invalid.
-
1a1. InTrack shows an error message.
Use case ends.
-
-
1b. The given order is invalid.
-
1b1. InTrack shows an error message.
Use case ends.
-
Use case: UC17 - View statistics of internship applications
MSS
-
User views list of internship applications (UC02).
-
User requests to view statistics of internship applications.
-
InTrack displays the statistics of the list of internship applications.
Use case ends.
Use case: UC18 - Sending an email
MSS
-
User selects an internship application (UC08).
-
User requests to email the email address associated with the selected internship application.
-
Default mail app is launched with the target recipient being the email address fo the selected internship application.
Use case ends.
Non-Functional Requirements
- Should work on any mainstream OS as long as it has Java
11
or above installed. - Should be able to hold up to 1000 internship applications without a noticeable sluggishness in performance for typical usage.
- 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.
- Data should be stored consistently even after closing and reopening the app.
- System should be usable by a Computing student who has never applied to an internship before.
- System should be easily usable by the majority of Year 2+ Computing students.
- The application is not required to support any other language other than English.
- The application is not required to support multiple users on a single device.
- The response to any commands carried out by the user should become visible within 5 seconds.
- The user is not required to install Gradle/JavaFX for the application to function.
- The user is not required to have an internet connection in order for the application to function.
Glossary
Term | Explanation |
---|---|
Mainstream OS | Windows, Linux, Unix, OS-X |
Graphical User Interface (GUI) | An interface for the user to interact with the system via graphical icons and audio |
Command Line Interface (CLI) | An interface for the user to input commands to interact with the system |
Tag | An optional one-word identifier of a internship application. An internship application can have multiple tags. |
Status | The status of the internship application, must be either Offered , Rejected or Progress
|
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 internships. 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.
-
Display help
Command: help
More information on usage: help command
- Test case:
help
Expected: Help window with list of commands is displayed
Listing all internships
Command: list
More information on usage: list command
- Test case:
list
Expected: Shows a list of all internship applications in InTrack.
Viewing statistics
Command: stats
More information on usage: stats command
- Test case:
stats
Expected: Statistics of the current list of internship applications are displayed, showing the number of offered, in progress and rejected applications.
Exiting application
Command: exit
More information on usage: exit command
- Test case:
exit
Expected: Exits InTrack and all data is saved.
Adding an internship
Command: add
More information on usage: add command
-
Adding an internship application while all internship applications are being shown.
-
Prerequisites: List all internship applications using the
list
command. -
Test case:
add c/Google p/SWE e/hr@google.com w/https://careers.google.com/ s/5000 t/Urgent
Expected: An internship application with the companyGoogle
and the following attributes are added to the internship applications list. The new internship is added to the last index of the internship list. The new internship application card appeared at the bottom of the list. The details of the newly added internship is shown in the success message. -
Test case:
add c/Google p/Data Analyst e/hr@google.com w/https://careers.google.com/ s/5000 t/Urgent
Expected: An internship application with the companyGoogle
with the following attributes are added to the internship applications list. Note that theCOMPANY
of this internship is that same as the test case above. However, the new internship’sPOSIITON
is different. The new internship is added to the last index of the internship list. The new internship application card appeared at the bottom of the list. The details of the newly added internship is shown in the success message. -
Test case:
add c/Google
Expected: No internship application added. Error details shown in error message. -
Other incorrect add commands to try:
add
,add c/Google p/Data Analyst
Expected: Similar to previous.
-
Deleting an internship
Command: delete
More information on usage: delete command
-
Deleting an internship while all internships are being shown
-
Prerequisites: List all internships using the
list
command. Multiple internships in the list. -
Test case:
delete 1
Expected: First internship is deleted from the list. Details of the deleted internship is shown in the success message. -
Test case:
delete 0
Expected: No internship is deleted. Error details shown in the error message. -
Other incorrect delete commands to try:
delete
,delete x
(where x is larger than the list size)
Expected: Similar to previous.
-
-
Deleting an internship while internships are being filtered.
-
Prerequisites: Filter the internship list using either
findc
,findp
orfindt
command. Multiple internships in the list. -
Test case: Similar to previous
Expected: Similar to previous
-
Updating status of an internship
Command: status
More information on usage: status command
-
Updating status of an internship while all internships are shown.
-
Prerequisites: List all internships using the
list
command. Multiple internships in the list. -
Test case:
status 1 o
Expected: First internship’s status is set toOffered
which is displayed as green on the internship card. -
Test case:
status 0 o
Expected: No internship status is changed. Error details shown in the error message. -
Other incorrect status commands to try:
status 1 j
,status x o
(where x is larger than the list size)
Expected: Similar to previous.
-
-
Updating status of an internship while internships are being filtered.
-
Prerequisites: Filter the internship list using either
findc
,findp
orfindt
command. Multiple internships in the list. -
Test case: Similar to previous
Expected: Similar to previous
-
Adding tags to an internship
Command: addtag
More information on usage: addtag command
-
Adding tags to an internship while all internships are shown.
-
Prerequisites: List all internships using the
list
command. Multiple internships in the list. The first internship in the list has only theUrgent
tag (case-sensitive). -
Test case:
addtag 1 Remote
Expected:Remote
tag is added to the first internship. -
Test case:
addtag 1 Urgent Remote
Expected:Remote
tag is added to the first internship. -
Test case:
addtag 1 Important Remote
Expected:Important
andRemote
tags are both added to the first internship. -
Test case:
addtag 1 Urgent
Expected: No tags are added to any internship. Success message is shown. -
Test case:
addtag 0 Urgent
Expected: No tags are added to any internship. Error details shown in the error message. -
Other incorrect addtag commands to try:
addtag 1
,addtag x Urgent
(where x is larger than the list size)
Expected: Similar to previous.
-
-
Adding tags to an internship while internships are being filtered.
-
Prerequisites: Filter the internship list using either
findc
,findp
orfindt
command. Multiple internships in the list. The first internship in the list has only theUrgent
tag (case-sensitive). -
Test case: Similar to previous
Expected: Similar to previous
-
Deleting tags from an internship
Command: deltag
More information on usage: deltag command
-
Deleting tags from an internship while all internships are shown.
-
Prerequisites: List all internships using the
list
command. Multiple internships in the list. The first internship in the list has only theUrgent
tag (case-sensitive). -
Test case:
deltag 1 Urgent
Expected: TheUrgent
tag is deleted from the first internship in the list. -
Test case:
deltag 1 Urgent Remote
Expected: No tags are deleted from any internship. Error details shown in error message. -
Test case:
deltag 0 Urgent
Expected: No tags are deleted from any internship. Error details shown in error message. -
Other incorrect status commands to try:
deltag 1
,deltag x Urgent
(where x is larger than the list size)
Expected: Similar to previous.
-
-
Deleting tags from an internship while internships are being filtered.
-
Prerequisites: Filter the internship list using either
findc
,findp
orfindt
command. Multiple internships in the list. The first internship in the list has only theUrgent
tag (case-sensitive). -
Test case: Similar to previous
Expected: Similar to previous
-
Selecting an internship
Command: select
More information on usage: select command
-
Selecting an internship while all internships are shown.
-
Prerequisites: List all internships using the
list
command. Multiple internships in the list. -
Test case:
select 1
Expected: The first internship is selected and its details are shown on the right panel. -
Test case:
select 0
Expected: No internship is selected. Error details shown in error message. -
Other incorrect select commands to try:
select
,select x
(where x is larger than the list size)
Expected: Similar to previous.
-
-
Selecting an internship while internships are being filtered.
-
Prerequisites: Filter the internship list using either
findc
,findp
orfindt
command. Multiple internships in the list. -
Test case: Similar to previous
Expected: Similar to previous
-
Editing an internship
Command: edit
More information on usage: edit command
-
Editing a selected internship.
-
Prerequisites: An internship application is selected using the
select
command and displayed on the right panel. The selected internship hasPOSITION
asSoftware Engineer
and has onlyUrgent
tag. -
Test case:
edit p/Data Analyst
Expected: ThePOSITION
field of the selected internship is set toData Analyst
-
Test case:
edit p/Data Analyst t/Remote
Expected: ThePOSITION
field of the selected internship is set toData Analyst
and the selected internship only contains theRemote
tag. -
Test case:
edit q/invalid prefix
Expected: No internship is edited. Error details shown in error message. -
Other incorrect edit commands to try:
edit
Expected: Similar to previous.
-
-
Editing without any internship selected
-
Prerequisites: No internship is selected and shown on the right panel.
-
Test case:
edit p/Data Analyst
Expected: No internship is edited. Error details shown in error message.
-
Adding a task to an internship
Command: addtask
More information on usage: addtask command
-
Adding a task to a selected internship.
-
Prerequisites: An internship application is selected using the
select
command and displayed on the right panel. -
Test case:
addtask Technical Interview /at 12-01-2023 15:00
Expected:Technical Interview
task is added to the task list of the selected internship, added in chronological order with the specified time. -
Test case:
addtask Technical Interview /at 31-02-2023 12:00
Expected: No task is added to the selected internship. Error details shown in error message -
Other incorrect edit commands to try:
addtask
,addtask Technical Interview
Expected: Similar to previous.
-
-
Adding a task without any internship selected
-
Prerequisites: No internship is selected and shown on the right panel.
-
Test case:
addtask Technical Interview /at 12-01-2023 15:00
Expected: No task is added to any internship. Error details shown in error message.
-
Deleting a task from an internship
Command: deltask
More information on usage: deltask command
-
Deleting a task from a selected internship.
-
Prerequisites: An internship application is selected using the
select
command and displayed on the right panel. The selected internship contains at least one task. -
Test case:
deltask 1
Expected: The first task on the task list of the selected internship is deleted. -
Test case:
deltask 0
Expected: No task is deleted from the selected internship. Error details shown in error message -
Other incorrect edit commands to try:
deltask
,deltask x
(where x is larger than the task list size)
Expected: Similar to previous.
-
-
Deleting a task without any internship selected
-
Prerequisites: No internship is selected and shown on the right panel.
-
Test case:
deltask 1
Expected: No task is deleted from any internship. Error details shown in error message.
-
Adding a remark to an internship
Command: remark
More information on usage: remark command
-
Adding a remark to a selected internship.
-
Prerequisites: An internship application is selected using the
select
command and displayed on the right panel. -
Test case:
remark r/Read up beforehand
Expected: The remarkRead up beforehand
is added to the remark field of the selected internship. -
Test case:
remark
Expected: No remark is added to the selected internship. Error details shown in error message
-
-
Adding a remark without any internship selected
-
Prerequisites: No internship is selected and shown on the right panel.
-
Test case:
remark r/Read up beforehand
Expected: No remark is added to any internship. Error details shown in error message.
-
Sending an email
Command: mail
More information on usage: mail command
-
Sending an email to the email of the selected internship
-
Prerequisites: An internship application is selected using the
select
command and displayed on the right panel. -
Test case:
mail
Expected: The default mail app is launched with the email of the selected internship in the recipient field.
-
-
Sending an email without any internship selected
-
Prerequisites: No internship is selected and shown on the right panel.
-
Test case:
mail
Expected: No mail app is launched. Error details shown in error message.
-
Clearing data
Command: clear
More information on usage: clear command
- Test case:
clear
Expected: All data is cleared from InTrack.
Filtering internships by company name
Command: findc
More information on usage: findc command
-
Filtering internships by company name while all internships are being shown.
-
Prerequisites: List all internships using the
list
command. Multiple internships in the list. -
Test case:
findc Microsoft
Expected: All internship applications withMicrosoft
(case-insensitive) in the company name are shown. -
Test case:
findc Microsoft Amazon
Expected: All internship applications withMicrosoft
orAmazon
(case-insensitive) in the company name are shown. -
Test case:
findc
Expected: Internship list is not filtered. Error details shown in error message.
-
-
Filtering internships by company name while internships are being filtered.
-
Prerequisites: Filter the internship list using either
findc
,findp
orfindt
command. Multiple internships in the list. -
Test case: Similar to previous.
Expected: Similar to previous. Filters do not stack on one another.
-
Filtering internships by position name
Command: findp
More information on usage: findp command
-
Filtering internships by position name while all internships are being shown.
-
Prerequisites: List all internships using the
list
command. Multiple internships in the list. -
Test case:
findp SWE
Expected: All internship applications withSWE
(case-insensitive) in the position name are shown. -
Test case:
findp Frontend Backend
Expected: All internship applications withFrontend
orBackend
(case-insensitive) in the position name are shown. -
Test case:
findp
Expected: Internship list is not filtered. Error details shown in error message.
-
-
Filtering internships by position name while internships are being filtered.
-
Prerequisites: Filter the internship list using either
findc
,findp
orfindt
command. Multiple internships in the list. -
Test case: Similar to previous.
Expected: Similar to previous. Filters do not stack on one another.
-
Filtering internships by tags
Command: findt
More information on usage: findt command
-
Filtering internships by tags while all internships are being shown.
-
Prerequisites: List all internships using the
list
command. Multiple internships in the list. -
Test case:
findt Urgent
Expected: All internship applications withUrgent
(case-sensitive) tag are shown. -
Test case:
findt Urgent Remote
Expected: All internship applications with eitherUrgent
orRemote
(case-sensitive) tag or both are shown. -
Test case:
findt
Expected: Internship list is not filtered. Error details shown in error message.
-
-
Filtering internships by tags while internships are being filtered.
-
Prerequisites: Filter the internship list using either
findc
,findp
orfindt
command. Multiple internships in the list. -
Test case: Similar to previous.
Expected: Similar to previous. Filters do not stack on one another.
-
Filtering internships by status
Command: filter
More information on usage: filter command
-
Filtering internships by status while all internships are being shown.
-
Prerequisites: List all internships using the
list
command. Multiple internships in the list. -
Test case:
filter o
Expected: All internship applications withOffered
status are shown. -
Test case:
filter s
Expected: Internship list is not filtered. Error details shown in error message.
-
-
Filtering internships by status while internships are being filtered.
-
Prerequisites: Filter the internship list using either
findc
,findp
orfindt
command. Multiple internships in the list. -
Test case: Similar to previous.
Expected: Similar to previous. Filters do not stack on one another.
-
Sorting internships
Command: sort
More information on usage: sort command
-
Sorting internships while all internships are being shown.
-
Prerequisites: List all internships using the
list
command. Multiple internships in the list. -
Test case:
sort time a
Expected: The currently displayed internships are sorted in ascending manner by upcoming tasks, with the internship with the task with the earliest date and time that is after the current date and time at the top. -
Test case:
sort salary a
Expected: The currently displayed internships are sorted in ascending manner by salary, with the internship with the lowest salary at the top. -
Test case:
sort salary j
Expected: Internship list is not sorted. Error details shown in error message.
-
-
Sorting internships while internships are being filtered.
-
Prerequisites: Filter the internship list using either
findc
,findp
orfindt
command. Multiple internships in the list. -
Test case: Similar to previous.
Expected: Similar to previous.
-
Saving data
-
Dealing with missing/corrupted data files
-
Open
InTrack.jar
and make any changes to the internship list with the commands provided, being sure to leave at least one internship in the list. -
Edit the
data/intrack.json
file by making any one of the following changes before saving the file and reopeningInTrack.jar
.-
Test case: Edit the salary field of the first internship to
invalid
. Expected: InTrack starts with an empty internship list. -
Test case: Edit the status field of the first internship to
invalid
. Expected: Similar to previous. -
Test case: Edit the email field of the first internship to
invalid
. Expected: Similar to previous.
-
-
-
Dealing with missing files.
-
Test case: Exit InTrack, then delete the
data/intrack.json
file. Reopen InTrack. Expected: All internships are deleted. InTrack will start as expected with sample data provided. -
Test case: Exit InTrack, then delete the
config.json
file. Reopen InTrack. Expected: InTrack starts as expected, with either the sample data provided or any previously saved data, if present. The size of the window should be the same as the previously saved user preference. -
Test case: Exit InTrack, then delete
preferences.json
. Reopen InTrack. Expected: The previous user preferences such as the size of the window will be deleted. InTrack starts with default settings.
-