By F14-1, JAYME
Refer to the guide Setting up and getting started for initial setup and basic instructions.
The Architecture Diagram given above explains the high-level design of the App.
Given below is a quick overview of main components and how they interact with each other.
Main components of the architecture
Main
(consisting of classes Main
and MainApp
) is in charge of the app launch and shut down.
The bulk of the app's work is done by the following four components:
UI
: Manages the user interface 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.Commons
represents a collection of classes used by multiple other components.
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),
interface
with the same name as the Component.{Component Name}Manager
class (which 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 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.
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
, PersonListPanel
, 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,
Logic
component.Model
data so that the UI can be updated with the modified data.Logic
component, because the UI
relies on the Logic
to execute commands.Model
component, as it displays Person
object residing in the Model
.API : Logic.java
Here's a (partial) class diagram of the Logic
component:
The sequence diagram below illustrates the interactions within the Logic
component, taking execute("delete 1")
API call as an example.
Note: The lifeline for DeleteCommandParser
should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline continues till the end of diagram.
How the Logic
component works:
Logic
is called upon to execute a command, it is passed to an InternHubParser
object which in turn creates a parser that matches the command (e.g., DeleteCommandParser
) and uses it to parse the command.Command
object (more precisely, an object of one of its subclasses e.g., DeleteCommand
) which is executed by the LogicManager
.Model
when it is executed (e.g. to delete a person).Model
) to achieve.CommandResult
object which is returned back from Logic
.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:
InternHubParser
class creates an XYZCommandParser
(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 a XYZCommand
object (e.g., AddCommand
) which the InternHubParser
returns back as a Command
object.XYZCommandParser
classes (e.g., AddCommandParser
, DeleteCommandParser
, ...) inherit from the Parser
interface so that they can be treated similarly where possible e.g, during testing.API : Model.java
The Model
component,
Person
objects (which are contained in a UniquePersonList
object).Person
objects (e.g., results of a search query) as a separate filtered list which is exposed to outsiders as an unmodifiable ObservableList<Person>
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.UserPref
object that represents the user’s preferences. This is exposed to the outside as a ReadOnlyUserPref
objects.Model
represents data entities of the domain, they should make sense on their own without depending on other components)API : Storage.java
The Storage
component,
AddressBookStorage
and UserPrefStorage
, which means it can be treated as either one (if only the functionality of only one is needed).Model
component (because the Storage
component's job is to save/retrieve objects that belong to the Model
)Classes used by multiple components are in the seedu.internhub.commons
package. The three over-arching sub-packages are core
, exceptions
, and util
.
core
: This package defines classes for user configuration, GUI settings, and even a version number.
exceptions
: This package defines exceptions thrown by InternHub when it encounters an error state.
util
: This package defines utility classes for certain operations, like file I/O, argument validation, and image processing.
This section describes some noteworthy details on how certain features are implemented.
Format: add c/COMPANY_NAME p/PHONE_NUMBER e/EMAIL [a/ADDRESS] t/TAG jd/JOB_DESCRIPTION [d/INTERVIEW_DATE] id/INTERN_DURATION s/SALARY [n/NOTE]
Parameters in []
are optional.
This command adds an internship application into the InternHub using the company name, phone number, email, address, tag, job description, interview date, intern duration, salary and note.
The following steps show how the add internship application feature works:
add
command followed by internship application details, the AddCommandParser
is invoked to parse this input.AddCommand
is instantiated with the Person object.CommandResult
with the following params:
New internship application added: [newly added internship application details]
.Alternative 1 (current choice): Creates a new Person object in AddCommandParser.
Pros: Simpler to test and understand.
Cons: Command object should not know details about model i.e. Person.
Alternative 2: New Person object is created and added to InternHub in model.
Pros: Command has no knowledge of Model and its attributes.
Cons: More prone to error.
The diagram below shows the class diagram for AddCommand.
The diagram below shows the sequence diagram for AddCommand. All Initialization commands above are similar in their interactions with the logic component and model component.
The following activity diagram shows how the user can interact with the Add Command.
Format: edit INDEX [c/COMPANY_NAME] [p/PHONE_NUMBER] [e/EMAIL] [t/TAG] [jd/JOB_DESCRIPTION] [id/INTERN_DURATION] [s/SALARY] [a/ADDRESS] [d/INTERVIEW_DATE] [n/NOTE]
INDEX
is a positive integer representing the index of the application in the applications list.The EditCommand
allows users to modify the details of an existing internship application, based on their table index
.
EditPersonDescriptor
object is created to store the edited details.EditPersonDescriptor
.EditCommand
is executed, modifying the specified internship application's details.The diagram below shows the class diagram for EditCommand.
The diagram below shows the sequence diagram for EditCommand.
The following activity diagram shows how the user can interact with the Edit Command.
Format: view INDEX
INDEX
is a positive integer representing the index of the application in the applications list.
The View Command allows users to view the internship application based on its index in the view panel
The following steps outline how the View Command feature operates :
view
command followed by an index
, the ViewCommandParser
is invoked to parse this inputViewCommand
is instantiated with the parsed index.ViewCommand#execute(Model model)
is then called, passing the current application modelexecute
method, the validity of the index entered is checked. This involves ensuring the index falls within the current range of the internship application listCommandException
is thrown with an error messageViewCommand
constructs a new CommandResult
with the following param :
Current internship application
ViewPanel
class displays the personToView with all its details and fieldsPerson
object based on the indexCommandResult
to pass the Person
object to the UI componentThe following sequence diagram shows what happens when view 3
is the command input.
The following activity diagram shows what the logic behind the command view 3
.
Format: note INDEX
INDEX
is a positive integer representing the index of the application in the applications list.
The Note Command feature allows users to retrieve the note attribute of an internship application based on its index and reflects it in the Command Box as an edit command, enabling users to make changes to the note seamlessly.
The following steps outline how the Note Command feature operates:
note
command followed by an index
, the NoteCommandParser
is invoked to parse this input.NoteCommand
is instantiated with the parsed index.NoteCommand#execute(Model model)
is then called, passing the current application model.execute
method, the validity of the index entered is checked. This involves ensuring the index falls within the current range of the internship application list.CommandException
is thrown with an error message.NoteCommand
retrieves the filtered list of applications (List<Person>
) from the model.NoteCommand
constructs a new CommandResult
with the following params :
edit [INDEX of application] n/{existing note}
Current internship application
CommandBox#handleCommandEntered()
, if the feedbackToUser
of the CommandResult object starts with edit
(ie our note Command Result), we set the text of the command box to be the feedbackToUser
Alternative 1 : Use edit to make changes to note attribute
note
commandThe diagram below shows the class diagram for NoteCommand.
The diagram below shows the sequence diagram for NoteCommand.
The following activity diagram shows how the user can interact with the Note Command.
Format: filter VALID_TAG
Valid Tag Inputs
The Filter Command allows users to filter the current list of applications by a specified tag, such that only applications with said tag will be displayed in the applications list.
The following steps outline how the Filter Command feature operates:
filter
command followed by a tag
, the FilterCommandParser
is invoked to parse this inputMatchingTagPredicate
is instantiated with the parsed tag StringFilteredPersonList
representing the list of applications is then updated with the new MatchingTagPredicate
which checks if the tag
field of each list entry matches the specified tag
FilterCommand
is instantiated with the number of entries in the updated FilteredPersonList
.FilterCommand#execute(Model model)
is then called, passing the current application modelFilterCommand
constructs a new CommandResult
with the following parameters :
[size of filtered list] persons listed
ObservableList
to filter the list of contacts using MatchingTagPredicate
generated from user inputCommandResult
to pass the resulting FilteredPersonList
to the UI componentThe diagram below shows the class diagram for FilterCommand.
The diagram below shows the sequence diagram for FilterCommand.
The following activity diagram shows how the user can interact with the FilterCommand
Format: reminder INT
The ReminderCommand
allows users to filter the list of internship applications to display only those with interviews scheduled within the next 'N' days, including today.
The following steps outline how the Reminder Command feature operates:
reminder
command followed by a number of days, the ReminderCommandParser
is invoked to parse this input.ReminderCommand
is instantiated with the parsed number of days.ReminderCommand#execute(Model model)
is then called, passing the current application model.execute
method, the ReminderCommand
filters the list of internship applications (List<Person>
) from the model to include only those with upcoming interviews within the specified number of days.ReminderCommand
constructs a new CommandResult
with the following parameters:
CommandResult
is displayed to the user, showing the filtered list of applications with upcoming interviews within the specified number of days.Alternative 1 (Current Implementation): Create reminder
command
Alternative 2: Integrated Feature
reminder
command with existing filter
commandChosen Approach: Alternative 1
reminder
command to maintain clarity and flexibility in filtering applications based on upcoming interviews.The diagram below shows the class diagram for ReminderCommand.
The diagram below shows the sequence diagram for ReminderCommand.
The following activity diagram shows how the user can interact with the ReminderCommand.
Target user profile:
Value proposition: Ultimate companion for Undergraduate students embarking on their internship journey!
Priorities: High (must have) - * * *
, Medium (nice to have) - * *
, Low (unlikely to have) - *
Priority | As an … | I want to … | So that I can… |
---|---|---|---|
* * * | internship applicant | add contact information of internship companies | easily access their details when needed |
* * * | internship applicant | delete contact information of internship companies | easily remove any old or irrelevant company contacts |
* * * | internship applicant | edit contact information of internship companies | easily update any details on the go |
* * * | internship applicant | see usage instructions | refer to instructions when I forget how to use the AddressBook |
* * * | internship applicant | find the contact information of a certain company | easily search which company contact I want by name |
* * * | internship applicant | keep track of the status of each internship application | categorize and easily follow up accordingly |
* * * | internship applicant | sort company contacts by dates | prioritize and plan for upcoming interviews |
* * | internship applicant | filter company contacts by date | quickly access contacts associated with a specific date |
* * | internship applicant | filter company contacts by tag | easily find and manage contacts within specific categories |
* * | internship applicant | add a time to a company contact | record when a specific task or interaction needs to be done |
* | internship applicant | add notes to company contacts | include important details or information about specific interviews and what I can learn from them |
(For all use cases below, the System is the InternHub
and the User is the InternHub User
, unless specified otherwise)
Main Success Scenario (MSS):
Extensions:
1a. System detects an error in the entered command syntax.
1b. System detects an error in the fields being added (No fields at all / Invalid field prefixes / Duplicate prefixes).
Main Success Scenario (MSS):
Extensions:
1a. System detects an error in index of application.
Main Success Scenario (MSS):
Extensions:
1a. System detects an error in the index of the application.
1b. User enters edit without index or without specifying the field scenario.
Main Success Scenario (MSS):
Extensions:
Main Success Scenario (MSS):
Extensions:
Main Success Scenario (MSS):
Extensions:
Main Success Scenario (MSS):
Extensions:
1. Availability: - The application should be available for download on the project's GitHub release page in the form of a JAR file.
2. Capacity: - The application should be capable of storing up to 1000 internship applications.
3. Performance: - Response time to any user command should be within 3 seconds. - The application should be able to handle up to 300 internship applications before facing any performance bottleneck issues.
4. Reliability: - The application should provide guidance to the user if it is unable to execute any user actions for various reasons.
5. Compatibility: - The application should work as intended on any mainstream operating system. - It is guaranteed to work on Java version 11.
6. Usability: - A user with above-average typing speed for regular English text should be able to accomplish most tasks faster using commands than using the mouse.
7. Robustness: - The application should remain highly relevant to internship applications at any point in the future.
8. Integrity: - There should be user updates to the internship applications to ensure integrity. - Application updates should not compromise the integrity of the save file.
9. Maintainability: - The application should comply with the coding standards set forth by CS2103T. - It should adhere to best coding practices highlighted in CS2103T. - The design should allow any programmer with at least a year of experience to read, maintain, and contribute to the source code easily.
10. Process: - The project features should align with any changes to real-world internship application processes.
11. Project Scope: - The application requires manual addition of internship applications into the system.
12. Privacy: - The application should not store any information about users' internship applications in remote storage.
1. Main components: Main, UI, Logic, Model, Storage, Commons.
2. Architecture Diagram: High-level design overview.
3. UI component: Manages app interface elements.
4. Logic component: Executes user commands.
5. Model component: Stores app data.
6. Storage component: Handles data storage.
7. Common classes: Shared utility classes.
8. Mainstream OS: Windows, Linux, Unix, MacOS.
9. CLI: Command Line Interface for user interaction.
Team size: 5
Handling of invalid date to be with accordance of Gregorian Calendar:
29-02-yyyy
where it is not a leap year, it will automatically changes it to the closest valid date, which is 28-02-yyyy
.Case sensitive for company name:
Prevent duplicate phone number:
Make company name less restrictive, allow special characters:
In UI, make the view card scrollable for all labels:
More flexible Filter Command:
address
, salary
, jobDescription
and so on, to allow greater flexibility for the user.filter a/Clementi t/I s/1200
would filter the applications that fit the provided filter-restrictions.Countdown in UI reflecting the number of days until interview date:
Find command based on fields other than name:
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.
Double-click the jar file.
Expected: Shows the GUI with a set of sample contacts. 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.
Using InternHub with Sample Internship Application List
Close InternHub.
Delete the folder data
which contain file ./addressbook.json
(if applicable).
Launch InternHub.
Expected: A sample internship application list with 1 internship applications should be displayed.
Test case: add c/Singapore Airline p/98765432 e/singaporeairline@example.com t/O jd/Animator intern id/3 months s/1000
Expected: A new internship application is added to the list. Details of the added internship application shown in the result display.
Test case: add
Expected: No internship application is added. Error details shown in the result display.
Deleting an internship application while all internship applications are being shown
Prerequisites: At least one internship application displayed.
Test case: delete 1
Expected: First application is deleted from the list. Details of the deleted internship application shown in the result display.
Test case: delete 0
Expected: No application is deleted. Error details shown in the result display.
Other incorrect delete commands to try: delete
, delete x
, ...
(where x is larger than the list size)
Expected: No application is deleted. Error details shown in the result display.
Deleting an internship application in a filtered list of applications
Prerequisites: Filter internship applications using filter I
based on tags. Do note, you can use other valid tags instead of I
as long as you have a populated result list of applications.
Test case: delete 1
Expected: First application based on the filtered list is deleted. Details of deleted internship application shown in result display.
Editing an internship application while all internship applications are being shown
Prerequisites: At least one internship application displayed.
Test case: edit 1 c/shoppa
Expected: The company name of the first internship application is updated to shoppa. Details of the edited internship application shown in the result display.
Test case: edit 0
Expected: No application is edited. Error details shown in the result display.
Other incorrect delete commands to try: edit
, edit x
, ...
(where x is larger than the list size)
Expected: No application is edited. Error details shown in the result display.
Deleting an internship application in a filtered list of applications
Prerequisites: Filter internship applications using filter I
based on tags. Do note, you can use other valid tags instead of I
as long as you have a populated result list of applications.
Test case: delete 1
Expected: First application based on the filtered list is deleted. Details of deleted application shown in result display.
Viewing an internship application with an empty application list
Prerequisites: Clear all applications using clear
command. Will empty the applications.
Test case: view 2
Expected: Error message should be shown in the result display as there are no applications to view.
Viewing an internship application in a populated list
Prerequisites: Ensure at least 1 internship application is in the applications list of InternHub.
Test case: view 1
Expected: The application details at index 1 will be aptly displayed on the view panel on the right.
list
Prerequisites: Starting from an empty list,
add c/Singapore Airline p/98765432 e/singaporeairline@example.com t/O jd/Animator intern id/3 months s/1000
add c/Malaysia Airline p/98765431 e/malaysiaairline@example.com t/NR jd/Data Science intern id/3 months s/1000
add c/shoppa p/98765430 e/shoppa@example.com t/OA jd/Junior Animator intern id/3 months s/1000
Test case: find
Expected: No internship application is displayed on the view panel on the right. Error message should be shown in the result display.
Test case: find airline
Expected: The application details of Singapore Airline and Malaysia Airline will be aptly displayed on the view panel on the right (the company name contain the word airline).
Append to existing note content of internship application
Prerequisites: Attach a test note to the internship application either when you create it or by using edit
.
Test case: note 2
where 2 is the index of that application
Expected: In the command box, you will notice the following: edit 2 n/[existing note content]
, then you can make changes and enter to modify the note.
filter to get internship application(s) with status 'NR' (No Reply) in an empty list
Prerequisites: Clear all applications using clear
command. Will empty the applications.
Test case: filter NR
Expected: Error message should be shown in the result display as there are no applications.
filter to get internship application(s) that has status 'NR' (No Reply) in a populated list
Prerequisites: Starting from an empty list,
add c/Singapore Airline p/98765432 e/singaporeairline@example.com t/O jd/Animator intern id/3 months s/1000
add c/Malaysia Airline p/98765431 e/malaysiaairline@example.com t/NR jd/Data Science intern id/3 months s/1000
add c/shoppa p/98765430 e/shoppa@example.com t/OA jd/Junior Animator intern id/3 months s/1000
Test case: filter NR
(Assuming there are at least 2 applications)
Expected: Only Malaysia Airline will be displayed on the left side of the list panel.
Getting reminders for internship applications which are due or have interviews scheduled in 7 days
reminder 7
Dealing with missing/corrupted data files
i. Test case: Deleting name field (the key
attribute) from a contact in the InternHub data file.
Expected: After the app is reboot, the now corrupt data file addressbook.json
will be detected and the corrupted data is considered invalid and will not appear in the app.
ii. Test case: Delete InternHub data file.
Expected: If the data file addressbook.json
is nowhere to be found, the app will simply recreate the an empty data file.
iii. Test case: Modify the json format in which InternHub data file is stored.
Expected: If data file addressbook.json
is still in the correct format, the app will run as per normal. However, if the data file becomes unreadable by the program, then the invalid data will be ignored when the app is run.
Overall, our team felt the difficulty level is moderate.