ProfBook is a tool tailored to helping specifically CS2103T professors and Teaching Assistants(TA) in managing their tutorial slots and groups. As our target users are technophile, we designed and optimised a CLI-based application specifically for them. It is currently optimised for CS2103T professors and TA with plans to expand to other Computer Science Modules. Please refer to our User Guide for more information on ProfBook.
This guide is intended for future developers, current contributors and users. This guide mainly aims to explain the implementation of ProfBook to future developers and deepen their knowledge in software development. By the end of this guide, you can expect to get an overview of the design architecture of ProfBook and comprehensive details of some of its core features, backed up by UML diagrams.
This project is based on the AddressBook-Level3 (UG, DG) project created by the SE-EDU initiative.
Refer to the guide Setting up and getting started.
Note: The lifeline for many of our diagram should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram.
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 rm 0001Y to delete student with id 0001Y.
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 Displayable
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("rmt 1") API call
as an example.
rmt is the command word for DeleteTaskCommand class. By executing the command rmt 1, tha task with index number 1
will be deleted.
Note: Due to the limitations of PlantUML, the reference frame in the first UML diagram is slightly overlapped.
How the Logic component works:
Logic is called upon to execute a command, it is passed to an ProfBookParser object which in turn creates a
parser that matches the command (e.g., DeleteTaskCommandParser) and uses it to parse the command.Command object (more precisely, an object of one of its subclasses e.g., DeleteTaskCommand)
which is executed by the LogicManager.Model when it is executed (e.g. to delete a task).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:
ProfBookParser class creates an XYZCommandParser (XYZ is a
placeholder for the specific command name e.g., Mark) which uses the other classes shown above to parse the user
command and create a XYZCommand object (e.g., MarkCommand) which the ProfBookParser returns back as a Command
object.XYZCommandParser classes (e.g., EditCommandParser, HelpCommandParser, ...) inherit from the Parser
interface so that they can be treated similarly where possible e.g, during testing.API : Model.java
The Model component,
Root, Group and Student objects (which are contained in a
hierarchical structure in the ProfBook package).Displayable objects (e.g., selected task list, children in current folder)
as a separate filtered list which is exposed to outsiders as an unmodifiable ObservableList<Displayable> 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).
The diagram above shows how the folder structure is implemented in ProfBook,
Root -> Group -> Student.TaskListManager and ChildManager respectively.ChildManager manages the children which is of type IChildElement.ChildrenAndTaskListManager) for classes that require both of those
aforementioned functionalities (e.g. Group and potentially in the future TutorialSlot).API : TaskListManager.java
How the Task component works:
TaskListManager encapsulates the logic required to maintain a TaskList, this logic is
utilised heavily in the ProfBook component.Task, we did this for extensibility. So in the future, should we decide
to implement a new type of task, all we have to do is extend from Task.The sequence diagram below illustrates the interactions within the Model component, taking an execution of a
CreateTodoCommand as example. As the behaviour of CreateTodoCommand is rather dynamic, in our example,
we shall be narrowing our scope to adding a todo tasks to a specified group, g.
How the Model component works:
TaskOperation or
a ChildOperation object that acts as an interface manipulate the modelTaskOperation object is created. This object would store all the necessary information to make
changes directly on the correct state.Command instance calls the required method in the TaskOperation object which results in the TaskOperation
object performing the addition of the Todo task to the group.Note: For ChildrenOperation, ModelManager provides more specific factory methods (e.g., groupChildOperation,
rootChildOperation) to generate the ChildOperation object. It is implemented this way so that ModelManager is able
to check that the operation required matches with the intended effect of the Command object's execution.
API : Path.java
The path package in model package serves as a fundamental representation of the hierarchical structure within the
application. It delineates the navigational paths essential for traversal and dynamic command execution within the
system.
Here is a class diagram for the path package:
PathElement class forms the building blocks for constructing paths within ProfBook.PathElementType enum defines the type of elements within a path:
ROOT: Represents the root element in the hierarchy.GROUPID: Represents the element corresponding to a group in the hierarchy.STUDENTID: Represents the element corresponding to a student in the hierarchy.PARENT: Corresponds to the .. notation, indicating the parent directory.CURRENT: Corresponds to the . notation, indicating the current directory.AbsolutePath represents an absolute path within the system and strictly commences with the ~ element.
resolve method is crucial to resolve a RelativePath and return the resolved path in AbsolutePath type.AbsolutePath represents ~/grp-001/0001A. If the resolve method is called with the
RelativePath representing ../../grp-002, the resolve method will return the AbsolutePath representing the path
~/grp-002.API : Storage.java
The Storage component,
ProfBookStorage and UserPrefStorage, which means it can be treated as either one (if only the
functionality of only one is needed).Model component (because the ProfBookStorageManager component's job is to
save/retrieve objects that belong to the Model)Classes used by multiple components are in the seedu.addressbook.commons package.
This section describes some noteworthy details on how certain features are implemented.
Due to the nature of the application that we aim to make, designing a robust folder structure to represent the hierarchy is crucial to our success. We strive to design a structure that is generic enough to be extended while also being able to capture unique functionality of the different parties at play.
In our current hierarchy, Root -> Group -> Student, Student and Group are required to manage tasks
whereas Root and Group are required to manage children. The Model component briefly mentioned this implementation,
but I will delve into it more comprehensively in this implementation.
We first created interfaces to represent the required logic for each of the manager, namely IChildManager
and ITaskListManager. Then we created concrete classes such as ChildManager and TaskListManager to encapsulate
the aforementioned logic. The purpose of these classes was so that should a folder type, e.g. Student, require a
manager functionality, we could just extend from said manager thus reducing on repeated code. Due to the limitation of
Java, classes are not able to extend from multiple classes. To remedy this, we created a wrapper
class, ChildrenAndTaskListManager.
It is important to note that ChildManager is a generic class that accepts classes that implements
the IChildElement interface. This was done to reduce repeated code while introducing a degree of polymorphism.
In our implementation, only the parents have reference to the child. This reference is stored by using
a Map<Id, Student> and Map<Id, Group> instance.
Note: It is important to note that ChildrenManager is a generic class that accepts classes that implements
the IChildElement interface. This was done to reduce repeated code while introducing a degree of polymorphism.
To further illustrate our folder structure, we have prepared this diagram
Aspect: How do we represent the hierarchy
Aspect: How store reference to children
Implementation for creating a Student and a Group is very similar, so in this guide, I would go through the
implementation for the harder one, which is creating a student. Should you have any questions do feel free to contact
us.
Most of the logic for creating a student is encapsulated in the CreateStudentCommand class, this class utilise
the ChildOperation<Student> class to add the student to the group and the Model class to check for duplicates.
The following methods of ModelManager and ChildOperation<Student> are used:
ModelManager::groupChildOperation - To generate an operation class specific to the current group, it also checks for
the validity and presence of the specified group.ModelManager::hasStudentWithId - To check if the new student id is unique.ChildOperation<Student>::addChild - To add the current student into the group.Given below is an example usage scenario on how an existing user can create a student.
When the user launches the application, existing information is read from the data file profbook.json. The initial
state would look something like this.
Suppose the user is still in the root directory and wants to add a new student to group 1, the user would execute the
following
command: touch ~/grp-001/2000Y --name Bob --email bobby@example.com --phone 92929292 --address blk 258 Toa Payoh.
Do note that the only required fields are --name.
The parser would retrieve all the relevant information from the input and encapsulates it in a CreateStudentCommand.
This command would first do these checks:
ModelManager::hasGroup method.AbsolutePath::isStudentDirectory method.ModelManager::hasStudentWithId method.In this case, if the input was touch ~/grp-001/1234Y ... or touch ~/grp-001/9876A ... a CommandException will
be thrown.
If all checks out, the command would create a new student and add the student to the Model. This addition is done
through getting a ChildOperation<Student> class from the Model::groupChildOperation method. This would ensure
the path to the group is present and valid. The student is added through the ChildOperation<Student>::addChild method.
It should look something like this.
This sequence diagram shows the general flow of the CreateStudentCommand, for more information on each specific
component, do head over to their respective documentation.
Below is an activity diagram showing the general activity of the add student command.
Aspect: Types of fields
Creating and adding a task is one of the key feature of ProfBook. Currently, we support two types of tasks,
namely ToDo and Deadline tasks. Both these tasks extends from the abstract Task class which add to its
extensibility. It is important to note that currently, you can only add tasks to Groups and Students. Needless to say,
the information for these tasks are encapsulated within their respective Task
instance.
As the implementation for creating a ToDo and Deadline task is very similar, I would be bringing you through
the implementation that we found to be more confusing. I would be going through creating a Deadline task and adding it
to all students in a group. For more information you could reach out to us, we would be more than happy
to help.
Note: Illustration in the form of a sequence diagram for creating a ToDo and adding a singular
tasks can be found at the Model component.
Most of the logic for creating a task is encapsulated in the CreateDeadlineCommand class, this class utilises
the ChildOperation<Student> class to add the Deadline to the group and check for duplicates.
The following methods of ModelManager and ChildOperation<Student> are used:
ModelManager::groupChildOperation - To generate an operation class specific to the current group, it also checks for
the validity and presence of the specified group.ChildOperation<Student>::addAllTasks - To add the tasks to all student within a group, it also checks if it is a
duplicate task before adding.ChildOperation<Student>::doAllStudentHaveTask - To check if all children within a group already has the task.It is important to note that for adding a task to a singular group/student, the operation class TaskOperation is used
instead, a sequence diagram illustrating this can be found in the Model component.
Given below is an example usage scenario on how an existing user can add Deadline to all students
When the user launches the application, existing information is read from the data file profbook.json. In our case,
let us narrow our focus to a specific group with 2 students.
Suppose the user is still in the root directory and wants to add a deadline to all students in group1, the user would
execute the following
command: deadline ~/grp-001 --desc Assignment 1 --datetime 2023-12-12 23:59 --all allStu. More information on the
flags could be found in the User Guide.
The parser would retrieve all the relevant information from the input and encapsulate it in
a CreateDeadlineCommand.
This command would first
AbsolutePath::isGroupDirectory method.ChildOperation<Student>::doAllStudentHaveTask method.If all checks out, the command would create a new Deadline instance and add the deadline to all student that do not
already have the aforementioned task. This is done
through getting a ChildOperation<Student> class from the Model::groupChildOperation method. The tasks are then
added through the ChildOperation<Student>::addTaskToAllStudent method. For each student, the method would check if the
task is already present, if not it would add the task.
It should look something like this.
In the above diagram, Jerry already has the exact Deadline and adding it would result in a duplicate. Therefore, the
task is only added to student Ben.
This sequence diagram illustrates the general flow when adding the deadline task to all students, the sequence
diagram for adding a deadline task to a single student can be found in the Model component.
This is an activity diagram showing the general activity of the add deadline command.
Aspect: Should groups have their own task list as well
Aspect: how should we implement adding of bulk tasks
Aspect: Should the same instance of the task be assigned during bulk task
Due to the dynamic need of our target users, professors and TAs, there is a need for our edit command to be equally dynamic.
Our edit command need to be general enough to allow the users to edit both students and groups. This is done by checking
the type of directory that was passed in. This is done through the AbsolutePath::isGroupDirectory
and AbsolutePath::isStudentDirectory method.
Note: More information on how this is done can be found in the documentation
for path package. This then allows parser to check for the validity of the given flags.
As the implementation for editing students and groups is similar, for simplicity, I would be going through implementation of editing a group.
The following methods of ModelManager, AbsolutePath and ChildOperation<Group> are used:
ModelManager::rootChildOperation - To generate an operation class with logic specific to the current root.ModelManager::hasGroupWithId - To check if editing results in a duplicate.ChildOperation<Group>::editChild - To edit the group with the values extracted from parser.AbsolutePath::isGroupDirectory - To check if the path leads to a group directory.AbsolutePath::isStudentDirectory - To check if the path leads to a student directory.Given below is an example usage scenario on how an existing user can edit the name of a group.
When the user launches the application, existing information is read from the data file profbook.json. The initial
state should look something like this.
Suppose the user is still in the root directory and wants to edit the id of group 1 from grp-001 to grp-003, the
user would execute the following command: edit ~/grp-001 -i grp-003.
When parsing the command, from the path, the parser would be able to deduce that we are editing a group. It then checks the flags to ensure only required flags are present.
The fields to be edited is then stored in an EditGroupDescriptor instance. (For student it would be stored in
an EditStudentDescriptor)
If the id is being edited, ModelManager::hasGroupWithId is called to ensure it does not result in a duplicate.
The ChildOperation<Group>::editChild then makes a copy of the existing group while updating the values found in
the EditGroupDescriptor.
It then deletes the old key-value pair in root's Map<Id, group> and adds the new key-value pair.
This is illustrated by the following sequence diagram. It shows the general flow of the edit through editing a Group
instance, this example should be general enough for you to understand how the edit command works on other classes such
as Student.
This is an activity diagram showing the general activity of the edit command.
Aspect: How to ensure edit is able to handle editing students and group
edit which acts differently depending on the input
path.
edit more extensibleedit commands.
Initially, implementing this feature seemed like a daunting task. However, after finalising our Model hierarchy, we
realised that implementing move was quite straight forward. Moving a student can be easily done by removing the
student's reference from its current group by removing its key-value pair from the group's Map<Id, Student> field.
Then to complete the move, the student is added to the target group by adding it into the target
group's Map<Id, Student> field. All of this operation is facilitated by the ChildOperation<Student> class.
Given below is an example usage scenario whereby a student is moved from group1 to group2.
profbook.json.1234Y from grp-001 to grp-002, the
user would execute the following command: mv ~/grp-001/1234Y ~/grp-002.MoveStudentCommand instance.ChildOperation<Student>::addChild method. The old
reference is removed via the ChildOperation<Student>::deleteChild method.
Currently, the only way to edit tasks is by manually deleting and then adding them again. This creates extra hassle for
the user and possible more inconveniences as doing so might change the task's index resulting in the user having
to cat again to figure out its new index. We plan to edit the task manually for the user by creating a new command
that deletes and then creates a new task with the edited information while keeping the index the same. Implementing this
is just a combination of deleting and creating, but it improves the user's quality of life greatly.
Currently, our application only checks if the phone number is more than 3 characters long. Our current validation is
lacking as users are able to enter a 123 as a phone number or a phone number that is infinitely long. We plan to
improve this validation by enforcing a tighter validation. This can be achieved by creating a Map<String, Integer> of
common phone extensions to their length and then enforcing that the phone number be of that length. This allows our
users to have the peace of mind that the phone number is validated and robust enough to handle international numbers.
Currently, our application only checks if the required fields (e.g. --name, --desc) is present. Our current validation is
lacking as users are able to enter a value that is infinitely long which may hinder the performance and functionality of
our GUI. We plan to counteract this by enforcing a max character length for each of our field. Implementing this is
would be rather simple by adding a length check during parsing. We could limit name length to 46 characters, email to 62
etc.
Currently, our application does not check if the tasks are marked or unmarked before any operation. This results in users being able to mark/un-mark tasks infinitely, this is not intuitive and may mislead some users. Hence, we plan to only allow users to un-mark tasks that are marked and vice versa. This can be easily done by checking the current state and throwing an error if the resultant state is same as the current state. Also, we plan to add a more descriptive error message to highlight to the user of the current state of the task.
Currently, our application only checks for duplicates by their id, meaning two students/group are considered the same if and only if their ids are identical. This means that two students with identical number and email but differing ids are considered different in ProfBook, needless to say this does not reflect requirements in the real world. Therefore, we plan to revamp our duplication checking for students by checking for equality between their phone number and email.
Currently, while our application tries to output a descriptive and apt message for each error, we have received feedback
that some of our error message could be more descriptive. One such example is trying to edit the root ~/ directory or
trying to edit a directory that does not exist. In both cases, the error message given
is Path does not exist in ProfBook. In this example, we could have mention that you are unable to edit the root
directory for the prior and that the Path does not lead to a student/group for the latter. This is just one example, we
plan to revamp our error message to be more descriptive and user-friendly.
Currently, our hierarchy only extends to Group. To serve our target users better, we plan to add a new level,
TutorialSlot to ProfBook. This would allow our target users to juggle not only groups but also tutorial slots.
Implementing this is rather easy as TutorialSlot would in theory be almost identical to the implementation of Group,
all TutorialSlot have to do is just extend from ChildrenAndTaskListManager.
Currently, our users can only mark tasks as completed. To serve our target users better, we plan to allow our users to
assign a grade or score to a task. This would allow our target users to better keep track of and monitor their students
and their groups progress. Implementing this would be adding a new tag to our display for tasks and creating a new
command similar to that of mark that receives and store the grade or score.
Currently, our users are unable to filter the current displayed list. We predict that this could be a hassle if the user is required to manage many groups and students with each having a myriad of tasks. We plan to implement this by creating a new command where users would be able to pass in the field that they wish to search by. Then, we can filter the display list with a simple for-loop.
Target user profile:
Value proposition: Keep track of groups and students and their deadlines and tasks efficiently with an interface that will be faster than a typical mouse/GUI driven app
Priorities: High (must have) - * * *, Medium (nice to have) - * *, Low (unlikely to have) - *
| Priority level | As a … | I want to … | So that I can… |
|---|---|---|---|
* * * | New user | see usage instructions | refer to instructions when I forget how to use the App |
* * * | New user | take advantage of existing Linux skills | be more efficient in using the application |
* * * | New user | create deadlines for student | keep track of when assignments are due |
* * * | New user | create todo task for student | keep track of their progress |
* * * | New user | create deadline for a group | keep track of when group specific assignments are due |
* * * | New user | create todo for a group | keep track of the progress of each group relative to others |
* * * | New user | add time to a task | I can record when a task needs to be done |
* * * | New user | set alerts and notification | I can receive the notifications of the task |
* * * | New user | add the matriculation number of students | I can track their tasks based on their matriculation number |
* * * | New user | create student profile | manage information of a specific student |
* * * | New user | delete a student | remove students that I no longer need to keep track of |
* * * | New user | delete a group | remove groups that I no longer need to keep track of |
* * * | New user | delete a task | remove tasks that I no longer need to keep track of |
* * * | New user | create group | manage information of a specific group |
* * * | Experienced user | mark task done for every student in a group | I do not need to mark each task manually |
* * * | Experienced user | add tasks for every student in the book | I do not need to add tasks manually |
* * * | Experienced user | add tasks for every student in a group | I do not need to add tasks manually |
* * | New user | add the profile picture of students | I can better remember them |
* * | New user | create tutorial slot | manage information fo a specific tutorial slot |
* * | New user | create deadline for a tutorial group | keep track of when tutorial specific assignments are due |
* * | New user | create todo tasks for a tutorial group | keep track of the progress of each tutorial group relative to others |
* * | New user | see the pending task that has the next earliest deadline | i can know what do do next |
* * | Experienced user | add tasks for every student in a tutorial group | I do not need to add tasks manually |
* * | Experienced user | search for a student/tutorial group by name | pull up students/tutorial groups without having to go through the entire list |
* * | Experienced user | be able to see an brief overview of last week | Can see deadlines that have passed etc |
* * | Experienced user | easily edit the student/tutorial groups | Information is applicable throughout time |
* * | Experienced user | move students around, edit which group they are in | I can be flexible with the groupings |
* * | Expert user | check last week's deadline have been met or not | I would not miss any deadline |
* * | Expert user | upload text file contains tutorial groups and students | I do not need to manually add students and tutorial groups |
* | Experienced user | sync with Google calendar | To keep information easily accessible |
* | Experienced user | sync with NUSMods | To make it easier to take note of tutorial venues |
* | Experienced user | use ProfBook to track attendance for each tutorial slot | I can easily write down attendance in one area |
* | Expert user | view a dashboard that provides the overview of the progress of each tutorial group and their respective tasks | I can easily and quickly focus on areas that require my attention |
* | Expert user | let the program generate a detailed report on the performance of each tutorial group | I can easily identify the areas of strengths and weaknesses of each students |
* | Expert user | incorporate my own scripts to customise my own experience | I can improve productivity and tailor fit the software for myself |
* | Expert user | make the program support customizable templates for tutorials and student profiles | I can make it more aesthetically pleasing |
* | Expert user | make use of the feature to archive certain task | I can keep track of the history and not focus on unimportant task. |
(For all use cases below, the System is the ProfBook and the Professor is the user, unless specified
otherwise)
Use case: User asks for help
MSS
User requests for help.
ProfBook displays help message, informs user how to input help with additional information specific to command.
Use case ends.
Use case: User asks for help for a specific command
MSS
User requests for help for a specific command.
ProfBook displays help message for the command.
Use case ends.
Extensions
1a. User inputs invalid command together with help.
1a1. ProfBook shows an error message.
Use case resumes at step 1.
Use case: Change directory to group
MSS
User requests to cd into a specific group.
ProfBook moves into the directory, display updates to show students within specified group.
Use case ends.
Extensions
1a. The path of the group is invalid.
1a1. ProfBook shows an error message.
Use case resumes at step 1.
1b. No path provided.
1b1. ProfBook shows an error message.
Use case resumes at step 1.
Use case: User requests to view children
MSS
User requests to view children either within current directory or specified path.
ProfBook displays list of children.
Use case ends.
Extensions
1a. Provided path is invalid.
1a1. ProfBook shows an error message.
Use case resumes at step 1.
1b. No path provided.
1b1. ProfBook shows list of children under current directory.
Use case ends.
Use case: View tasks
MSS
User requests to view tasks under specified path or current path if not specified.
ProfBook displays task list of path, either task list of group or student.
Use case ends.
Extensions
1a. The given path is invalid.
1a1. ProfBook shows an error message.
Use case resumes at step 1.
1b. No path specified.
1b1. Current path is root path
ProfBook shows an error message.
Use case resumes at step 1.
1b2. Current path is not root path.
ProfBook displays task list of current path.
Use case ends.
Use case: Clear all entries
MSS
User requests to delete all data stored in ProfBook.
ProfBook deletes all data stored and display updates to be empty.
Use case ends.
Use case: Exit ProfBook
MSS
User requests to exit ProfBook.
ProfBook stores all data and closes application.
Use case ends.
Use case: Add a student
MSS
User requests to add a student.
ProfBook adds the student to the specified group.
Use case ends.
Extensions
1a. The given parameters are invalid.
1a1. ProfBook shows an error message.
Use case resumes at step 1.
Use case: Edit a student's details
MSS
User requests to edit a student's details.
ProfBook edits the students details.
Use case ends.
Extensions
1a. The specified path is invalid.
1a1. ProfBook shows an error message.
Use case resumes at step 1.
1b. The given parameter is invalid.
1b1. ProfBook shows an error message.
Use case resumes at step 1.
Use case: Edit a group's details
MSS
User requests to edit a group's details.
ProfBook edits the groups details.
Use case ends.
Extensions
1a. The specified path is invalid.
1a1. ProfBook shows an error message.
Use case resumes at step 1.
1b. No path provided, user is in group directory.
1b1. ProfBook edits the groups details.
Use case ends.
1c. The parameter to be changed is invalid.
1c1. ProfBook shows an error message.
Use case resumes at step 1.
Use case: Delete a group or student
MSS
User requests to delete a group or student.
ProfBook removes group or student.
Use case ends.
Extensions
1a. The given path is invalid.
1a1. ProfBook shows an error message.
Use case resumes at step 1.
Use case: Delete a task
MSS
User requests to delete a task with task index.
ProfBook deletes the task.
Use case ends.
Extensions
1a. User inputs command while not in task list display.
1a1. ProfBook shows an error message.
Use case resumes at step 1.
1b. The given index is invalid.
1b1. ProfBook shows an error message.
Use case resumes at step 1.
Use case: Move student into/out of group
MSS
User requests to move a specific student from a source group to destination group with the path.
ProfBook moves the student from a source group to destination group.
Use case ends.
Extensions
1a. The given Student path is invalid.
1a1. ProfBook shows an error message.
Use case resumes at step 1.
1b. The given group path is invalid.
1b1. ProfBook shows an error message.
Use case resumes at step 1.
Use case: Create a group
MSS
User requests to create a group with path and name.
ProfBook creates the group.
Use case ends.
Extensions
1a. The given name of group is invalid.
1a1. ProfBook shows an error message.
Use case resumes at step 1.
1b. The given group id is a duplicate of an existing one.
1b1. ProfBook shows an error message.
Use case resumes at step 1.
1c. The given path is invalid.
1c1. ProfBook shows an error message.
Use case resumes at step 1.
Use case: Create a ToDo task
MSS
User requests to create a ToDo task.
ProfBook creates the task under specified path/current path.
Use case ends.
Extensions
1a. The given path is invalid.
1a1. ProfBook shows an error message.
Use case resumes at step 1.
1b. The given description is invalid.
1b1. ProfBook shows an error message.
Use case resumes at step 1.
1c. No path specified, user is in group directory.
1c1. ProfBook creates ToDo for the group.
Use case ends.
1d. No path specified, user in root directory.
1d1. ProfBook shows an error message.
Use case resumes at step 1.
1e. User specifies --all allStu or --all allGrp.
1e1. ProfBook creates Todo for either all students within the group or all groups or students within ProfBook.
Use case ends.
Use case: Create a Deadline task
MSS
User requests to create a Deadline task.
ProfBook creates the task under specified path/current path.
Use case ends.
Extensions
1a. The given path is invalid.
1a1. ProfBook shows an error message.
Use case resumes at step 1.
1b. The given description is invalid.
1b1. ProfBook shows an error message.
Use case resumes at step 1.
1c. The given deadline date is invalid.
1c1. ProfBook shows an error message.
Use case resumes at step 1.
1d. No path specified, user in root directory.
1d1. ProfBook creates Deadline for the group.
Use case ends.
1e. No path specified, user in root directory.
1e1. ProfBook shows an error message.
Use case resumes at step 1.
1f. User specifies --all allStu or --all allGrp.
1f1. ProfBook creates Deadline for either all students within the group or all groups or students within ProfBook.
Use case ends.
Use case: Mark task
MSS
User requests to mark a specific task.
ProfBook marks task based on given index, display updates to show as marked.
Use case ends.
Extensions
1a. User inputs command while not in task list display.
1a1. ProfBook shows an error message.
Use case resumes at step 1.
1b. The Index provided is invalid.
1b1. ProfBook shows an error message.
Use case resumes at step 1.
Use case: Un-mark task
MSS
User requests to un-mark a specific task.
ProfBook un-marks task based on given index, display updates to show as unmarked.
Use case ends.
Extensions
1a. User inputs command while not in task list display.
1a1. ProfBook shows an error message.
Use case resumes at step 1.
1b. The Index provided is invalid.
1b1. ProfBook shows an error message.
Use case resumes at step 1.
Use case: Delete task
MSS
User requests to delete a specific task.
ProfBook delete task based on given index.
Use case ends.
Extensions
1a. User inputs command while not in tasklist display.
1a1. ProfBook shows an error message.
Use case resumes at step 1.
1b. The Index provided is invalid.
1b1. ProfBook shows an error message.
Use case resumes at step 1.
Technical requirements:
11 or above installed.Performance requirements:
Reliability Requirements:
Quality requirements:
Constraints:
cat command.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.
Important: For simplicity, all the command given below are based on the assumption that you are currently at the
root directory ~/>. Should you change your directory to something other than root do take note that our commands may
need to change according to your current directory. More information can be found in our
user guide.
Initial launch
Download the latest ProfBook.jar file and copy into an empty folder from latest release.
Double-click the jar file Expected: Shows the GUI with some sample data. The window size may not be optimum.
Saving window preferences
Resize the window to an optimum size. Move the window to a different location. Close the window.
Re-launch the app by double-clicking the jar file.
Expected: The most recent window size and location is retained.
Creating a new group,
Prerequisites: No existing group with GroupId grp-001.
Test case: mkdir grp-001 --name Amazing Group1
Expected: A new group will be added to the list in the bottom output box, with name Amazing Group1 and GroupId grp-001.
Test case: mkdir 0123Y --name Amazing Group1
Expected: An error message indicating the path is invalid will be displayed.
Test case: mkdir x --name Amazing Group1 (where x is an invalid path to a Group)
Expected: An error message indicating the path is invalid will be displayed.
Other incorrect mkdir commands to try: mkdir, mkdir grp-001, mkdir --name Amazing Group1 (where one or more required fields are missing in the command)
Expected: An error message indicating the command format is invalid will be displayed.
Adding a student into the specified directory,
Prerequisites for all test cases: There exist a group with GroupId grp-001
Prerequisites: ProfBook does not contain a student with id 0199Y.
Test case: touch ~/grp-001/0199Y --name Mary --email mary@gmail.com --phone 65412987 --address 4 Loyang Walk Loyang Industrial Estate
Expected: The student with id 0199Y will be added to grp-001.
Prerequisites: ProfBook does not contain a student with id0123Y.
Test case: touch ~/grp-001/0123Y --name Mary
Expected: The student with id 0123Y will be added to grp-001.
Test case: touch grp-001 --name Mary
Expected: An error message indicating the path is invalid will be displayed.
Test case: touch x --name Mary (where x is an invalid path)
Expected: An error message indicating the path is invalid will be displayed.
Other incorrect touch commands to try: touch, touch grp-001, touch --name student, ... (where one or more required fields are missing in the command)
Expected: An error message indicating the command format is invalid will be displayed.
Deleting a student or group from the specified path,
Prerequisites: There exist a group with GroupId grp-001 with a student with id 0123Y inside it.
Test case: rm ~/grp-001/0123Y
Expected: The student 0123Y in grp-001 wil be deleted.
Prerequisites: There exist a group with GroupId grp-001.
Test case: rm ~/grp-001
Expected: The group with GroupId grp-001 wil be deleted.
Prerequisites: There does not exist a group with GroupId grp-002.
Test case: rm ~/grp-002
Expected: An error message indicating the path is invalid will be displayed.
Test case: rm ~/0001Y
Expected: An error message indicating the path is invalid will be displayed.
Other incorrect rm commands to try: rm
Expected: An error message indicating the command format is invalid will be displayed.
Edits a student's details or group's details in the specified path,
Prerequisites: There exist a group with GroupId grp-001 that contains a student with id 0123Y inside it.
Test case: edit ~/grp-001/0123Y --phone 91919191
Expected: The student 0123Y will have his/her phone number edited.
Prerequisites: There exist a group with GroupId grp-001 that contains a student with id 0999A inside it.
Test case: edit ~/grp-001/0123Y --id 0999A
Expected: An error message indicating the id has been used by other student will be displayed.
Test case: edit ~/grp-001/0123Y --id 0123Y
Expected: An error message indicating no changes have been made will be displayed.
Test case: edit --name Lucy --email lucy@gmail.com --phone 91919191
Expected: An error message indicating the root directory cannot be edited will be shown.
Other incorrect edit commands to try: edit ~/grp-001 --name Lucy --email lucy@gmail.com --phone 91919191, edit ~/grp-001
(Where one or more required fields are missing)
Expected: An error message indicating the command format is invalid will be displayed.
Creates todo task for a specific student or group,
Prerequisites: There exist a group with GroupId grp-001 that contains a student with id 0123Y inside it.
Test case: todo ~/grp-001/0123Y --desc Assignment 1
Expected: The todo task Assignment 1 will be assigned to student 0123Y.
Prerequisites: There exist a group with GroupId grp-001.
Test case: todo ~/grp-001 --desc Assignment 1
Expected: The todo task Assignment 1 will be assigned to group grp-001.
Prerequisites: There exist a group with GroupId grp-001 with a todo Assignment 1 already assigned to it.
Test case: todo ~/grp-001 --desc Assignment 1
Expected: An error message indicating that Assignment 1 has already been allocated to it.
Creates todo task for all groups or all students in a group,
Prerequisites: There exist at least one group in ProfBook and at least one of the groups does not have the todo task, Assignment 1.
Test case: todo --desc Assignment 1 --all allGrp
Expected: The todo task Assignment 1 will be allocated to all groups that does not already have the todo task.
Prerequisites: There exist a group with GroupId grp-001 with at least one student.
Prerequisites: At least one of the student does not have the todo task, Assignment 1.
Test case: todo ~/grp-001 --desc Assignment 1 --all allStu
Expected: The todo task Assignment 1 will be allocated all students in grp-001 that does not already have the todo task.
Prerequisites: There exist at least one student in ProfBook and at least one of the students does not have the todo task, Assignment 1.
Test case: todo --desc Assignment 1 --all allStu
Expected: The todo task Assignment 1 will be allocated to all students under root directory that does not already have the todo task.
Test case: todo --desc Assignment 1 --all allStudent
Expected: An error message indicating the format of category label is invalid will be displayed.
Test case: todo ~/grp-001/0001Y --desc Assignment 1 --all allGrp
Expected: An error message indicating allGrp flag is only allowed for root path.
Test case: todo ~/0001Y --desc Assignment 1
Expected: An error message indicating the path is invalid will be displayed.
Other incorrect todo commands to try: todo, todo ~/grp-001, ... (where one or more required fields are missing)
Expected: An error message indicating the command format is invalid will be displayed.
Creates deadline task for a specific student or group,
Prerequisites: There exist a group with GroupId grp-001 that contains a student with id 0123Y inside it.
Test case: deadline ~/grp-001/0123Y --desc Assignment 1 --datetime 2023-10-11 23:59
Expected: The deadline task Assignment 1 will be allocated to student 0123Y.
Prerequisites: There exist a group with GroupId grp-001.
Test case: deadline ~/grp-001 --desc Assignment 1 --datetime 2023-10-11 23:59
Expected: The deadline task Assignment 1 will be allocated to group grp-001
Test case: deadline ~/grp-001 --desc Assignment 1 --datetime 11-11-2023 23:59
Expected: An error message indicating the datetime format is invalid will be displayed.
Prerequisites: There exist a group with GroupId grp-001 with the same deadline task Assignment 1 already assigned to it.
Test case: deadline ~/grp-001 --desc Assignment 1 --datetime 2023-10-11 23:59
Expected: An error message indicating that Assignment 1 has already been allocated to it.
Creates deadline task for all groups or all students in a group,
Prerequisites: There exist at least one group in ProfBook and at least one of the groups does not have the deadline task, Assignment 1.
Test case: deadline --desc Assignment 1 --datetime 2023-10-11 23:59 --all allGrp
Expected: The deadline task Assignment 1 will be allocated to all groups that does not already have the task.
Prerequisites: There exist a group with GroupId grp-001 with at least one student.
Prerequisites: At least one of the student does not have the deadline task, Assignment 1.
Test case: deadline ~/grp-001 --desc Assignment 1 --datetime 2023-10-11 23:59 --all allStu
Expected: The deadline task Assignment 1 will be allocated all students in grp-001 that does not already have the task.
Prerequisites: There exist at least one student in ProfBook and at least one of the students does not have the deadline task, Assignment 1.
Test case: deadline --desc Assignment 1 --datetime 2023-10-11 23:59 --all allStu
Expected: The deadline task Assignment 1 will be allocated to all students under root directory that does not already have the task.
Test case: deadline --desc Assignment 1 --datetime 2023-10-11 23:59 --all allStudent
Expected: An error message indicating the format of category label is invalid will be displayed.
Test case: deadline ~/grp-001/0001Y --desc Assignment 1 --all allGrp
Expected: An error message indicating allGrp flag is only allowed for root path.
Test case: deadline ~/0001Y --desc Assignment 1 --datetime 2023-10-11 23:59
Expected: An error message indicating the path is invalid will be displayed.
Other incorrect deadline commands to try: deadline, deadline ~/grp-001, deadline ~/grp-001 --desc no date time flag (where one or more required fields are missing)
Expected: An error message indicating the command format is invalid will be displayed.
Marks a specified task as done for a student or group
Prerequisites: The display panel is showing the task list of the specified student or group.
This can be achieved by using the cat command alongside the path to the desired student/group to display their task list.
Prerequisites: The current directory is group directory and the group has been assigned minimally one task.
Test case: mark 1
Expected: The task with task index 1 will be marked as completed.
Test case: mark
Expected: An error message indicating the command format is invalid will be displayed.
Test case: mark a
Expected: No task would be marked, an error will be shown.
Other incorrect mark commands to try: mark \-2, mark x (Where x is positive integer which is greater than current task list size)
Expected: No task would be marked, an error message indicating that the index given is invalid.
Un-marks a specified task for a student or group
Prerequisites: The display panel is showing the task list of the specified student or group.
This can be achieved by using the cat command alongside the path to the desired student/group to display their task list.
Prerequisites: The current directory is group directory and the group has been assigned minimally one task.
Test case: unmark 1
Expected: The task with task index 1 will be un-marked.
Test case: unmark
Expected: An error message indicating the command format is invalid will be displayed.
Test case: unmark a
Expected: No task would be un-marked, an error will be shown.
Other incorrect unmark commands to try: unmark \-2, unmark x (Where x is positive integer which is greater than current task list size)
Expected: No task would be marked, an error message indicating that the index given is invalid.
Deletes a specified task for a student or group,
Prerequisites: The display panel is showing the task list of the specified student or group.
This can be achieved by using the cat command alongside the path to the desired student/group to display their task list.
Prerequisites: The current directory is group directory and the group has been assigned minimally one task.
Test case: rmt 1
Expected: The task with task index 1 will be deleted.
Test case: rmt
Expected: An error message indicating the command format is invalid will be displayed.
Test case: rmt a
Expected: No task would be deleted, an error will be shown.
Other incorrect rmt commands to try: rmt \-2, rmt x (Where x is positive integer which is greater than current task list size)
Expected: No task would be deleted, an error message indicating that the index given is invalid.
Changes the current directory in the ProfBook,
Prerequisites: There exist a group with GroupId grp-001.
Test case: cd grp-001, cd ~/grp-001
Expected: The current directory will be changed to grp-001 and the interface will change from displaying all the group to displaying all the student in grp-001.
Prerequisites: There does not exist a group with GroupId grp-002.
Test case: cd grp-002
Expected: An error message indicating the path is not found.
Test case: cd ~/0000Y
Expected: An error message indicating the path is invalid will be displayed.
Other incorrect cd commands to try: cd
Expected: An error message indicating the command format is invalid will be displayed.
Shows the list of children in specified directory,
Test case: ls
Expected: All the groups in ProfBook will be displayed.
Prerequisites: There exist a group with GroupId grp-001.
Test case: ls grp-001
Expected: The interface will change from displaying all the group to displaying all the student in grp-001.
Prerequisites: There does not exist a group with GroupId grp-002.
Test case: ls grp-002
Expected: An error message indicating the path is not found.
Test case: ls ~/0000Y
Expected: An error message indicating the path is invalid will be displayed.
Displays all tasks,
Prerequisites: There exist a group with GroupId grp-001.
Test case: cat grp-001
Expected: The interface will change from displaying all the group to displaying all tasks assigned to grp-001.
Prerequisites: There does not exist a group with GroupId grp-002.
Test case: cat grp-002
Expected: An error message indicating the path is not found.
Test case: cat ~/0000Y
Expected: An error message indicating the path is invalid will be displayed.
Getting the default save file.
Prerequisites: Place ProfBook.jar in an empty home folder. Perform the following step in the root directory.
Prerequisites: There should be a group with id grp-001, this grp-001 should contain a student with id 0001Y
Test case: todo grp-001/0001Y --desc Assignment One.
Expected: profbook.json appears in data folder inside home folder. Student with id 0001Y has a new task added which is reflected in profbook.json. Sample output here.
Test case: rm grp-001/0001Y.
Expected: profbook.json is updated with the removal of student 0001Y. Sample output here.
Clearing the save file.
Prerequisites: Have profbook.json in the data folder. Perform the previous step if the file isn’t there.
Test case: clear
Expected: An empty profbook.json file like here.
Our project, ProfBook, underwent a significant transformation with the primary objective of providing robust student organization and task management features. The project also aimed to create a terminal-like application, complete with a terminal-like user interface and the ability to navigate through a hierarchical structure.
The project was classified as challenging due to:
Terminal-Like Functionality: Creating a terminal-like interface and functionality from scratch was a complex task, requiring a deep understanding of terminal behavior and navigation.
Hierarchical Structure: Our application features a hierarchical structure, with ProfBook serving as the root entity. Under ProfBook, there are groups, and each group contains students. Managing this hierarchical structure added a significant amount of complexity to the project.
Diverse Classes: Unlike AB3, our project needed to handle a more extensive range of classes, including Student, Group, and Task. This expansion added complexity as we had to provide functionality for student organization and task management within the same application.
The project demanded an estimated total effort of approximately one month. The effort was distributed across various project phases:
Design and Architecture: This phase focused on designing the terminal-like user interface, defining terminal behavior, and integrating the hierarchical structure. Additionally, it involved accommodating and ensuring the smooth interaction of multiple entity types within the application. We found it especially difficult to find a class generic enough to capture all the different behaviour of each directory in ProfBook while also making it extensible.
Implementation and Coding: The implementation phase was dedicated to building custom components and functionalities essential for realizing terminal behavior, hierarchical structure navigation, and handling diverse classes.
Testing and Quality Assurance: This critical phase aimed to ensure the terminal-like interface worked seamlessly, the hierarchical structure navigation functionality was error-free, and the application effectively managed the different entity types.
Documentation: Preparing comprehensive documentation was essential for guiding both users and developers in understanding and utilizing the terminal-like application.
A notable aspect of our project was the efficient use of custom logics, which contributed to a significant reduction in the overall effort.
Path package: We introduced the path package, which includes subclasses for managing both absolute and
relative paths. This package played a crucial role in managing navigation and executing dynamic commands within
our application.
ChildManager Component: The class was instrumental in representing the hierarchical structure in our application. We successfully leveraged this class to perform operations related to child entities, optimizing the handling of students within groups and groups within the ProfBook.
TaskListManager class: This class streamlines task management and allocation by providing a consistent and unified interface for handling tasks throughout the application.
Reusing these logics enhanced project efficiency and maintainability.