Developer Guide
Pied Piper
Pied Piper is a user-friendly task management application tailored for current and future university student leaders. The app helps them stay organised and prepare for real-world situations by helping them manage project groups, and simulate the real world review system. Key features include creating tasks, assigning tasks to team members, setting due dates, rating completed tasks out of 5, and providing feedback through comments. The ability to seamlessly toggle between a person list and task list also helps team leaders easily identify each team members’ roles and their assigned task to complete. Ideal for personal projects and team collaboration, Pied Piper aims to improve productivity and equip university students with valuable skills for their future careers.
Some of our main features:
- Adding tasks with or without due dates.
- Adding team members and assigning them to created tasks.
- Mark tasks as complete and give a rating to gauge the performance of each member.
- Review each member’s overall performances based on the tasks completed.
This user guide provides a broad overview of how the various features work and how to use them properly. We hope you have fun using Pied Piper and may all your future endeavors be elevated with our product!
Table of Contents
- 1. Acknowledgements
- 2. Setting up, getting started
- 3. Design
- 4. Implementation
- 5. Other guides
- 6. Appendix: Requirements
- 7. Manual testing
1. Acknowledgements
- Pied Piper is a brownfield project that builds on AB-3.
- This project is a part of the se-education.org initiative.
The libraries used are as follows:
- Jackson was used for storage.
- JavaFX was used to render the UI.
- PlantUML was used to create UML diagrams.
- JUnit was used to make test scripts for testing.
2. Setting up, getting started
Refer to the guide Setting up and getting started.
3. Design
.puml
files used to create diagrams in this document can be found in the diagrams folder. Refer to the PlantUML Tutorial at se-edu/guides to learn how to create and edit diagrams.
3.1 Architecture
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
has two classes called Main
and MainApp
. It is responsible for,
- At app launch: Initializes the components in the correct sequence, and connects them up with each other.
- At shut down: Shuts down the components and invokes cleanup methods where necessary.
Commons
represents a collection of classes used by multiple other components.
The rest of the App consists of four components.
-
UI
: The UI of the App. -
Logic
: The command executor. -
Model
: Holds the data of the App in memory. -
Storage
: Reads data from, and writes data to, the hard disk.
How the architecture components interact with each other
The Sequence Diagram below shows how the components interact with each other for the scenario where the user issues the command delete 1
.
Each of the four main components (also shown in the diagram above),
- defines its API in an
interface
with the same name as the Component. - implements its functionality using a concrete
{Component Name}Manager
class (which follows the corresponding APIinterface
mentioned in the previous point.
For example, the Logic
component defines its API in the Logic.java
interface and implements its functionality using the LogicManager.java
class which follows the Logic
interface. Other components interact with a given component through its interface rather than the concrete class (reason: to prevent outside component’s being coupled to the implementation of a component), as illustrated in the (partial) class diagram below.
The sections below give more details of each component.
3.2 UI component
The API of this component is specified in Ui.java
The UI consists of a MainWindow
that is made up of parts e.g.CommandBox
, ResultDisplay
, 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,
- executes user commands using the
Logic
component. - listens for changes to
Model
data so that the UI can be updated with the modified data. - keeps a reference to the
Logic
component, because theUI
relies on theLogic
to execute commands. - depends on some classes in the
Model
component, as it displaysPerson
object residing in theModel
.
Note:
- Above describes the UI component for the
PersonList
. - For our
TaskList
, the way it works is the same, butModel
is changed toTaskBookModel
, andPerson
is changed toTask
.
3.3 Logic component
API : Logic.java
Here’s a (partial) class diagram of the Logic
component:
How the Logic
component works:
- When
Logic
is called upon to execute a command, it uses theAddressBookParser
class to parse the user command. - This results in a
Command
object (more precisely, an object of one of its subclasses e.g.,AddCommand
) which is executed by theLogicManager
. - The command can communicate with the
Model
when it is executed (e.g. to add a person). - The result of the command execution is encapsulated as a
CommandResult
object which is returned fromLogic
.
The Sequence Diagram below illustrates the interactions within the Logic
component for the execute("delete 1")
API call.
DeleteCommandParser
should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram.
Here are the other classes in Logic
(omitted from the class diagram above) that are used for parsing a user command:
How the parsing works:
- When called upon to parse a user command, the
AddressBookParser
class creates anXYZCommandParser
(XYZ
is a placeholder for the specific command name e.g.,AddCommandParser
) which uses the other classes shown above to parse the user command and create aXYZCommand
object (e.g.,AddCommand
) which theAddressBookParser
returns back as aCommand
object. - All
XYZCommandParser
classes (e.g.,AddCommandParser
,DeleteCommandParser
, …) inherit from theParser
interface so that they can be treated similarly where possible e.g, during testing.
Note:
- Our app also has a
TaskBook
, which works the same asAddressBook
, except that it interacts with the classes that handle tasks, such asTaskBookModel
andDeleteTaskCommandParser
.
3.4 Model component
API : Model.java
API : TaskBookModel.java
The Model
component,
- stores all
Person
objects (which are contained in aUniquePersonList
object). - stores the currently ‘selected’
Person
objects (e.g., results of a search query) as a separate filtered list which is exposed to outsiders as an unmodifiableObservableList<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. - stores a
UserPref
object that represents the user’s preferences. This is exposed to the outside as aReadOnlyUserPref
objects. - does not depend on any of the other three components (as the
Model
represents data entities of the domain, they should make sense on their own without depending on other components)
Note:Tasks are handled in a similar way in the TaskBookModel
component. It interacts with components like UniqueTaskList
and is ‘observed’ as an unmodifiable ObservableList<Task>
.
Role
list in Pied Piper, which Person
references. This allows Pied Piper
to only require one Role
object per unique role, instead of each Person
needing their own Role
objects.3.5 Storage component
API : Storage.java
The Storage
component,
- can save both address book data and user preference data in json format, and read them back into corresponding objects.
- inherits from both
AddressBookStorage
,TaskStorage
andUserPrefStorage
, which means it can be treated as either one (if only the functionality of only one is needed). - depends on some classes in the
Model
component (because theStorage
component’s job is to save/retrieve objects that belong to theModel
)
3.6 Common classes
Classes used by multiple components are in the seedu.addressbook.commons
package.
4. Implementation
This section describes some noteworthy details on how certain features are implemented.
4.1 Feature implementations
4.1.1 Add Task feature
The implementation of the add task function is facilitated by LogicManager
. It takes user input depending on the task user wants to add.
- For a
todo
task, the user input consists of 2 arguments, the command word being “todo”. The second argument is a description of the task. - For a
deadline
task, the user input consists of 3 arguments, the command word being “deadline”. The second argument is a description of the task, and the third argument is the deadline of the task. - For an
event
task, the user input consists of 4 arguments, the command word being “event”. The second argument is a description of the task, the third argument is the start date of the task, and the fourth argument is the end date of the task.
The format is as follows:
todo task/TASK_DESCRIPTION
deadline task/TASK_DESCRIPTION by/DEADLINE
event task/TASK_DESCRIPTION from/START_DATE to/END_DATE
Given below is an example scenario and how the adding task function works at each step.
Step 1. The user executes todo task/organise pantry
command to add the task in Pied Piper. The command is read by LogicManager
, which parses the user’s input into a commandText
.
Step 2. LogicManager
then calls parseCommand
on the commandText in AddressBookParser
.
Step 3. AddressBookParser
then uses Matcher
to group the commandText into commandWord
and arguments
.
Step 4. A ToDoCommandParser
is created, which generates a new toAdd:Task
and a new ToDoCommand
.
Step 5. LogicManager
then calls execute
in ToDoCommand
, which carries out the addition if the task is valid. It then returns a CommandResult
to be displayed to the user to acknowledge whether the addition has taken place.
Similarly, the above implementation applies to deadline
and event
tasks but with different arguments.
Note:The command can only work if a task with the same description is not already present in Pied Piper. Additionally, the above implmentation comes with the edittask
feature, which allows the user to edit the details of a task in the task book.
The following sequence diagram shows how the addition operation works for a TodoTask
:
The following sequence diagram shows how the addition operation works for a DeadlineTask
:
4.1.2 Add Person feature
The implementation of the add person function is facilitated by LogicManager
. It takes user input as 5 arguments, the command word being either add
. The second argument is the name
, the third argument is the phone number
, the fourth argument is the email
, and the fifth argument is the address
. The role
argument is optional and can be added by adding the argument r/ROLE
.
The format is as follows:
add n/NAME p/PHONE e/EMAIL a/ADDRESS [r/ROLE]
Given below is an example scenario and how the adding person function works at each step.
Step 1. The user executes add n/Jane Roe p/98123456 e/janer@nus.com a/Jane street, block 321 r/Member
command to add the person in Pied Piper address book. The command is read by LogicManager
, which parses the user’s input into a commandText
.
Step 2. LogicManager
then calls parseCommand
on the commandText in AddressBookParser
.
Step 3. AddressBookParser
then uses Matcher
to group the commandText into commandWord
and arguments
.
Step 4. A AddCommandParser
is created, which generates a new toAdd:Person
and a new AddCommand
.
Step 5. LogicManager
then calls execute
in AddCommand
, which carries out the addition if the person details aer valid. It then returns a CommandResult
to be displayed to the user to acknowledge whether the addition has taken place.
Note:The command can only work if a task with the same details is not already present in Pied Piper. Additionally, the above implmentation comes with the edit
feature, which allows the user to edit the details of a person in the address book.
The following sequence diagram shows how the addition operation works:
4.1.3 Delete/deletetask feature
The implementation of the delete/deletetask function is facilitated by LogicManager
. It takes user input as 2 arguments, the command word being either delete
or deletetask
, depending on whether the user wants to delete a person or task respectively. The second argument is an index, denoting the index of the person or task the user wishes to delete.
The format is as follows:
delete PERSON_INDEX
deletetask TASK_INDEX
Given below is an example scenario and how the delete function works at each step.
Step 1. The user executes deletetask 1
command to delete the 5th task in Pied Piper. The command is read by LogicManager
, which parses the user’s input into a commandText
.
Step 2. LogicManager
then calls parseCommand
on the commandText in AddressBookParser
.
Step 3. AddressBookParser
then uses Matcher
to group the commandText into commandWord
and arguments
.
Step 4. A DeleteTaskCommandParser
is created, which generated a new DeleteTaskCommand
.
Step 5. LogicManager
then calls execute
in DeleteTaskCommand
, which carries out the deletion if the task exists. It then returns a CommandResult
to be displayed to the user to acknowledge whether the deletion has taken place.
Note:The command can only work if there is at least 1 person or task present in Pied Piper, and the specified index must not be greater than the index of the last item on the list. In case of deleting a person, all the tasks assigned to that particular person must be handled (unassigned). The same sequence as above applies to the deletion of a person from address book, but the following classes are different:
-
DeleteTaskCommandParser
→DeleteCommandParser
-
DeleteTaskCommand
→DeleteCommand
The following sequence diagram shows how the delete operation works:
4.1.4 Assign Task feature
The implementation of the assign function is facilitated by LogicManager
. It takes user input as 3 arguments,
the command word being assign
. The second argument is an task index, denoting the index of task the user wishes to assign.
The third argument is an person index, denoting the index of the person the task is supposed to be assigned.
The format is as follows:
assign t/TASK_INDEX i/PERSON_INDEX
Given below is an example scenario and how the assign function works at each step.
Step 1. The user executes assign t/1 i/2
command to assign the first task in Pied Piper to second person in the address book.
The command is read by LogicManager
, which parses the user’s input into a commandText
.
Step 2. LogicManager
then calls parseCommand
on the commandText in AddressBookParser
.
Step 3. AddressBookParser
then uses Matcher
to group the commandText into commandWord
and arguments
.
Step 4. A AssignTaskCommandParser
is created, which generated a new AssignTaskCommand
.
Step 5. LogicManager
then calls execute
in AssignTaskCommand
, which carries out the functionality of the command.
This method creates a new Task
object with the same description as the task to be assigned, but with the person assigned to it.
This new instance of Task
is then replaced with the existing instance in the UniqueTaskList
in TaskBook
.
It then returns a CommandResult
to be displayed to the user to acknowledge whether the assignment has taken place.
Note:Multiple tasks can be assigned to a single person. The command can only work if the person to be assigned has been given a role.
The following sequence diagram shows how the assignment operation works:
4.1.5 Mark/Unmark Task feature
The implementation of the mark function is facilitated by LogicManager
. It takes user input as 3 arguments,
the command word being mark
. The second argument is an task index, denoting the index of task the user wishes to mark as complete.
The third argument is an score, denoting the score of the task alloted by the leader.
On the other hand, the implementation of the unmark function takes user input as 2 arguments,
the command word being unmark
. The second argument is an task index, denoting the index of task the user wishes to mark as incomplete.
The format is as follows:
mark t/TASK_INDEX s/PERFORMANCE_SCORE
unmark t/TASK_INDEX
Given below is an example scenario and how the mark function works at each step.
Step 1. The user executes mark t/1 s/3
command to mark the first task in Pied Piper as complete with a score of 3.
The command is read by LogicManager
, which parses the user’s input into a commandText
.
Step 2. LogicManager
then calls parseCommand
on the commandText in AddressBookParser
.
Step 3. AddressBookParser
then uses Matcher
to group the commandText into commandWord
and arguments
.
Step 4. A MarkCommandParser
is created, which generated a new MarkCommand
.
Step 5. LogicManager
then calls execute
in MarkCommand
, which carries out the functionality of the command.
This method creates a new Task
object with the same description as the task to be marked, but with the status marked as complete.
This new instance of Task
is then replaced with the existing instance in the UniqueTaskList
in TaskBook
.
It then returns a CommandResult
to be displayed to the user to acknowledge whether the task has been marked as complete.
Note:Any task cannot be marked if it not assigned to a person. Additionally, the user can mark the task again to give a different score. The score will be updated to the new score. The implemention of the unmark function is similar to the mark function, except that the status of the task is marked as incomplete.
The following sequence diagram shows how the mark/unmark operation works:
4.1.6 Review feature
The implementation of the mark function is facilitated by LogicManager
. It takes user input as 1 arguments,
the command word being review
.
The format is as follows:
review
Given below is an example scenario and how the review function works at each step.
Step 1. The user executes review
command to mark the first task in Pied Piper as complete with a score of 3.
The command is read by LogicManager
, which parses the user’s input into a commandText
.
Step 2. LogicManager
then calls parseCommand
on the commandText in AddressBookParser
.
Step 4. A ReviewCommand
is created.
Step 5. LogicManager
then calls execute
in ReviewCommand
, which carries out the functionality of the command.
This method goes through the UniqueTaskList
in TaskBook
and checks for any tasks that are marked as complete, or score is not given. After, it checks for any tasks that are assigned to a person and calculates the average score of the tasks assigned to each person.
It then returns a CommandResult
to be displayed to the user to acknowledge whether the averge score of each person has been calculated.
The following sequence diagram shows how the review operation works:
4.1.7 STATUS feature
The implementation of the status feature is facilitated by the setTaskStatus
method of TaskCard
.
It sets the STATUS UI element to a specific colour depending on the status of the task.
A sequence of steps are followed:
Step 1: Start
Step 2: colour is set to it’s default value: black.
Step 3: setTaskStatus
sets the colour to green if the task is marked as done. End.
Step 4: Otherwise it sets the colour to orange if the task is due today. End.
Step 5: Otherwise it sets the colour to red if the task is over due. End.
Step 6: If an error is thrown the colour is set to it’s default colour: black. End.
The following activity diagram shows how the colour is set:
4.2 Proposed implementation of future features:
Aspect: How to undo & redo executes:
-
Alternative 1 (current choice): Saves the entire address book.
- Pros: Easy to implement.
- Cons: May have performance issues in terms of memory usage.
-
Alternative 2: Individual command knows how to undo/redo by
itself.
- Pros: Will use less memory (e.g. for
delete
, just save the person being deleted). - Cons: We must ensure that the implementation of each individual command are correct.
- Pros: Will use less memory (e.g. for
Aspect: How to sort my tasks/members:
-
Proposed Implementation (current choice): Display a temporary list of tasks/members sorted by the user’s preference.
- Pros: Better user experience.
- Cons: Difficult to implement in terms of memory usage and different criterias for sorting.
5. Documentation, logging, testing, configuration, dev-ops
6. Appendix: Requirements
6.1 Product scope
Target user profile:
- University Students
- has a need to manage a project with significant complexity
- prefer desktop apps over other types
- can type fast
- prefers typing to mouse interactions
- is reasonably comfortable using CLI apps
Value proposition:
- Adding of various tasks with descriptions.
- Get an overview via the List view so that you can find the event that you need easily.
6.2 User Stories
Priorities: High (must have) - * * *
, Medium (nice to have) - * *
, Low (unlikely to have) - *
Priority | As a … | I want to … | So that I can… |
---|---|---|---|
* * * |
user | create tasks | keep track of the tasks I need to accomplish |
* * * |
user | delete tasks | remove tasks that are outdated or specified incorrectly |
* * * |
user | view each team member’s tasks | have a clear and easily understandable list of what they have to do |
* * * |
user | assign tasks | keep track of who is responsible for which task |
* * * |
user | assign roles | remember the responsibilities of each member |
* * * |
user | create tasks with a deadline | see the due date of the task easily |
* * * |
user | create tasks that are events | keep track of events we conduct as a group |
* * * |
user | comment on tasks | record my feedback for each accomplished task |
* * * |
user | mark a task as completed | have a clear view of what tasks are accomplished |
* * * |
user | unmark a task as uncompleted | undo any possible false marking of tasks |
* * * |
user | assign scores for each completed task | better evaluate overall performance of teammates |
6.3 Use cases
(For all use cases below, the System is Pied Piper
and the Actor is the user
, unless specified otherwise)
Use case 1: Add a person
MSS
- User requests to list persons
- Pied Piper shows a list of persons
- User requests to delete a specific person in the list
-
Pied Piper deletes the person
Use case ends.
Extensions
-
2a. The list is empty.
Use case ends.
-
3a. The given index is invalid.
-
3a1. Pied Piper shows an error message.
Use case resumes at step 2.
-
Use case 2: Create a task
MSS
- User requests to add a specific task in the list.
-
Pied Piper adds the task.
Use case ends.
Extensions
-
1a. The task already exists.
Use case ends.
-
1a. The given specifications are invalid.
-
1a1. Pied Piper shows an error message.
Use case resumes at step 2.
-
Use case 3: Delete a task
MSS
- User requests to delete a specified task in the list.
-
Pied Piper removes the task.
Use case ends
Extensions
-
1a. The list is empty.
Use case ends
-
1a. The given index is invalid.
-
1a1. Pied Piper shows an error message.
Use case resumes at step 2.
-
Use Case 4: view tasks
MSS
- User requests to view all tasks
-
Pied Piper displays all existing tasks as a numbered list
Use case ends
Extensions
- 1a. No existing tasks
-
1a1. Display message to user that there are no existing tasks
Use case ends
-
Use case: mark a task
MSS
- User requests to mark a specified task in the list with a score.
-
Pied Piper marks the task with a valid score.
Use case ends
Extensions
-
1a. The task is not assigned.
Use case ends
-
1a. The given index is invalid.
-
1a1. Pied Piper shows an error message.
Use case resumes at step 1.
-
6.4 Non-Functional Requirements
- Should work on any mainstream OS as long as it has Java
11
or above installed. - Should be able to hold up to 1000 persons without a noticeable sluggishness in performance for typical usage.
- A user with above average typing speed for regular English text (i.e. not code, not system admin commands) should be able to accomplish most of the tasks faster using commands than using the mouse.
- The response to any use action should become visible within 2 seconds.
- The user interface should be intuitive enough for users who are not IT-savvy.
6.5 Glossary
- Mainstream OS: Windows, Linux, Unix, OS-X
- Private contact detail: A contact detail that is not meant to be shared with others
7. Appendix: Instructions for manual testing
Given below are instructions to test the app manually.
7.1 Launch and shutdown
-
Initial launch
-
Download the jar file and copy into an empty folder
-
Double-click the jar file Expected: Shows the GUI with a set of sample 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.
-
7.2 Deleting a person
-
Deleting a person while all persons are being shown
-
Prerequisites: List all persons using the
list
command. Multiple persons in the list. -
Test case:
delete 1
Expected: First contact is deleted from the list. Details of the deleted contact shown in the status message. Timestamp in the status bar is updated. -
Test case:
delete 0
Expected: No person is deleted. Error details shown in the status message. Status bar remains the same. -
Other incorrect delete commands to try:
delete
,delete x
,...
(where x is larger than the list size)
Expected: Similar to previous.
-
-
{ more test cases … }
7.3 Saving data
-
Dealing with missing/corrupted data files
- {explain how to simulate a missing/corrupted file, and the expected behavior}
-
{ more test cases … }
7.3 Clearing people data
- Clearing data of all people while list of all people is being shown
-
Prerequisites: List all persons using the
list
command. -
Test case:
clear
Expected: Every person is removed. Status message is displayed.
-
7.4 Editing a person
- Editing details of person
-
Prerequisites: List all persons using the
list
command. Multiple persons on the list. -
Test case:
edit 1 n/James Lee e/jameslee@example.com
Expected: Person name and email is updated. Status message is shown. -
Test case:
edit 0 n/John Doe p/22224444
Expected: No person is edited. Error details are shown in the status message.
-