By: CS2113-T13-1
Since: Aug 2019
Licence: MIT
Team leaders often face problems managing multiple projects, especially software development projects where the usage of a Kanban board is common.
Having to manage multiple Kanban boards for each individual project is a huge hassle for team leaders. As such, ArchDuke solves this issue by allowing team leaders to manage
-
Team members
-
ArchDuke allows users to assign tasks to team members, and track their workload, progress on tasks, and contributions.
-
-
Tasks in a group project
-
ArchDuke allows users to track multiple tasks within a project. Tasks can be created and assigned to members.
-
ArchDuke tracks the deadlines and priority levels of tasks, to help the user organise which tasks should be assigned and completed.
-
-
Multiple group projects
-
ArchDuke allows users to track multiple group projects. New group projects can be created and a default Kanban board will be created for users to start adding tasks.
-
Revision Date | Summary of Changes |
---|---|
11 November 2019 |
Version 1.9: Finalised Developer Guide with Instructions for Manual Testing |
10 November 2019 |
Version 1.8: Included Class Diagrams for Storage layer and Repository layer |
9 November 2019 |
Version 1.7: Added more documentation regarding implementation of Assignment |
8 November 2019 |
Version 1.6: Added documentation regarding CI and Code Quality |
5 November 2019 |
Version 1.5: Small updates to AssignmentController and reorganising content |
1 November 2019 |
Version 1.4: Added documentation on Reminder and logging functionality |
31 October 2019 |
Version 1.3: Added documentation for Member and Tasks functionality |
30 October 2019 |
Version 1.2: Added documentation on UI functionality |
25 October 2019 |
Version 1.1: Added documentation on implementation design for Assignment |
23 October 2019 |
Version 1.0: Added documentation on implementation design for AssignmentController and Project functions |
22 October 2019 |
Version 0.9: Updated Architecture Design |
15 October 2019 |
Version 0.8: Updated the name of project from Duke to ArchDuke |
2 October 2019 |
Version 0.7: Updated Prerequisites and removed unwanted lines |
30 September 2019 |
Version 0.6: Added table of contents, preface and document history |
26 September 2019 |
Version 0.5: Updated use cases for a cleaner look |
24 September 2019 |
Version 0.4: Added Non-functional Requirements to DeveloperGuide |
23 September 2019 |
Version 0.3: Added user stories to DeveloperGuide |
22 September 2019 |
Version 0.2: Added use cases to DeveloperGuide |
18 September 2019 |
Version 0.1: Creation of DeveloperGuide based on template |
-
JDK
11
or above is required -
IntelliJ IDE is recommended
Note
|
IntelliJ by default has Gradle plugin installed. Do not disable them.
If you have disabled them, go to File > Settings > Plugins to re-enable them.
|
-
Fork and clone the forked remote on your local machine.
-
Launch IntelliJ (If you’re not on the IntelliJ Welcome screen please close your existing project by going to
File
>Close Project
.) -
Set up the correct JDK version for Gradle
-
Click
Configure
>Structure for New Projects
-
Under
Project Settings
Click onProject
-
Under
Project SDK
ClickNew…
and point it to JDK 11 path. -
Click
OK
to save the configuration
-
-
Click
Import Project
-
Locate the
build.gradle
file and select it. ClickOpen
. -
Open the IntelliJ console/terminal and run the gradle command
gradlew processResource
on Windows or./gradlew processResource
on Mac/Linux
Note
|
(If you are encountered a permission error: ./gradlew: Permission denied add the executable permission to the
the shell script by running chmod 744 gradlew in your terminal)
It should finish with the BUILD SUCCESSFUL message. This will generate the resources required by the application and tests.
|
-
Run ArchDuke to verify and try a few commands. Do refer to the user guide for a list of commands to try out.
-
Run the JUnit Tests/gradlew test command to ensure that all the test case passes.
-
ArchDuke uses CheckStyle to check for code quality violations.
-
To configure your project to use CheckStyle, add
id 'checkstyle'
under plugins for yourbuild.gradle
file. -
Ensure that your CheckStyle toolVersion is 8.23 by adding
toolVersion = '8.23'
into yourbuild.gradle
file.
You may refer to ArchDuke’s build.gradlew
file as a reference on how to set up CheckStyle correctly.
ArchDuke utilizes Travis to perform Continuous Integration (CI). Other CI tools available are AppVeyor, GitLab CI or Github Actions. ArchDuke has decided on using Travis CI due to its ease of configurations.
In order to set up Travis CI, a .travis.yml
needs to be added in the root directory of your working directory.
For more details on how to configure your .yml
file, do refer to Travis documentation online, or ArchDuke’s
.travis.yml
file located
here
After setting up Travis, you can set up coverage reporting for your team fork. ArchDuke utilizes JaCoCo as test coverage tool and Coveralls as a web service to track our code coverage over time.
ArchDuke was implemented using the N-tier architecture approach. Having a N-tier application architecture helped s to flexibly create the application by segregating the application into tiers. Hence instead of reworking the entire application when the application is modified, we only had to rework the specific layer dealing with the modification. This approach also helped us in logically structuring the elements which made up ArchDuke. The Architecture Diagram given below explains the high-level design of ArchDuke.
Below is a quick overview of each component based on our Architecture.
Not included in the diagram is the Main
program in the folder launcher. The Main program is responsible for
initializing the View
layer and its subsequent dependencies.
-
In our case, as ArchDuke is a command line program,
Main
will initializeCLIView
.
Utility
layer represents a collection of classes used by multiple other components and can be accessed by all layers.
-
Factory
classes : Used mainly byRepositories
andControllers
to create objects based on user input.-
Examples of
Factory
classes used in ArchDuke areMemberFactory
,ProjectFactory
andTaskFactory
. -
These factory classes are grouped under the package
util.factories
.
-
-
Logger
class: Used by all classes to write log messages to ArchDuke’s log file. -
ParserHelper
class: Used by all classes for user input parsing. -
SortHelper
class: Used primarily byRepositories
andControllers
for sorting objects based on description before a Response model is generated for theView
layer. -
DateTimeHelper
class: Used for handling anything that is related to Date objects or parsing inputs for Date objects -
ConstantHelper
class: Stores all magic numbers and strings for better code readability -
ValidityHelper
class: Responsible for data validation before object creation -
UIFormatter
classes: Responsible for formatting data into String arrays for theView
layer
The rest of the App consists of four main layers.
-
View
layer: The UI of ArchDuke. Responsible for printing everything that the user will see and reading inputs from the user. -
Controller
layer: Responsible for handling user inputs and sending them to the respective classes for parsing, cleaning, or object creation. -
Repository
layer: Responsible for holding data in-memory during program runtime -
Storage
layer: Responsible for serializing and serializing persistent JSON data files from hard disk.
Each layer will be discussed in detail below.
Our main UI Component is a class called CLIView. It is mainly responsible for reading the user input and displaying formatted messages to the user.
When ArchDuke is running, CLIView repeatedly reads the user input line by line, and sends it to the parsing components (Controllers) to make sense of the input. Eventually, the controllers will retrieve the relevant messages and information for CLIView to display.
ConsoleInputController
is the class which deals with the CRUD functionality for all the projects of the user.
Upon entry of ArchDuke, the input commands from CLIview
would be passed to the ConsoleInputController
to be
parsed and processed. Subsequently, based on what is interpreted from the user input, the ConsoleInputController
will call the relevant methods from the other classes from the next layer, and returns to CLIview
either the
desired data by the user or the success/error messages to inform the user of the result of the input command.
Rationale for implementation
The ConsoleInputController
is meant to process command inputs from the user and subsequently call methods from other
classes. It mainly allows the user to navigate between the different projects available, to give the user an
overview of the current projects.
ProjectInputController
is the class which deals with the management of a specific project.
Rationale for implementation
We realized that the commands related to managing a project are extremely complex. Hence we had to segregate the methods related
to managing a single project from the ConsoleInputController
and this resulted in the creation of the ProjectInputController
.
When the project is being managed, all the commands input by the user are directly handled by the ProjectInputController
.
Hence, ProjectInputController
acts like a parser for commands dealing with the CRUD functionality for Members, Tasks,
Task Assignments and Reminders. Control is handed back to the ConsoleInputController
after exiting from managing a project.
AssignmentController
is a class which manages the assignment of tasks to group members. It is invoked by ProjectInputController
when the user inputs the "assign task" command. It first ensures that the input is valid by ensuring that there are sufficient
parameters (task index numbers, member index numbers). It then accesses the respective Project
to create or remove assignments between
Member
and Task
objects. These assignments are recorded within the Project
itself in the form of Java HashMaps.
This controller contains a ParserHelper
to help parse assignment commands, and two separate ArrayLists to store
error or success messages to display to the user regarding task assignments.
Rationale for implementation
Before the implementation of AssignmentController
, the parsing of assign commands was planned to be done within the
ProjectInputController
class. However, we realised that parsing for assignment commands would be extremely complex due
to the potentially high number of arguments and operations that need to be done.
Separate methods would be needed to handle assignments and unassignments, with one unifying method that combines and
executes one or both based on the user input.
For these reasons, we decided to separate these methods into AssignmentController
class. This allows for higher cohesion
as all methods related to managing assignments between tasks and members are isolated into a single, focused class. It can help to fulfill the Separation of Concerns Principle.
The repository layer is responsible for the storage of information in ArchDuke. It consists of the ProjectRepository
class, which
keeps track of all the Project
objects. Each Project
contains the following components:
API : IRepository.java
An implementation of IRepository: ProjectRepository ProjectRepository.java
The Repository
Layer is responsible for serving as a boundary between the Storage
layer and the Controller
layer.
It uses the IRepository
interface, making it easy should other developers choose to implement their own
Repository
layer.
The responsibilities of the Repository
layer includes
-
Storing the data in-memory during programme runtime. It stores all
Project
objects created in anArrayList<Project>
. -
Separation of concern between data and persistence. In a full-fledged application, the
Repository
layer will serve as a boundary between the database and the domain logic
In our implementation of ProjectRepository
that implements the IRepository
interface, it
-
Calls
ProjectFactory
for creation ofProject
objects and stores it in anArrayList<>
-
Exposes APIs to retrieve details of the stored
Project
objects forController
to send back toView
layer. -
Exposes CRUD APIs for creation, deletion and getting a
Project
object from the storedArrayList<Project>
.
API :
JsonConverter.java
The Storage
layer is responsible for saving and loading data to and from persistent data. It utilizes a
3rd-party plugin called GSON, a serialization and deserialization library by Google to convert Java Objects into JSON
and back.
-
It can save
Project
objects in JSON format and read it back. -
It saves all JSON in the current working directory that ArchDuke is saved in
-
This can be changed by editing
userDirectory
component to the desired directory where saved data should be.
-
-
Each new
Project
object saved inside theRepository
will be saved in a new JSON file, named after the name of theProject
.
Classes used by multiple components are in the 'util' package. Within this package are several subpackages that assist the functionality of ArchDuke. The following table shows a brief description of these classes and a link to their API.
Class |
Functionality |
API |
ArchDukeLogger |
Help with the logging functionally for ArchDuke for easy debugging for the developers. |
|
AssignmentViewHelper |
Handles |
|
CommandHelper |
Contains the command help instruction for the user to consume. |
|
ConstantHelper |
Contains most of the constants used throughout ArchDuke. |
|
DateTimeHelper |
Handles the Date Format specific to ArchDuke |
|
ParserHelper |
Contains methods used by other classes to parse the user input to retrieve and validate the desired information. |
|
ProjectFactory |
The |
|
ReminderFactory |
The |
|
MemberFactory |
The |
|
TaskFactory |
The |
|
SortHelper |
Contains various function for sorting the item in different format. |
|
ViewHelper |
Formats and organises information in a presentable and user-friendly manner to display to the user. |
This section describes in detail on how certain features of ArchDuke are implemented. Most features are based on Create, Read, Update, Delete, also known as CRUD functions
CRUD functions are facilitated by ConsoleInputController
, ProjectRepository
and ProjectFactory
. It allows
ArchDuke to be able to do some basic CRUD functions for a Project, namely Creation, Reading, Update and Deletion.
ConsoleInputController
will read the relevant commands from the View
layer and call the relevant methods in
ProjectRepository
.
It implements the following commands:
-
create PROJECT_NAME
— Creation of a new Project -
list
— Viewing all Projects that have been created -
delete PROJECT_INDEX
— Delete a Project that has been created previously
These operations are exposed in the IRepository
interface as addToRepo()
, getAll()
and deleteItem()
.
Note
|
However, in order to create a object, inputs sent to the Repository layer must be sent to a Factory class as the
Repository layer is not responsible for the creation of Objects.
|
The example usage scenario below will explain in detail the data flow and how the program behaves at each step of CRUD functions with regards to a Project object.
Step 1) ArchDuke is launched for the first time by the user. A new CLIView()
and ConsoleInputController
is
created upon initialization. Immediately after initialization, CLIView.start()
will be called which prints a welcome
message to the user and awaits for user input.
Step 2) The user executes the command create Avengers Assemble!
to create a new Project with the description
"Avengers Assemble!". User input is fed from CLIView
to ConsoleInputController
, where simple parsing will be done
to determine the type of command that the user has executed.
Step 3) User input will be understood as a command to create a new project and thus sent to ProjectRepository
where
it will call on ProjectFactory
for the creation of a new Project object.
Step 4) ProjectRepository
will check if ProjectFactory
managed to create an object successfully. Any unsuccessful
creation will be due to wrong user commands or a bug during data validation in ProjectFactory
.
Step 5) Assuming Project creation was a success, ProjectRepository
will store it in an ArrayList and return True
back to ConsoleInputController
to signify the successful creation of a new Project object. ConsoleInputController
will call CLIView
to print appropriate messages to the user based on whether a new Project object was created
successfully or not.
The following sequence diagram shows how the create PROJECT_NAME
command works.
The delete PROJECT_INDEX
command works similarly to create PROJECT_NAME
. Both commands will result in a
Boolean
of either True
or False
to indicate whether command was executed successfully. There are minor
differences, listed below:
-
Instead of creating a new Project object, the
delete PROJECT_INDEX
command will calldeleteItem()
inProjectRepository
instead ofaddToRepo()
. -
Deletion of Project works by Project Index instead of Project Name.
Manage project
ArchDuke allows users to manage each individual project in the ProjectRepository
.
The following sequence diagram shows how the manage PROJECT_INDEX
command works.
-
Alternative 1 (current choice): Use Factory creational design pattern
-
Pros:
-
Reduces complexities by creating objects without using the
new
operator -
Avoids tight coupling by separating the object creation process from the class that needs it
-
Frequent changes to the Interface can be accommodated
-
Aids scalability as other classes only need to refer to the
Factory
class to create more objects
-
-
Cons:
-
Requires deep technical knowledge on handling Null objects
-
-
-
Alternative 2: Using the
new
operator to create new Objects-
Pros:
-
Simple, basic and easy to learn
-
-
Cons:
-
High coupling, as instances of the Object created cannot be isolated for unit testing
-
Breaks Single Responsibility Principle as sometimes the Object needs to be modified frequently
-
-
CRUD Member functions are handled by Member, MemberList, MemberFactory, Project and ProjectInputController. It allows ArchDuke to perform simple CRUD function for Member in the Project, these simple functions include Create, Read, Update and Delete. ProjectInputController will read the relevant command related to the member function and call the relevant methods in ParserHelper.
It implements the following commands:
-
add member -n MEMBER_NAME [-i MEMBER_PHONE_NUMBER] [-e MEMBER_EMAIL]
— Creates a new Member with the member name, phone number (optional) and email address (optional). -
edit member MEMBER_INDEX [-n MEMBER_NAME] [-i PHONE_NUMBER] [-e MEMBER_EMAIL]
— Updates an existing member details based on the member index with the new attributes specified. -
view members
-- Displays all the members in the current project. -
view credits
-- Displays the compiled credits of all members from their individually assigned tasks. -
role INDEX -n MEMBER_NAME
-- Assigns roles to specific members using their names. -
delete member MEMBER_INDEX
--Deletes a member from the current project using the member index.
The example usage scenario will explain in detail the data flow and how the program behaves at each step of CRUD
functions with regards to a Member
object.
Step 1) The user creates a new project and chooses to manage it.
Step 2) The user executes the command add member -n Charles Wong -i 95674325 -e [email protected]
to create a new member
with the name "Charles Wong" whose phone number is "95674325" and whose email address is "[email protected]".
Step 3) The ProjectInputController.manageProject()
method triggers the MemberFactory
which does the validation of the input.
Step 4) MemberFactory
then goes on to call parser.parseMemberDetails()
to do a simple parsing which will clean up
the flags and will return an ArrayList<String>
for MemberFactory to create the member.
Step 5) MemberFactory
will create the member based on the information provided by the user. The created member will
subsequently be added into memberList
which holds all the members in the current project. Upon doing successfully or
unsuccessfully doing so, a String message will be returned.
CRUD Task functions are handled by Task
, TaskList
, TaskFactory
, Project
and ProjectInputController
.
It allows ArchDuke to perform simple CRUD function for Task in the Project, these simple functions include Create, Read,
Update and Delete. TaskFactory
will create the relevant task with the appropriate input from the user which will then be
added into the TaskList
managed by the Project
. ProjectInputController
will read the relevant command related to task
function and call the relevant methods in TaskFactory
And ParserHelper
.
It implements the following commands:
-
add task -n TASK_NAME -p TASK_PRIORITY -c TASK_CREDIT [-d TASK_DUE_DATE] [-s TASK_STATE] [-r TASK_REQUIREMENTS]
— Creates a new Task with the task name, priority, credit, due date (optional), state(optional) and additional requirements (if any). -
edit task TASK_INDEX -n TASK_NAME -p TASK_PRIORITY -c TASK_CREDIT [-d TASK_DUE_DATE] [-s TASK_STATE]
— Updates existing task attributes with the new input values. -
view tasks
— Displays all tasks in current project. -
view tasks [-MODIFIER]
— Displays tasks sorted based on the attribute specified by the user. -
view task requirements TASK_INDEX
— Displays all additional requirements of a specified task. -
edit task requirements TASK_INDEX rm/TASK_INDEXES r/TASK_REQUIREMENT1
— Updates task requirements of specified task by removing unwanted requirements and adding new ones. -
delete task TASK_INDEX
— Deletes task with stated index.
The example usage scenario below will explain in detail the data flow and how the program behaves at each step of CRUD
functions with regards to a Task
object.
Step 1) Assuming Project have been created and the user is currently managing a specific project.
Step 2) The user execute the command add task -n kill Thanos! -p 100 -c 100
to create a new task with the task
name “kill Thanos!”, priority value “100” and a credit of “100”. These input will be consumed by ProjectInputController.manageProject()
Step 3) The ProjectInputController.manageProject()
will trigger the TaskFactory
which will do a validation to ensure the
required input are given.
Step 4) TaskFactory
will then call parserHelper.parseTaskDetails() to do a simple parsing which will clean up the
flags and return ArrayList<String>
for TaskFactory
to create the task.
Step 5) TaskFactory
will create the task based on the information given by the user. The created task will subsequently
be added into taskList
managed by the project and a successfully or unsuccessfully a message in String[] will be returned.
The following sequence diagram show how add task
operation works.
CRUD Reminder functions are handled by Reminder
, ReminderList
and ReminderFactory
,Project
and ProjectInputController
.
It allows ArchDuke to perform simple CRUD function for Reminder in the Project, these simple functions include Create, Read,
Update and Delete. ReminderFactory
will create the relevant task with the appropriated input from the user which will then be
added into the ReminderList
managed by the Project
. ProjectInputController
will read the relevant command related to task
function and call the relevant methods in ReminderFactory
And ParserHelper
.
Reminder function implements the following commands:
-
add reminder -n REMINDER_NAME -r REMINDER_REMARKS -d REMINDER_DUEDATE -l REMINDER_LIST_NAME
— Creation of a new Reminder with the reminder name and due date (optional) the remarks of the reminder and the reminder list name. -
edit reminder TASK_INDEX -n REMINDER_NAME -r REMINDER_REMARKS -d REMINDER_DUEDATE -l REMINDER_LIST_NAME
— Edits existing reminders with the new input values specified by the user. -
delete reminder REMINDER_INDEX
— Delete existing reminder with the specified index. -
view reminders
— Viewing of all reminders in current project -
view reminders by list
— Viewing of all reminders in current project sort in their respective list.
The following sequence diagram show how add reminder
operation works.
The example usage scenario below will explain in detail the data flow and how the program behaves at each step of CRUD
functions with regards to a Reminder
object.
Step 1) Assuming Project have been created and the user is currently managing a specific project.
Step 2) The user execute the command add Reminder -n Do System integration -d 31/10/2019
to create a new reminder with the reminder
name “Do System integration” on a specific date "31.10/2019". These input will be consumed by ProjectInputController.manageProject()
Step 3) The ProjectInputController.manageProject()
will trigger the ReminderFactory
which will do a validation to ensure the
required input are given.
Step 4) ReminderFactory
will then call parserHelper.parseReminderDetails() to do a simple parsing which will clean up the
flags and return a ArrayList<String>
with the relevant details for ReminderFactory
to create the task.
Step 5) ReminderFactory
will create the reminder based on the information given by the user. The created Reminder will subsequently
be added into ReminderList
managed by the project and a successfully or unsuccessfully a message in String[] will be returned.
ArchDuke allows users to track tasks and their assignments to members in a project.
Assignments establish a relationship between a task and a member. When a member is assigned a task,
they are expected to complete it, and will be given the stipulated credit when the task state is marked
as DONE
. The degree of each member’s contributions are measured by task credit.
Assignment functions are handled by ProjectInputController
, ParserHelper
, AssignmentController
, AssignmentViewHelper
and Project
.
Assignment functions implement the following commands:
-
assign task -i TASK_INDEX -to [MEMBER1_INDEX] [MEMBER2_INDEX] -rm [MEMBER3_INDEX]
-
view assignments MODIFIER
Upon creation, each Task
and Member
object are given a unique ID using the UUID class in Java. The ID
is stored as a String and is immutable throughout the lifetime of the object.
Assignments are tracked in the Project
class by mapping the task IDs to the member IDs using 2 Java HashMaps:
-
taskAndListOfMembersAssigned
-
Key: String
taskID
of each task. -
Value: ArrayList<String> containing
memberID
of all members assigned to the respective task.
-
-
memberAndIndividualListOfTasks
-
Key: String representing
memberID
of each member. -
Value: ArrayList<String> containing
taskID
of all the tasks assigned to that particular member.
-
The following steps show how the assign task
command is implemented in ArchDuke.
Step 1) Assume Project has been created and the user is currently managing a specific project.
Step 2) User enters the command assign task -i 1 2 -to 1 2 3 -rm 4
. This indicates the user would like to assign tasks with index
number 1 and 2 to members 1, 2 and 3, and also unassign/remove the task from member 4.
Step 3) The ProjectInputController.manageProject()
will call projectAssignTask()
. A new AssignmentController
will be created,
and the assignAndUnassign()
method is called to manage the assignment.
Step 4) ParserHelper.parseAssignmentParams()
is called to parse and split the input into 3 parts: the task index numbers, the assignee
index numbers, and the unassignees index numbers.
Step 5) ParserHelper
checks all 3 sets of index numbers to ensure that they are valid (non-negative integers,
and exist within the project) using ParserHelper.parseMembersIndexes()
and ParserHelper.parseTasksIndexes()
.
AssignmentController.checkForSameMemberIndexes()
checks if the list of assignees and unassignees contain any identical
index numbers, and removes them to avoid redundant work. ParserHelper
returns all 3 sets of valid indexes to AssignmentController
.
Step 6) If there are valid task numbers, a for loop is used to iterate through the tasks to handle the assignments
one by one. AssignmentController.assign()
and AssignmentController.unassign()
are called to assign or unassign
tasks to the members.
Step 7) Project.containsAssignment()
is used to check if an assignment between a task and member already exists to
avoid any errors (for example, duplicating assignments or trying to remove an assignment which does not exist).
The errors are noted down by adding error messages to the ArrayList errorMessages
which will be displayed to the user later.
Step 8) If the input is valid, the assignment is created by calling Project.createAssignment()
or removed by calling
Project.removeAssignment()
. The 2 HashMaps in the project are manipulated accordingly to note down the assignment between the specified task
and member. Success messages are stored in successMessages
.
Step 9) The errorMessages
and successMessages
from AssignmentController
are retrieved by ProjectInputController
. The messages are validated, and then
formatted with the help of ViewHelper
, which organises the information into easy-to-read tables and displayed to the user.
The following sequence diagram shows how the assign task
command works.
Certain objects, such as Project
and ViewHelper
are omitted for simplicity.
The following steps show how view assignments
is implemented in ArchDuke.
Step 1) Assume Project has been created and the user is currently managing a specific project.
Step 2) User enters a command to view assignments. This can be in one of the following formats:
-
view assignments -m
(to view each member’s tasks) -
view assignments -t
(to view each task’s assigned members)
Each command is accompanied with a suffix all
, or selected index numbers of members or tasks.
Step 3) The ProjectInputController.manageProject()
will call projectViewAssignments()
.
Step 4) AssignmentViewHelper
is created, and calls viewAssignments()
to to retrieve the necessary
assignment information. The input length is checked to ensure that there are sufficient parameters.
Depending on the flag in the user input, viewAssignments()
calls 1 of 2 the helper methods:
-
Task flag
-t
: viewTasksAssignments() is called.-
ParserHelper.parseTaskIndexes()
is called to parse and retrieve valid task indexes. -
AssignmentViewHelper.getTaskOutput()
is called to access the HashMaptaskAndListOfMembersAssigned
to retrieve the assigned members for selected tasks.
-
-
Member flag
-m
: viewMembersAssignments() is called.-
ParserHelper.parseMemberIndexes()
is called to parse and retrieve valid member indexes. -
AssignmentViewHelper.getMemberOutput()
is called to access the HashMapmemberAndIndividualListOfTasks
to retrieve the assignments for the selected members.
-
The necessary information is stored in an ArrayList of String totalOutputToPrint
in both cases.
Step 5) The helper class ViewHelper
formats the output in an organised table, and the output is returned
to ProjectInputController
, and subsequently back to CLIView
to be displayed to the user.
The following sequence diagram shows how the view assignments
command works.
-
Alternative 1 (current choice): Use 2 HashMaps which store IDs of tasks and members in Project class
-
taskAndListOfMembersAssigned
-
Key: String
taskID
of each task. -
Value: ArrayList<String> containing
memberID
of all members assigned to the respective task.
-
-
memberAndIndividualListOfTasks
-
Key: String representing
memberID
of each member. -
Value: ArrayList<String> containing
taskID
of all the tasks assigned to that particular member. -
Pros:
-
1) Allows fast and easy writing and retrieval of data.
-
2)
Task
andMember
objects to not need to be aware of each other in order to maintain the assignment. Assignments can be managed entirely by the project itself, which reduces coupling betweenTask
andMember
objects.
-
-
Cons:
-
1)
Task
andMember
objects must be retrieved manually by iterating through thetaskList
/memberList
to find the corresponding object with the matching ID.
-
-
-
Alternative 2: Use 2 HashMaps in Project class which store Similar to Alternative 1, but instead of storing String IDs, the objects themselves are stored.
-
taskAndListOfMembersAssigned
-
Key:
Task
-
Value: ArrayList of assigned
Member
objects (List of members assigned to task)
-
-
memberAndIndividualListOfTasks
-
Key:
Member
-
Value: ArrayList of
Task
objects (List of each member’s individual tasks)
-
-
Pros: (same as in Alternative 1)
-
1) Allows fast and easy writing and retrieval of data.
-
2) Task and Member objects to not need to be aware of each other in order to maintain the assignment. Assignments can be managed entirely by the project itself.
-
-
Cons:
-
1) Complications associated with hashing non-primitive objects.
-
2) Key or values cannot be updated consistently in the HashMap when task/member details are changed. This results in inconsistent task and member information being stored in the 2 HashMaps, and outdated information being retrieved when viewing assignments.
-
-
-
Alternative 3: Each
Task
maintains an ArrayList of assigned members, and eachMember
maintains an ArrayList of assigned tasks.-
Pros:
-
1) More intuitive.
-
-
Cons:
-
1) Increases coupling between
Member
andTask
as each member has to keep a list of assigned tasks and vice versa. -
2) Cyclic dependencies will exist between
Task
andMember
objects, making it difficult to edit and change task assignments.
-
-
-
Alternative 4: Use an association class to record the assignment.
-
Pros:
-
1) Reduces coupling between
Member
andTask
.
-
-
Cons:
-
1) Since the association class does not belong to
Member
orTask
in particular, it might be more difficult to retrieve specific information about the assignments of a particular task/member. -
2) No additional information needs to be stored by the association class.
-
-
UI functions are handled by CLIView
, ViewHelper
, and the repository layer which stores the details of projects,
members and tasks. It allows ArchDuke to present useful information to the user in an easily readable format when
requested. The information will be presented in a table form with a clear header that describes the content and
has the information in bullet point form.
The UI display uses the following methods to produce a table:
-
consolePrintTable()
— Main method that constructs the table. Returns a String array with each element representing one row of the table -
consolePrintTableHoriBorder()
— Returns a String containing the horizontal border of the table -
getRemainingSpaces()
— Returns a String containing the remaining number of spaces required to fill up the rest of the line -
getArrayOfSplitStrings()
— When a String that is meant to be in one row in the table is too long, it is passed into this method to split the string up into an array of Strings of suitable length to fit into one row of the table -
consolePrintMultipleTables()
— This method reusesconsolePrintTable()
and expands on it to create a table containing multiple smaller tables each with its own header. Returns a String array with each element containing the String corresponding to the line of the table to be printed
The following steps show how the UI table display are made in ArchDuke.
Step 1) User enters a command that requires information to be presented in a clear format such as list
, view members
,
view tasks
etc.
Step 2) Assume the command list
is entered. The user is requesting an overview of all the projects that he is currently doing.
This would call the method getAllProjectDetailsForTable()
in ProjectRepository
.
Step 3) The method getAllProjectDetailsForTable()
would return an ArrayList containing multiple ArrayLists of String,
with each ArrayList of String containing all the details of each project which will be stored in one table. The parent
ArrayList would then contain information to be printed in different tables. In this case, each project will fill one table.
Step 4) The ArrayList of ArrayLists would then be passed into the consolePrintMultipleTables()
method in the ViewHelper
class, which will create an overall table containing information to all the projects and pack each individual
ArrayList of Strings into a formatted table. Each String in the ArrayList of Strings is an entry that is meant to be presented
in one line of the table.
Step 5) Within the consolePrintMutlipleTables()
method, each ArrayList of String is supposed to be stored within one
smaller table. Hence, for each ArrayList of String, the consolePrintTable()
method is used to generate a string array
containing the contents in the ArrayList of String. The width of each of the smaller tables will be calculated based on
the width of the overall table and the input parameter for the number of columns required.
Step 6) Within the consolePrintTable()
method, when the String is shorter that the full table width, there are spaces
that need to be added to maintain the visual implementation of the table. Hence, the getRemainingSpaces()
method is
called to fill up the remaining spaces.
Step 7) When the String is longer than the full table width, it needs to be split into multiple lines in order to fit it
within the table. Hence, the getArrayOfSplitStrings()
method is called to split the string up nicely to fit the table width.
It will ensure that the String is split at the spaces as much as possible so that the words remain intact. If the
point of the string that exceeds the table width is in the middle of a word and it is within a predefined length,
the entire word will be shifted to the next line. If it exceeds that predefined length, that word will be split with
a hyphen '-' with the remaining half of the word to be pushed to the next line. This process repeats and each
line will be stored in an individual string.
Step 8) The consolePrintTableHoriBorder()
method is called at any point where the horizontal border of the table is required.
Step 9) After the tables are generated, the tables would be lined up in each column one by one. The tables will be added to the shortest column at any point in time. If 2 or more columns are of the same length, the next table will be added to the left most column.
Step 10) The consolePrintMultipleTables()
method would then store the entire series of tables to be displayed into a
String array with each element containing a line to be printed to be passed into consolePrint()
where it will be
printed with indentation and horizontal borders on the top and bottom.
The following sequence diagram show how list
operation works.
-
Alternative 1 (current choice): Use ArrayList of ArrayLists, with each ArrayList being an ArrayList of Strings.
-
Pros:
-
1) Allows fast and easy retrieval of data.
-
2) Allows orderly storing of individual separate table information in separate ArrayLists.
-
3) Allows easy manipulation of
consolePrintTable()
to print each individual table’s content.
-
-
Cons:
-
1) Tedious to have multiple nested loops as code may be prone to bugs.
-
-
-
Alternative 2: Use one ArrayList of Strings to store all content to be in the table.
-
Pros:
-
1) Simple data structure used.
-
-
Cons:
-
1) Difficult to separate contents from different tables.
-
2) Difficult to account for formatting of different table lengths and widths.
-
-
We are using org.apache.logging.log4j
package for logging. The ArchDukeLogger
class under Utility
layer is used for
logging every step that ArchDuke takes so that debugging will be easier.
-
The logging level is controlled by property name
rootLogger.level
inlog4j2.properties
. Currently the level is set to all. (Show all log level message) -
The
ArchDukeLogger
call by usingArchDukeLogger.logInfo(className, Message);
function which will log the message according to the specified logging level method called. -
Currently all the log messages are store in the log file located in the logs directory
The log4j2.properties
file in the resource folder is used configure the following:
-
RootLogger level - The level root logger to be shown in the log file. Currently it is set to
all
to view all the logs level. -
File Appender - The file direction and log file name. The log file can be found in the logs folder.
-
PatternLayout - The output format message displayed in the log file
The following shows the class diagram of ArchDukeLogger
API : ArchDukeLogger.java
Note
|
If any bugs or errors encountered during the testing, please do create an issue on this repo and upload the logs file located
is the logs directory.
|
We chose to use AsciiDoc writing format to write the documentation. This is because Ascii syntax is consistent and there is a flexibility offered for essential syntax unlike MarkDown.
Diagrams are drawn and edited using the tool draw.io. The tool provides support for a wide range of UML diagrams, such as class, object and sequence diagrams.
There are two ways to run tests.
Method 1: Using IntelliJ JUnit test runner
-
To run all tests, right-click on the
src/test/java
folder and chooseRun 'All Tests'
-
To run a subset of tests, you can right-click on a test package, test class, or a test and choose
Run 'ABC'
Method 2: Using Gradle
-
Open a console and run the command
gradlew clean test
(Mac/Linux:./gradlew clean test
)
Note
|
See UsingGradle.adoc for more info on how to run tests using Gradle. |
We have three types of tests:
-
Unit tests targeting the lowest level methods/classes.
e.g.java.factorytests.TaskFactoryTests
-
Integration tests that are checking the integration of multiple code units (those code units are assumed to be working).
e.g.java.controllers.ProjectInputControllerManageTest
-
Hybrids of unit and integration tests. These test are checking multiple code units as well as how the are connected together.
e.g.java.helpertests.AssignmentViewHelperTest
Gradle is an open-source build automation tool that automates build-related tasks by running scripts. It is mainly used for the following tasks:
-
Automating tests
-
Performing checks on code style
-
Managing dependencies on external libraries
Note
|
The Gradle configuration for ArchDuke is defined in build script build.gradle .
|
Gradle commands are run on the command prompt window. Navigate to the project folder and enter the desired commands. The following are some examples of gradle commands:
-
Windows: gradlew [command1] [command2]
-
Mac/Linux: ./gradlew [command1] [command2]
Cleaning deletes the files leftover from previous builds. This prevents existing builds from failing.
Command: clean
(eg. ./gradlew clean
)
This command runs all the tests located in the test directory.
Command: test
(eg. ./gradlew test
)
-
checkstyleMain Runs the code style check for the main code base
-
checkstyleTest Runs the code style check for the test code base
Note
|
The two tests are often run side by side (eg. ./gradlew checkstyleMain checkstyleTest ).
Any code style violations found will be documented in HTML reports found in build/reports/checkstyle .
|
Note
|
Code style rules can be found in config/checkstyle/checkstyle.xml . These can be reconfigured to
suit the purposes of the project.
|
We use Travis CI to perform Continuous Integration (CI) for ArchDuke. Other CI tools can be used so long
as an appriopriate .yml
file is provided and the relevant toolchain is set up properly. Some examples are
-
GitLab CI
-
AppVeyor
-
Github Actions
Travis CI can be configured to run JUnit tests automatically with the help of Gradle. This ensures that existing features and functionality are working as intended and are not broken by new code.
For ArchDuke, TravisCI is configured to run the following things every time code is pushed or a pull request is submitted:
-
Runs
./gradlew clean checkstyleMain checkstyleTest test
command-
This is to run all unit and code style tests and ensures all tests passes.
-
-
Upon success, it will run
./gradlew jacocoTestReport coveralls
-
This utilizes JaCoCo to generate test coverage and send it to Coveralls
-
Further customization can be done by referring to Travis documentation online.
Here are the steps to create a new release.
-
Update the archiveVersion number in
build.gradle
shadowJar section. -
Generate a JAR file using Gradle shadowJar.
-
Create a Tag to the current repo release with the version number e.g v.1.4.
-
Create a new release using GitHub and upload the JAR generated earlier.
Target user profile:
-
Team leaders of group projects
-
Group project team leaders who monitor contributions of team members
-
Project managers who track progress for multiple projects
-
Teachers who evaluate and act upon their students’ progress
-
Technical professionals who keep track of task deadlines
-
Project planners who plan out priority and assignment of roles
-
People who prefer Command Line Interfaces (CLI)
-
People who prefer desktop applications
Priorities: High (must have) - * * *
, Medium (nice to have) - * *
, Low (unlikely to have) - *
Priority | As a … | I want to … | So that I can… |
---|---|---|---|
|
project leader |
be able to track deadlines for each project |
prioritize which project to be completed earlier |
|
project leader |
be able to manage multiple projects and view all the task delegations of my team members in them |
distribute my resources appropriately |
|
project leader |
be able to create projects |
keep track of all my projects using a command line application |
|
project leader |
be able delete projects that are completed |
have a cleaner working environment |
|
project leader |
view a progress bar for each project |
have a clearer view of the total progress for each project |
|
project leader |
manage my team members |
assign different roles to team members so that they are clear of their relevant roles |
|
project leader |
manage my team members |
assign different tasks to team members so that they will be clear of the work that they are supposed to do |
|
project leader |
add team members to a specific group project |
assign different roles and tasks to them based on the project they belong to |
|
project leader |
update the details of my team members |
have up to date information about them whenever needed |
|
project leader |
remove members from a particular project |
remove unwanted or old members from a project that they are no longer contributing |
|
project leader |
keep track of each member’s progress and contributions |
ensure all students contribute to their respective tasks sufficiently |
|
project leader |
find a person by name |
locate details of persons without having to go through the entire list |
|
project leader |
generate a report of the contributions of the members |
credit can be rightfully assigned to the respective members |
|
project leader |
indicate the credit of each task |
track the level of contribution by each member |
|
project leader |
track the status of every task |
track the progress of each project |
|
project leader |
indicate the priority of the tasks |
ensure members know what order to be done |
|
project leader |
input the requirements of the tasks I have been assigned |
ensure needs members are clear about what needs to be done |
|
project leader |
be able to track deadlines for each task |
I will know if a group member is slacking. |
|
project leader |
assign one task to multiple students |
more than one student can contribute to the task |
|
project leader |
delete erroneous tasks from the project I am managing |
prevent any confusion and achieve a cleaner work space |
|
project leader |
view tasks sorted by name, index, date, priority, credit, assigned member names or Kanban board style |
I can view all the tasks in a customised manner according to the required scenario. |
|
project leader |
import files from other sources |
track all my projects from different workstations or work environments |
|
project leader |
be able to edit and read the exported file |
have other people can add in details as well into the file and send back |
|
project leader |
have a good overview of all the projects I am managing |
I can distribute my resources appropriately |
|
project leader |
define a clear end goal/target for the project |
that we stay on the right track |
|
project leader |
I can view the tasks and roles that I have assigned |
ensure members can complete them |
|
project leader |
keep track of the contributions of members |
ensure everyone does his/her fair share |
|
project leader |
create task dependencies |
members can complete tasks in a certain order |
|
project leader |
calculate the total weightage of tasks done by each member |
keep track of the amount of contributions done by each member |
|
project leader |
schedule project meet-ups |
group members can meet at a stipulated date and time |
|
project leader |
be able to export the relevant details for each project |
send it to other people for viewing |
|
project leader |
be able to export the details for each project in different formats |
avoid compatibility issues with a specific file format |
|
project leader |
view a calendar with all tasks, milestones and deadlines |
easily visualise the progress of the project |
|
project leader |
have a more intuitive way to view the current task and role assigned to a particular team member |
better manage their well being |
|
project leader |
be able to track the technical and non-technical roles assigned to my team members |
I can keep track of the overall progress of the project |
|
project leader |
define milestones to track the progress of the entire project |
have users work towards each milestone sequentially |
|
project leader |
save time managing my team members from the manual way of tracking my group progress |
make this group can be as efficient as possible |
|
project leader |
change the assignment of tasks halfway through the project |
cater to different needs and schedules of team members |
{To be edited}
(For all use cases below, the System is the ArchDuke
and the Actor is the user
, unless specified otherwise)
MSS
-
User requests to create project with desired project name and number of members
-
ArchDuke creates a project named after desired project name and number of members
Use case ends.
Extensions
-
1a. The given input is wrong.
-
1a1. ArchDuke shows an error message.
Use case ends.
-
MSS
-
User requests to view all projects.
-
ArchDuke shows a list of all projects with their respective details.
Use case ends.
Extensions
-
1a. The given input is wrong.
-
1a1. ArchDuke shows an error message.
Use case ends.
-
MSS
-
User requests to view all projects.
-
ArchDuke shows a list of all projects with their respective details.
-
User requests to manage a project specified in the list.
-
ArchDuke opens up the specified project.
Use case ends.
Extensions
-
2a. The list is empty.
Use case ends.
-
3a. The given index is invalid.
-
3a1. ArchDuke shows an error message.
Use case resumes at step 2.
-
MSS
-
User selects a specific project to manage (UC03).
-
User enters command to add member specifying at least the member’s name. Phone number and email address are optional.
-
ArchDuke adds specified member into current project.
Use case ends.
Extensions
-
2a. The given information (member details) is invalid.
-
2a1. ArchDuke shows an error message.
Use case resumes at step 1.
-
-
2b. The user enters the name of a member already in the project.
-
2b1. ArchDuke shows an error message informing user of existing member.
-
MSS
-
User selects a specific project to manage (UC03).
-
User requests to edit member specifying member index and fields that require editing.
-
ArchDuke edits specified fields of specified member in current project.
Use case ends.
Extensions
-
2a. The given index is invalid.
-
2a1. ArchDuke shows an error message prompting user to check again and enter the correct index.
Use case resumes at step 1.
-
MSS
-
User selects a specific project to manage (UC03).
-
User requests to add task.
-
ArchDuke adds task to current project.
Use case ends.
MSS
-
User selects a specific project to manage (UC03).
-
User requests to edit task specifying task index and fields that require editing
-
ArchDuke edits specified fields of specified task in current project.
Use case ends.
Extensions
-
2a. The given index is invalid.
-
2a1. ArchDuke shows an error message.
Use case resumes at step 1.
-
MSS
-
User selects a specific project to manage (UC03).
-
User requests to assign/unassign a specific task to one or several members.
-
ArchDuke assigns/unassigns specified members to specified task in current project.
Use case ends.
Extensions
-
2a. User enters invalid index numbers of tasks/members.
-
2a1. ArchDuke shows error messages indicating invalid index numbers of respective tasks/members.
Use case resumes from step 2.
-
-
2b. User tries to assign task to someone who has already been assigned the task, or unassigns
-
2b1. ArchDuke shows error message indicating unsuccessful assignments.
Use case resumes from step 2.
-
MSS
-
User selects a specific project to manage (UC03).
-
User requests to mark a specific task as completed.
-
ArchDuke marks specified task in current project as completed.
Use case ends.
Extensions
-
2a. The given index is invalid.
-
2a1. ArchDuke shows an error message.
Use case resumes at step 1.
-
The following is a summary of all the commands in ArchDuke, and some examples of input. The commands are organised into sections, each relating to a particular feature. There is already some data preloaded into the ArchDuke jar file. You may follow the steps in numerical order to test all the features of ArchDuke.
Note
|
Inputs in square brackets [EXAMPLE] are optional.
|
Project Commands
-
Creating projects.
-
Please use the following commands to create, view or delete projects.
-
Create project:
create PROJECT_NAME
-
Example:
create Infinity Gauntlet
-
Example:
create New Project
-
-
View projects:
list
-
Delete project:
delete PROJECT_INDEX
-
Example:
delete 3
-
-
-
-
Managing projects.
-
Please use this command to select a project you would like to manage. The rest of the commands can only be used after this command is successfully executed. For the purposes of this test, we will manage the project
avengers
preloaded in the ArchDuke jar file.-
Manage project:
manage PROJECT_INDEX
-
Example:
manage 1
-
-
-
-
Managing members
-
Please use these commands to manage members in the project. Before starting, ensure that you are managing the project
avengers
. You may follow the commands provided in sequence to test the member functionalities.
-
Member Commands
-
View members:
view members
-
To check that member details were updated successfully, you may use
view members
again at any point in time.
-
-
Add members:
add member -n NAME [-i PHONE_NUMBER] [-e EMAIL] [-r ROLE]
-
Example:
add member -n Cynthia
-
Example:
add member -n Jerry Zuang -i 9123456 -e [email protected] -r Lead
-
-
Delete members:
delete member INDEX1 [INDEX2]
-
Example:
delete member 1 2
-
-
Edit members:
edit member INDEX [-n NAME] [-i PHONE_NUMBER] [-e EMAIL]
-
Example:
edit member 5 -n Jerry Zhang -e [email protected]
-
Example:
edit member 1 -n Sean -e [email protected]
-
Example:
edit member 2 -n Abhishek -i 91234567
-
Example:
edit member 3 -n Dillen -e [email protected]
-
-
Give roles for members:
role INDEX -n ROLE_NAME
-
Example:
role 2 -n Tester
-
Managing members
-
Please use these commands to manage tasks. You may follow these commands in sequence to test task functionalities.
-
-
-
Task Commands
You may first view all the tasks existing in the project by using view tasks
-
Add task:
add task -n TASK_NAME -p TASK_PRIORITY [-d TASK_DUEDATE-(dd/mm/yyyy)] -c TASK_CREDIT [-s STATE] [-r TASK_REQUIREMENT1] [-r TASK_REQUIREMENT2]
-
Example:
add task -n Hello World Code -p 5 -c 5
-
Example:
add task -n Documentation for product -p 2 -d 21/09/2019 -c 40 -r do something -r do another thing -r do another thing
-
-
Edit task:
edit task TASK_INDEX [-n TASK_NAME] [-p TASK_PRIORITY] [-d TASK_DUEDATE-(dd/mm/yyyy)] [-c TASK_CREDIT] [-s TASK_STATE]
-
Example:
edit task 1 -n Finish CS2113 -p 4 -c 80 -d 11/11/2019
-
Example:
edit task 2 -n JUnit tests -s doing -c 55 -d 5/11/2019
-
Example:
edit task 3 -n Submit UG -s done -d 8/11/2019 -c 35
-
-
Delete tasks:
delete task INDEX
-
Example:
delete task 4 5
-
-
View tasks:
view tasks MODIFIER
-
The following are examples of
MODIFIER
suffixes which can be added to be tested.-
Example:
view tasks -state done
-
Example:
view tasks -name
-
Example:
view tasks -priority
-
Example:
view tasks -credits
-
Example:
view tasks -date
-
Example:
view tasks -who EXISTING_MEMBER_NAME
-
-
-
View task requirements:
view task requirements TASK_INDEX
-
Example:
view task requirements 2
-
-
View task requirements:
view task requirements TASK_INDEX
-
Example:
view task requirements 1
-
-
Edit task requirements:
edit task requirements TASK_INDEX [-r TASK_REQUIREMENT_TO_ADD] [-rm TASK_REQUIREMENT_INDEX_TO_REMOVE]
-
Example:
edit task requirements 1 -r Testing -r Documentation
-
Example:
edit task requirements 1 -rm 1 2 3 -r Submit
-
-
Agenda of Tasks:
agenda
-
Assignment Commands
-
-
Assign/Unassign members to tasks:
assign task -i TASK_INDEX1 [TASK_INDEX2] [-to MEMBER1_INDEX [MEMBER2_INDEX]] [-rm MEMBER3_INDEX [MEMBER4_INDEX]]
-
Example:
assign task -i 1 2 -to 1 2
-
Example:
assign task -i 2 4 -to 3 4 5
-
Example:
assign task -i 1 -to 5 -rm 2
-
Example:
assign task -i 3 -to all
-
-
View assignments:
view assignments MODIFIER
-
Example:
view assignments -m all
(show all members' tasks) -
Example:
view assignments -m 1 2
(show tasks of member 1 and 2) -
Example:
view assignments -t all
(show all the members assigned to a task) -
Example:
view assignments -t 3 4
(show members assigned to tasks 3, 4, 5)
-
-
View total credits completed by each member:
view credits
-
Requirement Commands
-
-
Create reminder:
add reminder -n reminder_NAME [-d TASK_DUEDATE-(dd/mm/yyyy) -l REMINDER_LIST_NAME]
-
Example:
add reminder -n Fix important bug -d 21/09/2019 -l Software Reminder List
-
-
View reminders:
view reminders [by list]
-
Example:
view reminders
-
Example:
view reminders by list
-
-
Delete reminder:
delete reminder INDEX_NUMBER
-
Example:
delete reminder 1
-
-
Edit reminder:
edit reminder INDEX_NUMBER -n REMINDER_NAME [-d REMINDER_DUEDATE-(dd/mm/yyyy) -l REMINDER_LIST_NAME]
-
Example:
edit reminder 1 -n Fix important bug -d 21/09/2019
-
-
Mark reminder:
mark reminder INDEX_NUMBER
-
Example:
mark reminder 1
-
Miscellaneous
-
-
-
View current details of project:
view
-
Edit the name of the current project :
rename PROJECT_NAME
-
Example: rename Avengers
-
-
Report progress :
report
[coming in v2.0] -
Exit managing a project:
exit
-
Exiting the program from anywhere:
bye
-
Display help:
help
-
ArchDuke should be able to run on any machine with Java Development Kit (JDK 11) installed.
-
ArchDuke should be able to handle up to a thousand tasks and projects.
-
ArchDuke should be secure, to prevent unauthorised modification.
-
ArchDuke should not save passwords in plain text.
-
ArchDuke should be smooth and fast to view and edit.
-
ArchDuke output should be organised clearly with proper tabbing.