Developer Guide
- Setting up, getting started
- Design
- Implementation
- Extension Suggestions
- Documentation, logging, testing, configuration, dev-ops
- Appendix: Requirements
- Task: Something to be done for a project with a certain progress status.
- Appendix: Instructions for manual testing
Setting up, getting started
Refer to the guide Setting up and getting started.
Design
Architecture
Figure 1: Architecture Diagram of the application
The Architecture Diagram given above explains the high-level design of the App. Given below is a quick overview of each component.
.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.
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 User Interface of the App. -
Logic
: The command executor. -
Model
: Holds the data of the App in memory. -
Storage
: Reads data from, and writes data to, the hard disk.
Each of the four components,
- defines its API in an
interface
with the same projectName as the Component. - exposes its functionality using a concrete
{Component Name} Manager
class (which implements the corresponding APIinterface
mentioned in the previous point.
For example, the Logic
component (see the class diagram given below) defines its API in the Logic.java
interface
and exposes its functionality using the LogicManager.java
class which implements the Logic
interface.
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
, which deletes project 1.
The sections below give more details of each component:
Figure 2: Sequence Diagram of an example of a user input
UI component
Figure 3: Class Diagram of the UI component
API :
Ui.java
The UI consists of a MainWindow
that is made up of parts e.g.CommandBox
, ResultDisplay
, ProjectListPanel
,
StatusBarFooter
, ProjectDashboard
, EmptyDashboard
, TaskDashboard
, TeammateDashboard
etc. All these, including the MainWindow
, inherit from the abstract UiPart
class.
The UI
component uses 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.
Logic component
Figure 4: Class Diagram of the logic component
API :
Logic.java
-
Logic
component uses theMainCatalogueParser
class to parse the user command. - This results in a
Command
object which is executed by theLogicManager
(only commands with correct scope will be generated: refer to “Scoping feature”). - The command execution can affect the
Model
(e.g. adding a project). - The result of the command execution is encapsulated as a
CommandResult
object which is passed back to theUi
. - In addition, the
CommandResult
object can also instruct theUi
to perform certain actions, such as displaying help to the user.
Given below is the Sequence Diagram for interactions within the Logic
component for the execute("delete 1")
API call.
Figure 5: Sequence Diagram for “delete” input
DeleteCommandParser
should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram.
Model component
Figure 6: Class Diagram of the Model component
API : Model.java
The Model
,
- stores a
UserPref
object that represents the user’s preferences. - stores the main catalogue data, which is essentially a list of
Project
s, a list ofPerson
s, and a list of their associationsParticipation
s. - exposes unmodifiable
ObservableList<Project>
andObservableList<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. - keeps a status about the current status of the application which may affect the execution of commands.
- does not depend on any of the other three components.
Storage component
Figure 7: Class Diagram of the Storage component
API : Storage.java
The Storage
component,
- can save
Project
,Person
,Task
,Participation
objects and their details in json format and read it back. - can save the main catalogue data in json format and read it back.
Common classes
Classes used by multiple components are in the seedu.addressbook.commons
package.
Implementation
This section describes some noteworthy details on how certain features are implemented.
Logging of data
To record data, after each action, we used thejava.util.logging
package.
Logging implements several levels using to describe at a glance the severity of the message. This allows developers to identify the message at a glance.
The log level is set to INFO
by default, but can be modified to any other level with the use of the setter
method setLogLevel
.
Logging levels
- SEVERE (events that are of considerable importance and which will prevent normal program execution.
They should be reasonably intelligible to end users and to system administrators.) - WARNING (may cause issues, proceed with caution)
- INFO (should be used for reasonably significant messages that will make sense to end users and system administrators.)
There are many other logging levels available in the Level class, however these above should be sufficient.
Scoping feature
Implementation
The scoping mechanism is facilitated by an enum
class Status
in MainCatalogue
. Possible values of Status
are PROJECT_LIST
, PERSON_LIST
, PROJECT
, PERSON
, TASK
, and TEAMMATE
.
The possible values of Status
corresponds to a UI status as follows:
Scope | Left panel | Middle panel | Right panel |
---|---|---|---|
PROJECT_LIST |
project list | empty | empty |
PERSON_LIST |
person list | empty | empty |
PROJECT |
project list | project dashboard | empty |
PERSON |
person list | person dashboard | empty |
TASK |
project list | project dashboard | task dashboard |
TEAMMATE |
project list | project dashboard | teammate dashboard |
As per in the description above, can understand the scopes using the hierarchy as follows:
- global
-
PROJECT_LIST
-
PROJECT
TASK
TEAMMATE
-
-
PERSON_LIST
PERSON
-
In most cases a command that is valid in a parent scope would be valid in any descendant scopes, but there may be some exceptions.
The Status
of MainCatalogue
is open to be accessed in other Model
components by a public getter. The MainCatalogue
has a field project
which is an Optional
object of Project
.
This is a pointer to the project that is expected to be the focus for the application if it is in the PROJECT
or lower status. Similarly, there is a pointer in each Project
to keep the task of focus if the application is in TASK
status.
The switch of Status
is implemented by the following operations:
-
MainCatalogue#enter(Project project)
— Switches toPROJECT
status and updates the project on view to the given project. -
MainCatalogue#enter(Person person)
— Switches toPRERSON
status and updates the project on view to the given project. -
MainCatalogue#enterTask(Task task)
— Switches toTASK
status and updates the task on view to the given task. -
MainCatalogue#enterTeammate(Participation teammate)
— Switches toTEAMMATE
status and updates the teammate on view to the given teammate (participation). -
MainCatalogue#quit()
— Switches to the parent status, and clear the lower-level pointer.
These operations are exposed in Model
interface with the same name.
In the GUI design of the application, the three columns correspond to three levels of the status.
The left column refers to the top level, which is PROJECT_LIST
or PERSON_LIST
, and it thus consists of a list of projects or persons.
The middle column refers to the middle level, which can be PROJECT
or PERSON
, and it shows the details of the project or person of focus as stored in MainCatalogue
.
The right column refers to the bottom level, which can be TASK
or TEAMMATE
, and it shows the details of the object this status refers to that is of focus as stored in its parent object (project or person).
Users are allowed to switch the scoping status while using the app using user input commands. Relevant commands include:
-
ListProjectsCommand
— Requests to view the list ofProject
s. -
ListPersonsCommand
— Requests to view the list ofPerson
s. -
StartProjectCommand
— Enters a project with its index in the current filtered list of projects and switches toPROJECT
status. This corresponds toenter
method with input typeProject
. -
StartPersonCommand
— Enters a person with its index in the current filtered list of persons and switches toPERSON
status. This corresponds toenter
method with input typePerson
. -
ViewTaskCommand
— Requests to view the detailed information of a task. This corresponds toenterTask
method. -
ViewTeammateCommand
— Requests to view the detailed information of a teammate (which is represented by participation). This corresponds toenterTeammate
method. -
LeaveCommand
— Leaves the current object of focus, i.e. Switches to the parent status and clear the lower-level pointer. This corresponds toquit
method.
All commands have a restriction on the scope. This is seen in CommandParser
. If a command is invoked but the application is not in the correct scoping status, an InvalidScopeException
would be thrown and an error message would be shown on the GUI.
Step 1. The user launches the application. The default status of scope is PROJECT_LIST
, and project
in MainCatalogue
is initialized to an empty Optional
object.
(The person
in MainCatalogue
is also initialized to be empty, and all behaviors under PERSON_LIST
scope would be very similar to PROJECT_LIST
, so relevant behaviors will not be repeated in this document.)
Figure 8: Diagram of the initial scoping
PROJECT_LIST
level cannot be executed.
The following sequence diagram shows how scoping works in the application.
Figure 9: Sequence Diagram of the scoping components with an input
Step 2. The user executes startproject 3
command to view the details of the project of index 3 in the main catalogue. The startproject
command
calls enter
, causing a switch of scoping status and assignment of project
of focus in MainCatalogue
.
Figure 10: Diagram of the scoping after ‘startproject 3’ command
startproject
command calls enter
method in model, causing a switching of level and updates the project of focus.
The following sequence diagram shows the execution of startproject command.
Figure 11: Sequence Diagram of the ‘startproject’ command
Step 3. The user executes viewtask 5
command to view the details of the task of index 5 in the filtered task list of current project.
The viewtask
command calls enterTask
, causing a switch of scoping status and assignment of taskOnView
in the current project.
(viewteammate
command is executed similarly.)
Figure 12: Diagram of the scoping after ‘viewtask 5’ command
viewtask
command calls enterTask
method in model, causing a switching of level and updates the task of focus.
The following sequence diagram shows the execution of view task command.
Figure 13: Sequence Diagram of the ‘viewtask’ command
Step 4. The user executes startproject 2
command to view details of project of index 2 in the current list of projects instead.
The scope is switched to PROJECT
, project of focus is updated to a new project and the task on view is updated to empty.
Figure 14: Diagram of the scoping after ‘startproject 2’ command
Step 5. The user executes leave
command to go to the parent status.
Currently the application is at PROJECT
status, so after execution of leave
command, the new status would be PROJECT_LIST
.
The leave
command calls quit
method.
Figure 15: Diagram of the scoping after ‘leave’ command
leave
command calls quit
method in model, causing a switching of level and updates the project and task of focus.
The following sequence diagram shows the execution of leave command. Note that the leave command will do nothing if the application is already in the PROJECT_LIST
scope.
Figure 16: Sequence Diagram of the ‘leave’ command
The following activity diagram summarizes the scoping features when a user executes a new command:
Figure 17: Activity Diagram of the scoping components
Design consideration:
Aspect: How to check scope
-
Alternative 1 (current choice): Parses a command only if the scoping is valid.
- Pros: Easy to implement.
- Cons: May increase coupling because parser needs to know the status.
-
Alternative 2: Checks the validity of scope of a command upon execution.
- Pros: Will not increase coupling with parser.
- Cons: The scoping features of each command are not explicitly seen, and may increase coupling with command.
Aspect: How to establish hierarchy of scopes
-
Alternative 1 (current choice): Use a hierarchy scheme to define scopes, and all scoping status at the same level are strictly restricted to its parent scope.
- Pros: Only need one status field in
Model
, and easy to extend. - Cons: When lower levels of
PERSON
is implemented, child scopes ofPROJECT
likeTASK
might be reused, but it is not easy to implement this.
- Pros: Only need one status field in
-
Alternative 2: Keeps a status for every level.
- Pros: Do not need a hierarchy understanding of all scopes anymore, and will solve the duplication problem in alternative 1.
- Cons: Need several status field in
Model
, which may make the code more complicated and harder to extend.
New Task feature
Implementation
The implementation of the task feature involves adding new tasks created in the Project
class and storing them with a JsonAdaptedTask
class which is contained by the JsonAdaptedProject
class.
The new task command has to be prefixed with ‘addtask’ and include some of the following fields:
-
tn/
prefix followed by the name of the Task -
tp/
prefix followed by the percentage of the task that has been finished -
d/
prefix followed by a description of the task (Optional) -
td/
prefix followed by the deadline of the task (Optional)
The system validates each field upon entry by the user, and failing the validation, will display to the user that the command failed, and requesting the user to try again.
Given below is an example usage scenario of how the add task mechanism behaves at each step.
After entering the project scope of a chosen project, the user enters the command to add a new task such as “addtask tn/Create Person class tp/25 td/9-11-2020 00:00:00”.
The command text is passed into LogicManager
(an implementation of Logic) which passes the raw text into the MainCatalogueParser
to validate the first command word, which in this case is addtask
. A new instance of AddTaskCommandParser
class is then created which proceeds to parse the various fields of the command. Any invalid fields such as invalid field prefixes or invalid format of data would throw an exception at this stage.
If the fields are all valid, a new Task
object would be created and passed into the AddTaskCommand
class.
Within the AddTaskCommand
class, an instance of AddTaskCommand
is created, along with an instance of the task
is created in the same class and this instance of Command
is passed back to LogicManager
.
LogicManager then calls the method execute
of the AddTaskCommand
which stores the task into the respective project’s task list.
The diagram below summarises the events above with the help of a sequence diagram:
Figure 18: Sequence Diagram of the ‘addtask’ command
The diagram below gives a short overview on what happens when a user’s input is received:
Figure 19: Activity Diagram of the ‘addtask’ command
Design consideration:
Aspect: Whether a Task object can be instantiated without filling up all of its attributes
-
Alternative 1: All fields must be filled up
- Pros: No ambiguity regarding the task, all information of the task is standardised.
- Cons: The user may not know every aspect of a task such as the description.
-
Alternative 2 (current choice): Only some fields have to be filled up (i.e. name and progress)
- Pros: Task can be created without knowing all the information of a task.
- Cons: Users might forget to input a deadline or description for the task which might cause trouble for the user when sorting or filtering his/her tasks as the system would not inform them they had no input a deadline or description for the task.
Aspect: Whether all tasks in a project have to be unique
-
Alternative 1: Tasks in a project can be duplicated
- Pros: The user can keep the name of the task short and simple. For instance, two task could have the same name
Update UG
with differing task descriptions ofupdate UG with glossary
andupdate UG with FAQ
. - Cons: The user may be confused by the list of tasks with the same name and deadline or might have accidentally created two of the same task but only intended to create one.
- Pros: The user can keep the name of the task short and simple. For instance, two task could have the same name
-
Alternative 2 (current choice): A task is not allowed to be created with the same name and deadline as an existing task
- Pros: Tasks with the same name and deadline are very likely to be the same task and so will spare the user from accidentally keying in the same task twice.
- Cons: Tasks with the same name and deadline but with different descriptions are still not allowed to be created.
Filtering feature
Implementation
The task filtering mechanism is facilitated by the predicte taskFilter
kept in the Project class. When UI
component requested for the filtered and sorted task list, the task list filtered by the taskFilter
will be returned.
Tasks can be filtered by following attributes of a task (using command filter PREFIX/ATTRIBUTE
):
- the Github user name
gitUserName
of one of the task’s assignees (prefix:ta/
) - the task’s name:
taskName
(prefix:tn/
) - the task’s deadline:
deadline
(prefix:td/
) - the task’s progress:
progress
(prefix:tp/
) - whether the task is done:
isDone
(prefix:done/
)
Additionally, one can also use filter start/START_DATE end/END_DATE
to find tasks whose deadlines are within the time range between the START_DATE
and the END_DATE
.
The predicate used to filter tasks is generated in the TaskFilterCommandParser
and encapsulated by the TaskFilterCommand
that the paser returns. When the TaskFilterCommand
is executed, the taskFilter
of the current project will be updated and UI
will be refreshed automatically.
When the user want to clear the filter using alltasks
, the taskFilter
of the current project will be changed to a predicate that always returns true. Then, the UI
will correspondingly show all the tasks in the current project.
Given below is an example usage scenario and how the task filtering mechanism behaves at each step:
Step 1. The user uses startproject
to open a project called “Taskmania”. Suppose there are currently three tasks in this project: task1
, task2
, and task3
. There are three persons involved: a person named “Tan Chia Qian” whose Github username is “TCQian”, a person named “Tian Fang” whose Github username is “T-Fang” and a person named “Li Jiayu” whose Github username is “lll-jy”. task1
is assigned to “Tan Chia Qian” and “Tian Fang”, task2
is assigned to “Tian Fang”, and task3
is assigned to “Li Jiayu”.
Figure 20: Object Diagram of the project ‘Taskmania’
Step 2. The user executes filter ta/T-Fang
command to find all tasks that assigned to a “Tian Fang” whose Github username is “T-Fang”. the command is eventually passed to TaskFilterCommandParser
and the parser will identify the type of the filtering condition using the prefix entered and create the corresponding task predicate. In this case, ta/
indicates that a predicate that filter tasks by their assignees’ Github usernames should be created.
Step 3. The LogicManager
executes the TaskFilterCommand
returned by the parser. The TaskFilterCommand
will get the current project (“Taskmania”) from the Model
and update the taskFilter
predicate inside the “Taskmania” project. Therefore, the filtered task list of “Taskmania” will only contain task1
and task2
. Note that the commands related to task indices such as viewtask
now take in indecies with respect to the newly filtered list (e.g. viewtask 3
will show an error message as there are only two tasks in the filtered task list ).
Figure 21: Sequence Diagram of the ‘filter’ command
Step 4. After seeing tasks that have been assign to “Tian Fang”, the user wants to take a look at other tasks in “Taskmania”. The user executes alltasks
to see all the tasks in “Taskmania”. the MainCatalogueParser
parses the command and creates a AllTasksCommand
.
Step 5. The LogicManager
executes theAllTasksCommand
returned. The AllTasksCommand
will get the current project (“Taskmania”) from the Model
and call the showAllTasks()
method inside the “Taskmania” project. Then the taskFilter
inside “Taskmania” will be replaced by a predicate that always returns true and all the tasks will be shown.
Figure 22: Sequence Diagram of the ‘alltasks’ command
In the example above, the users can also filter the task list in different ways and the taskFilter
predicate in “Taskmania” will be updated correspondingly:
-
filter tn/Filter
:task2
andtask3
will be displayed -
filter tp/50
:task3
will be displayed -
filter done/false
:task1
andtask3
will be displayed -
filter td/19-10-2020 13:30:00
:task1
will be displayed -
filter start/16-10-2020 end/19-10-2020
:task1
andtask2
will be displayed
The following activity diagram summarizes what happens when a user executes a task filter command:
Figure 23: Activity Diagram of the filter command
Design consideration:
Aspect: Which attribute of assignees should be used to filter tasks
-
Alternative 1 (current choice): Assignee’s Github username
- Pros: Avoid viewing tasks of another person with the same personName. (Github username is unique)
- Cons: The user might not always remember the GitHub usernames of teammates.
-
Alternative 2: Assignee’s personName
- Pros: More intuitive when there are no teammates with the same name.
- Cons: If two teammates have the same name, the task filter by their name will display tasks that have been assigned to any of them.
Aspect: Whether to clear filter when user re-enters the project
-
Alternative 1 (current choice): Keep the filter and display filtered tasks when the user re-enters the project
- Pros: Task list remains unchanged (e.g. users don’t have to filter everytime they re-enter the same project if they only want to see tasks that are assigned to them) .
- Cons: Users might not be able to see all the tasks when they enter the project.
-
Alternative 2: Clear the filter when the user re-enters the project
- Pros: Users always gets to see all the tasks every time they enter the project.
- Cons: Users have to filter everytime they re-enters the same project if they only want to see tasks that are assigned to them.
New Person feature
Implementation
The implementation of New Teammate involves both the storing of the New Teammate in memory through the use of Participation
as well as storing the Teammate in the JSON file on the hard disk using the Storage
class.
The New Teammate created is added in the following places:
- global static variable
allPeople
in the Person class - within the project it was created for, in the associated Participation class
The New Teammate command has to be prefixed with addperson
and include all of the following fields:
-
mn/
prefix followed by the name of the new teammate -
mg/
prefix followed by the teammate’s Github User Name -
mp/
prefix followed by the phone number of the teammate -
me/
prefix followed by the email of teammate -
ma/
prefix followed by the address of the teammate - Each of the fields above is validated upon entry by the user, and failing the validation, will display to the user that the command failed, and requesting the user to try again.
The teammate can be created in any scope. However, if created in the project scope, it is added to that project to be
come a teammate. The following explanation will detail AddPerson
being executed in the project scope.
Once created in the project scope, the newly created person is added into that particular project. Further assignment of a user to other projects can be done in the scope of other projects.
Given below is an example usage scenario and how the AddPerson
mechanism behaves at each step:
Step 1: The user enters startproject 2
for example to start project 1 from the mainscreen.The user is greeted with the
projects list on the left, and the description of the project in the centre.
Figure 24: What the app looks like after ‘startproject 2’ command
Step 2: The user enters a AddPerson command such as addperson mn/John Ivy mg/Ivydesign98 mp/82938281 me/imjon@gmail
.com ma/13 Cupertino Loop
.
The command text is passed into LogicManager
(an implementation of Logic) which
passes the raw text into the MainCatalogueParser
to validate the first command word, which in this case is
addperson
. A new instance of AddPersonCommandParser
is then created which proceeds to parse the various
fields of the command. Any invalid fields such as invalid field prefixes or invalid format of data would throw an exception at this stage.
If the fields are all valid, a new Person
object would be created in the same class and passed into the
AddPersonCommand
class.
Within the AddTeammateCommand
class, an instance of AddPersonCommand
is created, along with an instance of the
teammate created in the same class and this instance of Command
is passed back to LogicManager
.
LogicManager
then calls the method execute
of the NewTeammateCommand which stores the teammate into the respective
project’s participation list, and for the project to be stored in the teammate’s participation list.
While seeming to increase coupling, it however keeps both classes separate and would not break each other when something is changed.
The diagram below summarises what is happening above with the help of a sequence diagram:
Figure 25: Sequence Diagram of the ‘addperson’ command
The diagram below gives a short overview on what happens when a user’s input is received:
Figure 26: Activity Diagram of the ‘addteammate’ command
Design consideration:
Aspect: Whether Teammate can be instantiated without filling up all attributes
-
Alternative 1 (current choice): All fields must be filled up
- Pros: No ambiguity about a teammate, every teammate’s information is standardised.
- Cons: The user may not know every aspect of a user such as his address, for example.
-
Alternative 2: Only some fields have to be filled up, such as gitUserName and name.
- Pros: Teammate can be created without knowing all information of a user.
- Cons: Contacting such teammates would be difficult as the user would not be pressed to enter the teammate’s phone number or address.
Aspect: Whether to take name as an attribute when gitUserName is already present as an attribute
-
Alternative 1 (current choice): Keep both name and gitUserName
- Pros: GitUserName may be something entirely different from the teammate’s name, and would be difficult for the user to identify if the user simply knew the teammate by his real name.
- Cons: The gitUserName exactly matches the teammate’s name, and the name field is irrelevant. However, this is generally quite rare.
-
Alternative 2: Only have gitUserName as an attribute.
- Pros: The user has one less attribute to enter when instantiating the teammate.
- Cons: If the gitUserName is very different from the teammate’s actual name, it may be difficult for the user to remember, as is often the case for gitUserNames.
Delete Person feature
Implementation
The implementation of DeleteTeammate involves both the deleting of the teammate in memory through the use of
Participation
, deleting from all projects the teammate is a part of, as well as deleting the Teammate in the JSON
file on the harddisk using the Storage
class.
The DeleteTeammate created is removed in the following places:
- global static variable
allPeople
in the Person class - within the project it added to, in the associated Participations.
The Delete Teammate command has to be prefixed with deleteperson
and include the following field:
-
mg/
prefix followed by the teammate’s Github User Name
The field above is validated upon entry by the user, and failing the validation, will display to the user that the command failed, and request the user to try again.
Delete Teammate is also performed in the scope of ListPersons
.
Given below is an example usage scenario and how the DeletePerson
mechanism behaves at each step:
Step 1: The user enters listpersons
for example to list all persons from the mainscreen.The user is greeted with the
projects list on the left, and the description of the project in the centre.
Figure 27: What the app looks like after ‘listpersons’ command
Step 2: The user enters a DeleteTeammate command such as deleteperson GeNiaaz
. The command text is passed into
LogicManager
(an implementation of Logic) which
passes the raw text into the MainCatalogueParser
to validate the first command word, which in this case is
deleteperson
. A new instance of DeletePersonParser
class is then created which proceeds to parse the various
fields of the command. Any invalid fields such as invalid field prefixes or invalid format of data would throw an
exception at this stage.
To illustrate, the object diagram below shows the how Project and Person classes are related to each other, through the use of an association class Participations.
How Project and Person are associated
Project
and Person
cannot be directly linked, and hence are related in this manner to allow the Participation
class to
handle the association. If the instance of Participation
is deleted for example, the Project
and Person
can still
exist, without an association between them.
If the Git Username is valid, the allPeople
list in Person (which is a list of all persons, stored as a static
variable in Person class) would be searched for a teammate with a matching Git Username and deleted from the list
. All projects would also be searched for instances of participation with a teammate with a matching Git Username
and removed.
Within the DeletePersonCommand
class, an instance of DeletePersonCommand
is created, and this instance of
Command
is passed back to LogicManager
.
LogicManager then calls the method execute
of the DeletePersonCommand which deletes instances of itself in
all instances of participation as well as in memory and storage.
Design consideration:
Aspect: Which scope deletion of a teammate should happen in.
-
Alternative 1 (current choice): Deletion should happen in the listperson scope.
- Pros: All teammates can be viewed at once, and one can be selected for deletion there.
- Pros: Teammate can be deleted even if all associations deleted from all projects.
- Cons: The user has to navigate to another menu to delete the teammate.
(While it does indeed require the user to change scope to delete a teammate, deleting a teammate is not something the user will be doing regularly, and so we believe the pros outweigh the cons in this case.)
-
Alternative 2: Deletion should happen in the project scope.
- Pros: A teammate can be deleted quickly.
- Cons: It would be impossible to delete a teammate if all associations are deleted.
- Cons: User would have to know which project the teammate is associated and navigate there to delete it.
Extension Suggestions
Person management
Current implementation in the project:
Call listpersons
and startperson
command to start the view of Person
dashboard, which summarizes the information of this person, including the projects, tasks that this person involved in.
Extension features:
Allow for more manipulations on persons after entering the view of Person
dashboard, including filtering tasks, viewing task dashboards, etc.
Extension guidelines:
The behaviors of managing persons would be similar to the behaviors of managing projects. Thus, it is possible to reuse the commands that are set for PROJECT
or lower scope. There are two suggested approaches:
- Duplicate the relevant commands in
PROJECT
scope to make them available inPERSON
scope. - Change the scoping requirement of existing
PROJECT
scope commands and change the behavior to accommodate both scopes.
Teammate comparing
Current implementation in the project:
Call viewteammate
to view one teammate and call it again to view another.
Extension features: Allow for multiple teammates to be viewed side by side to compare qualifications and other characteristics to determine who is most suitable for a project.
Extension guidelines: The behaviour of comparing teammates would be akin to seeing 2 teammates side by side. In this scenario, each teammate would have more attributes such as experience, educational qualifications etc.
The teammates displayed side by side would be compared attribute by attribute to allow the user to see at a glance which teammate to pick for a project easily.
More records for projects and persons
Current implementation in the project:
The key of the application lies in Participation
, the association class of Person
and Project
.
The app now allows a list of Tasks
for each Participation
, but there are many other attributes possible for Participation
.
Extension features:
It is possible to add more realistic records for Participation
. They would basically fall in the two categories:
- Single attribute for each
Participation
, such asRole
. - Collective attribute for each
Participation
, such asMeetings
.
Extension guidelines:
For single attributes, future developers may simply add a field in the Participation
class and add relevant manipulation methods.
They can also create a new class for this attribute if it is complicated.
For collective attributes, future developers may refer to how Task
is implemented.
Basically, it would require future developers to create a new class of this attribute and keep a list in either the Participation
, Person
or Project
.
Other relevant tasks would need to be done, including adding commands (and parsers if needed), creating dashboards of these attributes, and making higher-level commands (such as filter, edit, etc.) to accommodate the new attributes.
More task implementation
Current implementation in the project:
The implementation of task is very fundamental currently, and are mostly very general such as add, edit, view, delete, and filter.
The attributes of Task
are very simple, too, which includes only a deadline and progress in addition to basic information such as name and description.
Extension features:
It is possible to allow advanced Task
management, such as allowing recurring of tasks.
This may also be done for other collective attributes that are newly added.
Extension guidelines:
Create new fields and methods in Task
class and implement relevant commands.
Custom attributes for projects and persons
Current implementation in the project: All attributes are hardcoded in the app, and are determined by developers.
Extension feature: It is possible to allow the users to create custom attributes for projects and persons.
Documentation, logging, testing, configuration, dev-ops
Appendix: Requirements
Product scope
Target user profile: team leaders who are managing software projects:
- has a growing number of projects and teammates to manage
- prefers desktop apps over mobile apps
- can type fast and prefers typing to mouse interactions
- is tech-savvy and reasonably comfortable using CLI apps
Value proposition: manage projects, teammates, and tasks on a unified platform as opposed to scattered on different messaging platforms
User stories
Priorities: High (must have) - * * *
, Medium (nice to have) - * *
, Low (unlikely to have) - *
Priority | As a … | I want to … | So that I can … |
---|---|---|---|
* * |
new user | see usage instructions | refer to instructions when I forget how to use the App |
* * * |
project team leader | add a project | |
* * * |
project team leader | add a new person | |
* * * |
project team leader | edit a person | change details of a person |
* * * |
project team leader | add a teammate to another project | have a teammate in multiple projects |
* * * |
project team leader | remove a teammate from a project | remove a teammate when he leaves a project |
* * * |
project team leader | delete a person | remove a person that will never collaborates again |
* * |
project team leader | view projects of a teammate | assess a specific teammate’s workload |
* * |
project team leader | view a dashboard of tasks my project | see at a glance what needs to be done for a project |
* * * |
forgetful user | add in teammate’s information | keep track of my teammate’s contact information |
* * * |
fast typing user | use a Command line type Interface | have higher efficiency when managing my team’s workload |
Use cases
System: Project Profile Tracking System (PTS)
Use Case: UC1 - Create New Project
Actor: User
MSS:
- User creates a new project profile.
- PTS asks for the details of project such as
projectName
,deadline
,repoUrl
andprojectDescription
. - User keys in the details.
-
PTS stores the project profile into the data file.
Use case ends.
Extensions
- 3a. The given details are not valid.
- 3a1. PTS shows an error message.
Use case resumes at 3.
Use Case: UC2 - Edit Existing Project Profile
Actor: User
MSS:
- User chooses to edit a project profile.
-
Same as UC1 2-4.
Use case ends.
Extensions
- 1a. The project profile does not exist.
- 1a1. PTS shows an error message.
User case resumes at 1.
System: Teammates Tracking System (TMTS)
Use Case: UC3 - Add A Person
Actor: User
MSS:
- User creates a new person’s profile.
- TMTS asks for the details of the person such as
personName
,phone
,email
, andgitUserName
. - User keys in the details.
-
TMTS stores the person’s profile into the data file.
Use case ends.
Extensions
- 3a. The given details are not valid.
- 3a1. TMTS shows an error message.
Use case resumes at 3.
Use Case: UC4 - Edit An Existing Person
Actor: User
MSS:
- User chooses to edit a person’s profile.
- PTS asks for the
gitUserName
of the person whose profile is to be edited. - User keys in the
gitUserName
of the person. -
Same as UC3 2-4.
Use case ends.
Extensions
- 3a. Person with the given
gitUserName
does not exist.- 3a1. TMTS shows an error message.
User case resumes at 3.
System: Project Management System (PMS)
Use case: UC5 - Start A Project
Actor: User
MSS:
- User requests to find a project.
- PMS shows a filtered list of projects according to the conditions of the project to find given by the User.
- User requests to start a target project with its index.
-
PMS shows the dashboard of the project.
Use case ends.
Extensions
- 1a. The conditions result in an empty filtered list of projects.
- 1a1. PMS shows an error message.
Use case resumes at 1.
- 3a. The index is not valid.
- 3a1. PMS shows an error message.
Use case resumes at 3.
-
3b. The project has already been shown on the dashboard.
Use case ends.
Use case: UC6 - Find A Task
Precondition: The application has already started a project.
Actor: User
MSS:
- User requests to find a task.
- PMS asks for specifications for filtering.
- User provides details of the task wanted such as
taskName
,description
, andassignee
s. -
PMS shows the list of filtered tasks with given specifications.
Use case ends.
Extensions:
-
4a. Task wanted is not in the filtered list.
Use case resumes at 3.
Use case: UC7 - Add A New Task
Precondition: The application has already started a project.
Actor: User
MSS:
- User requests to add a task in a project.
- PMS asks for details of the task such as
taskName
, anddeadline
. - User keys in details.
- PMS stores the task’s profile into the data file.
- User UC6: finds the task just added.
- PMS shows a filtered list of task including the new task added.
- User requests to assign the task to a teammate.
- PMS associates the task with the teammate and stores in the data file.
-
Repeat 7-8 until all assignees have been added.
Use case ends.
Extensions
- 3a. The given details are not valid.
- 3b1. PMS shows an error message.
Use case resumes at 3.
-
5a. The task is intended for no assignees.
Use case ends.
-
5b. The task can be easily found in the current list.
Use case resumes at 7.
- 7a. The input task index is invalid or the teammate is not found in the project.
- 7a1. PMS shows an error message.
Use case resumes at 7.
- 7b. The task has already been associated with the teammate.
- 7b1. PMS shows an error message.
Use case resumes at 9.
Use Case: UC8 - View Task Details
Actor: User
Precondition: The application has already started a project.
MSS:
- User UC6: finds the task wanted.
- PMS shows a filtered list of task including the new task added.
- User requests to view the task.
- PMS asks for the task index.
- User keys in the task index.
-
PMS shows the profile of the task.
Use case ends.
- 5a. The given task number is not found.
- 5a1. PMS shows an error message.
Use case resumes at 5.
Use case: UC9 - Delete A Task
Precondition: The application has already started a project.
Actor: User
MSS:
- User UC6: finds the task wanted to be deleted.
- PMS shows a filtered list of task including the new task added.
- User requests to delete the task.
- PMS asks for the task index.
- User keys in the task index.
-
PMS deletes the task in the project and updates the data file.
Use case ends.
Extensions
- 5a. The given task number is not found.
- 5a1. PMS shows an error message.
Use case resumes at 5.
Non-Functional Requirements
- The application should work on any mainstream OS (tested on Windows, Mac, Linux) as long as it has Java
11
or above installed. - The application should be able to hold up to 30 projects and 150 teammates without a noticeable drop in performance.
- The application can function without an internet connection.
- 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.
- There are checks for the inputs the user gives, and corresponding tips are presented if the input format is incorrect.
- There are
help
commands to tell the user what command does what. - Information is presented in a pleasing way.
- New user can learn the software easily and quickly (so that other teammates can help organize or add tasks if they want to)
- Tests are written for important components, and every working prototype must pass all the test first.
- Code is written in an easy-to-maintain manner (e.g. no extremely long function).
Glossary
- Mainstream OS: Windows, Linux, Unix, OS-X.
- Participation: The class of an object that handles the relations between a Project object and Person Object.
- Scope: The confines of when certain commands will work.
- Teammate: A member of the user’s team in a project.
- Person: A person that could be in any number of the user’s team’s projects.
- Project: A software project with a GitHub repository link and a deadline.
-
Task: Something to be done for a project with a certain progress status.
Appendix: Instructions for manual testing
Given below are some instructions to test Taskmania manually.
Launch and shutdown
-
Initial launch
-
Download the jar file and copy into an empty folder
-
Double-click the jar file Expected: Shows the GUI contains of three columns. The leftmost column contains command box, a result display box, and a set of sample projects. The middle column shows a project dashboard while the rightmost column shows a task or teammate dashboard.
-
-
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.
-
Deleting a project
-
Deleting a project while all projects are being shown
-
Prerequisites: List all projects using the
list
command. Multiple projects 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 project 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.
-
Adding a Teammate
- Adding a teammate into a project while in a project scope
-
Prerequisites: Have a valid project created, and start it using
startproject
. -
Test case:
addteammate mn/Lucas mg/LucasTai98 mp/93824823 me/lucas@gmail.com ma/18 Evelyn Road
Expected: A new teammmate is added to project 1. “New Teammate added: LucasTai98” message is returned to the user. -
Test case:
addteammate
Expected: No teammate added to the project. Error details about incorrect format shown to user. . -
Other incorrect delete commands to try:
addteammate mn/%&
,add teammate ...
, where the input is incomplete or the command is incorrect.
Expected: Similar to previous.
-
Deleting a Teammate from listpersons scope
- Deleting a teammate while in listpersons view
-
Prerequisites: Have a valid teammate created as described just above, and enter listpersons scope with
listpersons
. - Test case:
deleteteammate LucasTai98
Expected: A teammate is deleted. Teammate is deleted and all participations in projects are deleted as well . Message is returned to the user to tell the user deletion was a success. -
Test case:
deleteteammate 2
Expected: No teammate is deleted. Error details about incorrect format shown to user. - Other incorrect delete commands to try:
deleteteammate
,delete teammate ...
, where the input is incomplete or the command is incorrect.
Expected: Similar to previous.
-
Editing a Teammate from project scope
- Editing a teammate while in a project’s view
-
Prerequisites: Have a valid teammate in a project created as described just above, and enter project scope with
startproject 1
. - Test case:
editteammate LucasTai98 mn/Wiener
Expected: Teammate’s name is changed to Wiener, everything else, including the GitUserName, is changed . Feedback to the user tells the user it is successful. -
Test case:
editteammate LucasTai98
Expected: No teammate is edited. Taskmania complains that no data to change the attributes of Teammate were included. - Other incorrect delete commands to try:
editteammate
,editteammate $%%v
, where the input is incorrect or .
Expected: Similar to previous.
-
Saving data
-
Dealing with missing/corrupted data files
-
Test case: Delete maincatalogue.json to simulate a missing data file.
Expected: A new maincatalogue.json is created with default projects and persons. -
Test case: Delete “Participations” from maincatalogue.json.
Expected: Taskmania will start with an empty maincatalogue.json with no default projects and persons.
-
Adding a Task
- Adding a task into a project while in a project scope
- Prerequisites: Have a valid project created, and start it using
startproject
.
- Prerequisites: Have a valid project created, and start it using
- Test case:
addtask tn/Refactor Person class tp/0
Expected: A new task is added to project 1. “New task added: [Refactor Person Class]” message is returned to the user.- Test case:
addtask
Expected: No task added to the project. Error details about incorrect format shown to the user. . - Other incorrect delete commands to try:
addtask tn/%&
,add teammate ...
, where the input is incomplete or the command is incorrect.
Expected: Similar to previous.
- Test case:
Deleting a task
-
Deleting a task while in a project
- Prerequisites: Have a valid project created, and start it using
startproject
- Prerequisites: Have a valid project created, and start it using
-
Test case:
deletetask 1
Expected: First task is deleted from the task list. Name of the deleted task shown to the user. If the user was viewing the task’s details usingviewtask
, the task detail panel will close as the task is now deleted.- Test case:
deletetask 0
Expected: No project is deleted. Error details about incorrect format shown to the user. - Other incorrect delete commands to try:
deletetask
,deletetask x
,...
(where x is larger than the task list size)
Expected: Similar to previous.
- Test case: