This project is based on the AddressBook-Level3 project created by the SE-EDU initiative (UG, DG, GitHub Page).
Refer to the guide Setting up and getting started.
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: 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.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 12345678.
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 is managed by the UiManager class, which serves as the main controller for managing the UI in EduContacts.
It serves as the interface layer between the application's backend logic and the JavaFX UI components, ensuring a smooth
and consistent user experience.
The UI consists of a MainWindow that is made up of the following parts:
CommandBox CommandHistory to provide an efficient command-tracking mechanism, allowing users to navigate
through previously entered commands using the UP and DOWN arrow keys.ResultDisplay PersonListPanel PersonCardStatusBarFooter PersonDetails FindCommand is run, showing the resulting person's full detailsPersonCard HelpWindow 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.CommandHistory IntegrationThe CommandHistory class, located in seedu.address.ui.util, is responsible for tracking user-entered commands.
It enhances the CommandBox functionality by allowing users to navigate through their command history with the
UP and DOWN arrow keys. This design keeps the command history encapsulated and separate from other UI components,
promoting modularity and adhering to good OOP practices.
The stylesheet used for the UI can be found in src/main/java/resources/view/LightTheme.css.
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 12345678") 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 EduContactsParser 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:
EduContactsParser 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 EduContactsParser 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 object stores StudentId, Name, Address, Phone, Email, Role, Course objects.Module objects which is optional.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.Note: An alternative (arguably, a more OOP) model is given below. It has a Role list in the AddressBook, which Person references. This allows AddressBook to only require one Role object per unique role, instead of each Person needing their own Role objects.
API : Storage.java
The Storage component has a key role in persisting data across user sessions. Specifically, it,
can save both EduContacts data and user preference data in JSON format. Upon application startup, it reads the saved JSON data back into the app, reconstructing it into the corresponding objects in the Model component.
inherits from both EduContactsStorage and UserPrefStorage, 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 to serialize and deserialize data, because the Storage component's job is to save/retrieve objects that belong to the Model. This dependency allows it to handle domain-specific structures, like Person and UserPrefs, ensuring the saved data aligns with the current application state and structure.
uses exception handling to manage file I/O issues (e.g., missing or corrupted files) and provides feedback to the user if data loading or saving encounters an issue, ensuring that the application can gracefully handle storage-related errors.
Classes used by multiple components are in the seedu.address.commons package.
This section describes some noteworthy details on how certain features are implemented.
Note: The execution of commands mentioned in this section follows a similar path to that depicted in the sequence diagram under the Logic component section and will not be discussed in this section.
The module feature allows users to keep track of modules a Person in EduContacts is taking. Each Person object has a List<Module> field that encapsulates the list of modules the Person is taking.
Adding a Module:
Users are able to add a Module to a Person's list of modules using the ModuleCommand. Given below is an example usage scenario of the ModuleCommand.
Step 1. The user launches the application, which is populated with a list of their students. One of the students has StudentId of 12345678. Let's refer to this Person as Alex.
Step 2. The user executes module 12345678 m/CS2103T command to add the CS2103T Module to Alex's list of modules. Alex now has a CS2103T Module in their list of modules.
Editing a Module:
The user is able to edit a Module in a Person's list of modules using the EditCommand. Given below is an example usage scenario of the EditCommand.
Step 1. The user launches the application, which is populated with a list of their students. One of the students has StudentId of 87654321 and a CS2103T Module in their list of modules. Let's refer to this Person as Bernice.
Step 2. The user executes edit 12345678 m/CS2103T CS2103 command to edit the CS2103T Module to CS2103. Bernice now has a CS2103 Module in their list of modules instead of a CS2103T Module.
Deleting a Module:
The user is able to delete a Module from a Person's list of modules using the DeleteCommand. Given below is an example usage scenario of the DeleteCommand.
Step 1. The user launches the application, which is populated with a list of their students. One of the students has StudentId of 87654321 and a CS2103T Module in their list of modules. Let's refer to this Person as Bernice.
Step 2. The user executes delete 12345678 m/CS2103T command to delete the CS2103T Module from Bernice's list of modules. Bernice now no longer has a CS2103T Module in their list of modules.
The grade feature allows users to assign a Grade to a Module of a Student in EduContacts. Each Module object has a Grade field.
Users are able to assign a Grade to a Module using the GradeCommand. Given below is an example usage scenario of the GradeCommand.
Step 1. The user launches the application, which is populated with a list of their students. One of the students has StudentId of 87654321 and a CS2103T Module in their list of modules. Let's refer to this Student as Bernice.
Step 2. The user executes grade 87654321 m/CS2103T g/A command to assign an A Grade to Bernice's CS2103T Module. Bernice now has a CS2103T Module graded A in their list of modules.
Target user profile:
Value proposition: Provides teachers comfortable with CLI-based interfaces an efficient platform for contact management and student academic progress tracking.
Priorities: High (must have) - * * *, Medium (nice to have) - * *, Low (unlikely to have) - *
| Priority | As a … | I want to … | So that I can… |
|---|---|---|---|
* * * | teacher | add a contact | have easy access to contacts |
* * * | teacher | delete a contact | remove contacts that I no longer need |
* * * | teacher | add contact details like email, address, phone number, modules etc. | keep track of my contacts' details |
* * * | teacher | assign a grade to a module that my student is taking | keep track of a student's grades and academic progress |
* * * | teacher | view contact information | have a clear visual reference for contact information |
* * | teacher | edit a contact | update contact information without having to delete it |
* * | teacher | search for a contact | find the contact I am looking for without having to scroll through the list |
* * | teacher | add roles/tags to contacts | group the many contacts that are in the application by their type (e.g. student, tutor etc.) |
* * | teacher | filter contacts by labels or tags | have an easy visual reference with irrelevant contacts filtered out |
* * | new user | access a page that teaches me how to use the application | familiarise myself with the application interface |
* * | efficient CLI user | navigate command history (like in other CLI-based applications) | easily load previously entered commands without having to re-type commands from scratch (to save time) |
* | new user | see the application populated with sample data | see what the application interface looks like |
* | mistake-prone user | undo previous action | undo a mistake without having to delete or edit any contacts |
* | teacher with many contacts | perform mass operations on contacts | perform operations (add, edit, delete etc.) on multiple contacts without having to do so one by one |
* | organised teacher | archive contacts | reduce clutter in the application without permanently deleting the contact |
* | careful teacher | export contact data | have a backup data file in case anything happens to the application |
* | careful teacher | import contact data | load data from a file to restore lost or missing data |
(For all use cases below, the System is the EduContacts and the Actor is the user, unless specified otherwise)
MSS
User adds a contact to the list of contacts.
EduContacts updates the list of contacts.
Use case ends.
Extensions
1a. EduContacts detects an error in the user input.
1a1. EduContacts provides an appropriate error message as feedback to user.
Use case ends.
Preconditions: The list of contacts is not empty.
MSS
User provides details of the student.
EduContacts displays the student and their details.
Use case ends.
Extensions
1a. EduContacts detects an error in the user input (command format, student does not exist etc.).
1a1. EduContacts provides an appropriate error message as feedback to user.
Use case ends.
MSS
User searches for the student (UC02) they wish to add a module for.
User adds a module to the student in the list.
EduContacts updates the list of contacts.
Use case ends.
Extensions
1a. EduContacts detects an error in the user input (command format, student does not exist, duplicate module etc.).
1a1. EduContacts provides an appropriate error message as feedback to user.
Use case ends.
Preconditions: The student has a module already added (UC03).
MSS
User searches for the student (UC02) they wish to add a grade for.
User adds a grade for the student.
EduContacts updates the list of contacts.
Use case ends.
Extensions
1a. EduContacts detects an error in the user input (command format, student or module does not exist etc.).
1a1. EduContacts provides an appropriate error message as feedback to user.
Use case ends.
2a. The module is already graded.
2a1. EduContacts overwrites the old grade with the new grade.
Use case ends.
MSS
User searches for the student (UC02) they wish to delete from the list.
User deletes the student in the list.
EduContacts updates the list of contacts.
Use case ends.
Extensions
1a. EduContacts detects an error in the user input (command format, student does not exist etc.).
1a1. EduContacts provides an appropriate error message as feedback to user.
Use case ends.
MSS
User searches for the student (UC02) they wish to edit.
User edits the details of the student in the list.
EduContacts updates the list of contacts.
Use case ends.
Extensions
1a. EduContacts detects an error in the user input (command format, student does not exist etc.).
1a1. EduContacts provides an appropriate error message as feedback to user.
Use case ends.
MSS
User provides a set of contact-related conditions.
EduContacts updates the list view to show contacts matching the provided conditions.
Use case ends.
Extensions
1a. EduContacts detects an error in the user input (command format etc.).
1a1. EduContacts provides an appropriate error message as feedback to user.
Use case ends.
17 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.
Ensure you have Java 17 or above installed in your computer.
Download Java here if you haven't already.
Note that Mac users should use the specific Azul JDK 17 distribution specified in this guide.
Download the latest .jar file from here.
Copy the file to the folder you want to use as the home folder for your EduContacts.
To run EduContacts, open a command terminal.
To navigate to the folder where you placed the .jar file, use the cd command. For example, if you placed the file in a folder named EduContacts on your desktop, you would enter:
cd ~/Desktop/EduContacts
and use the following command to run the application:
java -jar educontacts.jar
A GUI similar to the screenshot below should appear in a few seconds. Note how the app contains some sample data.
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.
Opening the help window
helpUsing the help button
Adding a valid person
add 12345678 n/John Doe p/91234567 e/johndoe@example.com a/123 Example Street c/Computer Science r/StudentAdding a duplicate person
12345678.add 12345678 n/John Doe p/91234567 e/johndoe@example.com a/123 Example Street c/Computer Science r/StudentAdding an person with invalid Student ID
Editing an existing person
12345678.edit 12345678 p/9876543298765432. The updated details are shown in the success message.Editing a non-existing person
00000000edit 00000000 p/98765432Editing with invalid input
edit 12345678 p/invalidPhoneNumberFilter by name
filter n/JohnFilter by course
filter c/Computer ScienceFilter by multiple attributes
filter n/John c/Computer ScienceAdding a module to an existing person
12345678.module 12345678 m/CS2103TAdding a duplicate module
module 12345678 m/CS2103TAdding an invalid module
Adding a grade to a module
12345678 has "CS2103T" in their module list.grade 12345678 m/CS2103T g/AAdding a grade to a non-existent module
grade 12345678 m/CS9999 g/BAdding an invalid grade
grade 12345678 m/CS2103T g/ZFinding an existing person
find 1234567812345678 are shown in the result panel.Finding a non-existing person
find 00000000Clearing all entries
clearExiting the application
exitNavigating to previous commands
list, add 12345678 n/John Doe p/91234567 e/johndoe@example.com a/123 Example Street c/Computer Science r/Student, filter n/John).
Then, press the UP arrow key in the Command Box.Navigating to next commands
To simulate a missing file, in the same folder as the jar file, navigate to the data folder and delete the address.json file in the folder.
Launch EduContacts by double-clicking the jar file.
Expected: EduContacts is populated by a set of default list of persons. A new address.json file will be created in the data folder after closing the app or executing a command.
To simulate a corrupted file, navigate to the data folder and remove a curly brace at the end of the file.
Launch EduContacts by double-clicking the jar file.
Expected: EduContacts has a blank list of persons. A new address.json file will be created in the data folder after closing the app or executing a command.
We have put in a significant amount of effort in this project, with close to 2,000 commits over 15,000 lines of code contributed. We estimate that our effort for the project is about 50% of that spent on creating AB3.
Our project requires a relative high level of understanding of the code base. Due to the change to make student ID the unique identifier for persons in EduContacts, we needed a high level of understanding of how the various command parsers and argument tokenisers work in order to implement bug-free code.
Additionally, we had to have a good understanding of our JSON and the Jackson library worked in order to implement modules in our project.
Finally, we have also made numerous updates to the GUI, which was tough as we were all relatively new to JavaFX. We therefore rate the difficulty level of our project as medium to hard.
The following planned enhancements are proposed by the development team (team size of 5) to be implemented in the near future.
These are current known issues or feature flaws related to the design of the application that have been identified. These enhancements are not critical to the usability of the application for its intended use case, but rather highlight potential mis-steps in the design process of the application by the development team.
The implementation for the planned enhancements required to improve these known issues/feature flaws have been deferred for future iterations as the development team feels that the effort required to fix these known issues/feature flaws outweighs their value add to the user at this current stage of development.
Feature Flaw: The application currently displays a generic "Invalid command format" error message when duplicate command words are entered. This can be confusing and unhelpful to users. For instance:
edit edit xxxedit."Enhancement: Implement a granular exception handling mechanism to specifically detect and report duplicate command words. This will involve:
Justification for Deferral:
Feature Flaw: When duplicate IDs are entered in commands, the application currently provides a generic "Invalid command format" error message. This does not clearly communicate the issue to the user. For example:
find ID IDID detected, only one allowed."Enhancement: Introduce specific error handling to detect and report duplicate IDs in user commands. This will involve:
ID detected, only one allowed."Justification for Deferral:
Known Issue: On certain platforms (notably MacOS), running the help command and closing the popup window repeatedly in quick succession while in full screen can cause the application to hang or crash.
Proposed Enhancement:
help command by enhancing resource management and concurrency handling to prevent hangs or crashes.Justification for Deferral:
help command in quick succession in full screen), making it less critical compared to other bugs or enhancements.Feature Flaw: All contacts are currently identified by their StudentID. This approach is restrictive, especially for non-student contacts like tutors or colleagues, and relies on dummy IDs as a workaround for non-students.
Enhancement: Introduce a more robust identification mechanism outside of StudentID to distinguish between students and other contact types. For example:
Justification for Deferral:
Model, Storage, and Logic components, including data representation, validation processes, and storage formats.Feature Flaw: The filter command currently has two limitations:
filter c/Computer Science n/CroweEnhancement: Extend the filter command to support multiple filtering conditions. This will allow users to specify multiple conditions for filtering contacts with a toggle functionality to choose between:
Justification for Deferral:
Logic and Parser components to manage complex search constraints effectively.Feature Flaw: The current behavior of partial or full matching in the filter command depends on the field being filtered, which may confuse users.
Enhancement: Add a toggle feature to allow users to choose between:
CS21 matches CS2103T).CS2103T matches only CS2103T).Justification for Deferral:
Logic and Parser components to interpret and handle matching options.Feature Flaw: The application currently supports only Student and Tutor roles, limiting its applicability for broader use cases.
Enhancement: Update the role types to include specific roles such as Colleague and customizable generic roles like Other. For example:
Colleague, and IT.Justification for Deferral:
Model, Logic, and Storage components to handle additional and customizable roles.Student and Tutor), making this enhancement a lower-priority task compared to core feature developments.Feature Flaw: Each contact can only be assigned one role, which limits flexibility in scenarios where a person fits into multiple categories (e.g., a student who is also a part-time teaching assistant/tutor).
Enhancement: Allow contacts to hold multiple roles where logically appropriate. For example:
Student and Tutor simultaneously if they are a part-time teaching assistant.Student and Colleague cannot co-exist).Justification for Deferral:
Model to support role combinations, as well as changes to Logic and UI for input validation and display.Feature Flaw: The current module utility only supports tracking modules, limiting its value for users who might want to track additional details like assignment grades or attendance.
Enhancement: Expand the module utility to allow customization, such as the ability to rename Module to Assignments, for example.
Justification for Deferral:
Model, Storage, and UI components are required to support flexible customization.Feature Flaw: Tutors and non-student contacts may not need a module field, but the current implementation does not allow this distinction.
Enhancement: Add an option to mark the module field as "Not Applicable" for specific roles (e.g., Tutor, Colleague).
Justification for Deferral:
Model and updates to validation logic.The following are new features planned that add additional functionality to our application. (Not to be confused with Planned Enhancements)