Developer Guide
- Introduction
- Setting up, getting started
- Design
- Implementation
- Documentation, logging, testing, configuration, dev-ops
- Appendix A: Requirements
- Appendix: Instructions for manual testing
Introduction
Focuris is a desktop application for managing events with a KanBan board, which is a board where your events displayed according to the level of completion of each event, which consists of Backlog, Todo, In-Progress and Done. It functions via a Command-Line Interface (CLI) that allows more efficient management of events.
Setting up, getting started
Refer to the guide Setting up and getting started.
Design
Architecture
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.
Overall Components
Main
has two classes called Main
and MainApp
. It is responsible for,
- At app launch: Initializes the components in the correct sequence, and connects them up with each other.
- At shut down: Shuts down the components and invokes cleanup methods where necessary.
Commons
represents a collection of classes used by multiple other components.
The rest of the App consists of four components.
-
UI
: The UI of the App. -
Logic
: The command executor. -
Model
: Holds the data of the App in memory. -
Storage
: Reads data from, and writes data to, the hard disk.
Each of the four components,
- defines its API in an
interface
with the same name as the Component. - exposes its functionality using a concrete
{Component Name}Manager
class (which implements the corresponding API 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
.
The sections below give more details of each component.
UI component
API :
Ui.java
The UI consists of a MainWindow
that is made up of parts e.g.CommandBox
, ResultDisplay
, ListPanel
, StatusBarFooter
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. -
HelpWindow
will only be shown when executing thehelp
command. -
KanbanPanel
is displayed as the default view.
Logic component
API :
Logic.java
-
Logic
uses theEventBookParser
class to parse the user command. - This results in a
Command
object which is executed by theLogicManager
. - The command execution can affect the
Model
(e.g. adding a todo event). - 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.
DeleteCommandParser
should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram.
Model component
API : Model.java
The Model
,
- stores a
UserPref
object that represents the user’s preferences. - stores the event book data.
- exposes an unmodifiable
ObservableList<Event>
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. - does not depend on any of the other three components.
Storage component
API : Storage.java
The Storage
component,
- can save
UserPref
objects in JSON format and read it back. - can save the event book data in JSON format and read it back.
Common classes
Classes used by multiple components are in the seedu.focuris.commons
package.
Implementation
This section describes some noteworthy details on how certain features are implemented.
Priority feature
Implementation
The priority feature is an additional field in the Event class. It is implemented as an enumeration named EventPriority and consists of a set of members named HIGH, MEDIUM, LOW. If the User decides not to add a priority to an event, LOW will be assigned as the default priority. The user can change the priority of the Event via the Edit command.
The following class diagram illustrates how the priority feature is implemented:
Event identifier
attribute
Events in Focuris have a unique identifier
attached to them.
- Identifier is an integer attribute inside the Event model, which increments each time the constructor is called. This means, identifier will increment regardless of whether an Event is successfully added in EventBook.
- Identifier gets re-allocated each time Focuris restarts.
- Identifiers never reset or decrement in a single session. This ensures that even with a potential undo feature in the future, Focuris’ Events are not at risk of having duplicate identifiers.
- This implementation of an identifier which does not reset or decrement is in line with other kanban boards, such as GitHub or Jira.
Design consideration:
Aspect: Optional Priority
-
Alternative 1 (current choice): Set LOW as the default priority
- Pros: Easy to implement.
- Cons: Events would have an additional field for priority even if there is no priority. May increase memory usage.
-
Alternative 2: Include an additional constructor that takes in priority as an additional argument.
- Pros: Will use less memory when no priority is assigned.
- Cons: We must ensure that the implementation of each individual command are correct and uses the right constructor.
Documentation, logging, testing, configuration, dev-ops
Appendix A: Requirements
Product scope
Target user profile:
- NUS Computing Students
- has a need to manage a significant number of events
- prefer desktop apps over other types
- can type fast
- prefers typing to mouse interactions
- is reasonably comfortable using CLI apps
Value proposition:
- Adding of various different types of events with descriptions.
- Prioritise work based on priority level by labeling events as Low, Medium, or High priority.
- Split work into progressions such as Backlog, ToDo, In Progress, and Done.
- Get an overview via the List view so that you can find the event that you need easily.
- Quickly updating events on the go as you complete them.
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 am unsure or forget how to use the App |
* * * |
user | add a new TODO event | keep track of events that I have to work on |
* * * |
user | add a new BACKLOG event | keep track of the events that I have upcoming |
* * * |
user | add a new IN PROGRESS event | keep track of the events that I am currently working on |
* * * |
user | get an overview of all the events by status | keep track of all events and what stages of completion they are in |
* * * |
user | edit an existing event | update events on the go as I work through my events |
* * * |
user | delete an existing event | remove events that have already finished or are no longer needed |
* * * |
user | remove all existing tasks to make way for the next sprint | focus on tasks to work on in the new sprint |
* * |
user | find an event by name or description | locate specific events without scrolling through list |
* * |
user | mark events as completed quickly | work on the next task and see that I am making progress |
* * |
user | attach priorities to different events | manage time better by working on events with higher priorities first |
Use cases
(For all use cases below, the System is Focuris and the Actor is the user, unless specified otherwise)
Use case: Delete an event
MSS
- Focuris currently shows events.
- User requests to delete a specific event.
-
Focuris deletes the event.
Use case ends.
Extensions
-
1a. There are no events.
Use case ends.
-
2a. The given identifier is invalid.
-
2a1. Focuris shows an error message.
Use case resumes at step 2.
-
Use case: Add an Event
MSS
- Focuris currently shows events.
- User requests to add an event.
-
Focuris adds the event.
Use case ends.
Extensions
-
2a. The format to add an event is invalid.
-
2a1. Focuris shows an error message.
Use case resumes at step 2.
-
-
2b. The event already exists in Focuris.
-
2b1. Focuris shows an error message.
Use case resumes at step 2.
-
Use case: Edit an event
MSS
- Focuris currently shows events.
- User requests to edit a specific event.
-
Focuris edits the event.
Use case ends.
Extensions
-
1a. There are no events.
Use case ends.
-
2a. The given identifier is invalid.
-
2a1. Focuris shows an error message.
Use case resumes at step 2.
-
-
2b. No fields are provided to edit.
-
2b1. Focuris shows an error message.
Use case resumes at step 2.
-
-
2c. The edited Event already exists.
-
2c1. Focuris shows an error message.
Use case resumes at step 2.
-
Use case: Mark an event to be done
MSS
- Focuris currently shows events.
- User requests an event to be done.
-
Focuris marks the event as done.
Use case ends.
Extensions
-
1a. There are no events.
Use case ends.
-
2a. The given identifier is invalid.
-
2a1. Focuris shows an error message.
Use case resumes at step 2.
-
-
2b. The event is already marked done.
-
2b1. Focuris shows an error message.
Use case resumes at step 2.
-
Use case: Find an event
MSS
- Focuris currently shows events.
- User requests to find an event.
-
Focuris shows events whose name or description contain any of the given words.
Use case ends.
Extensions
-
2a. There is no such event with the given keyword.
Use case ends.
Use case: Request help
MSS
- User requests help.
-
Focuris shows a link to the User Guide.
Use case ends.
Use case: Show all events
MSS
- User requests to show all events in Focuris.
-
Focuris shows all events.
Use case ends.
Extensions
-
2a. There are no events.
Use case ends.
Use case: Switch to list view of all events
MSS
- User requests to switch to list view of events in Focuris.
-
Focuris shows all events in a list view.
Use case ends.
Extensions
-
2a. There are no events.
Use case ends.
Use case: Clear all entries of events
MSS
- User requests to clear all entries of events in Focuris.
-
Focuris clears the entries of events.
Use case ends.
Extensions
-
1a. There are no events to be cleared.
Use case ends.
Use case: Exit Focuris
MSS
- User requests to exit Focuris.
-
Focuris closes.
Use case ends.
Non-Functional Requirements
- Should work on any mainstream OS as long as it has Java
11
or above installed. - Should be able to hold up to 1000 events without a noticeable sluggishness in performance for typical usage.
- A user with above average typing speed for regular English text (i.e. not code, not system admin commands) should be able to accomplish most of the tasks faster using commands than using the mouse.
Glossary
Mainstream OS: Windows, Linux, Unix, OS-X
Event: A task that needs to be completed by the user.
- An event consists of a title, description and identifier that we use to track each event.
- The stage of completion of an event can be split into four types:
- Backlog
- Todo
- In Progress
- Done
- An event can also have three different degrees of priorities:
- High
- Medium
- Low
Backlog: A set of events that the user has agreed to work on next. This could be events that are currently being planned to be worked on or pending or any upcoming events, but we leave the definition loose up to the user.
Todo: A set of events that the user has to work on as effective of immediately or have been delegated to already. We leave the definition loose up to the user.
In Progress: A set of events that the user is currently working on. We leave the definition loose up to the user.
Done: A set of events that the user has completed. This could be events that are currently being planned to be worked on or pending, but we leave the definition loose up to the user.
Kanban: Meaning signboard or billboard in Japanese. It is a method of managing and improving work flow across human systems. It is often used via a Kanban Board, where cards are used to represent work items and columns are used to represent each stage of the work process. An example of a Kanban Board is our application itself.
Sprint: A time-boxed iteration of a continuous development cycle, where a planned amount of work is completed by the team.
Appendix: Instructions for manual testing
Given below are instructions to test the app 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 with a set of sample contacts. The window size may not be optimum.
-
-
Saving window preferences
-
Resize the window to an optimum size. Move the window to a different location. Close the window.
-
Re-launch the app by double-clicking the jar file.
Expected: The most recent window size and location is retained.
-
Switching views
Switching Focuris’s view with switch.
-
Prerequisites: None.
-
Test case:
-
Open the app
Expected: the default view should be Kanban View. -
Execute
switch
Expected: the view should be switched. -
Execute
switch
again
Expected: the view should be switched back to the original one.
-
Opening the help
window
Opening the Focuris’s help
window in two ways.
-
Prerequisites: Launch Focuris successfully
-
Test case 1:
-
Switch to Kanban View.
-
Execute
help
Expected: thehelp
window should be opened. -
Close the
help
window using the mouse
Expected: only thehelp
window will be closed.
-
-
Test case 2:
-
Switch to List View.
-
Press
F1
Expected: thehelp
window should have opened. -
Select the app’s main window (either using your mouse or by pressing
Alt
+Tab
on your keyboard). -
Press
F1
again
Expected: thehelp
window should be selected again. -
Close the
help
window using the mouse
Expected: only thehelp
window will be closed.
-
Adding an event
Adding a event using the various log
, prog
, todo
commands.
-
Prerequisites: Launch Focuris successfully and clear all the events.
-
Test case 1:
-
Switch to Kanban View or List View.
-
Execute
log n/My Event d/Text
Expected: a new event with the name “My Event”, description “Text” and priority “low” should be added. (Since the priority is by default “low” if not specified)For the Kanban view, it is added into in the
Backlog
column. For the List view, theBacklog
tag will be shown. -
Execute
todo n/Event d/Des p/high
Expected: a new event with the correct fields should be added.For the Kanban view, it is added in the
Todo
column. For the List view, thetodo
tag will be shown.
-
-
Test case 2:
-
Execute
prog n/Event1 d/des
Expected: a new event with the correct fields should be added. -
Execute
log n/b
Expected: No event is added. The app should response with “Invalid command format! …” (since thedescription
field is missing). -
Execute
todo n/Event1 d/Description
Expected: No event is added. The app should response with “An Event with the same NAME …” (since an event with the same name already exists).
-
Deleting an event
Deleting an event while all events are being shown.
-
Prerequisites: List all events using the
list
command. Ensure that an event with the name “Event1” and identifier “1” is present (this may require you toclear
andexit
and restart the app) -
Test case 1:
-
Switch to List view or Kanban view.
-
Execute
delete 1
Expected: Event with identifier “1” is deleted from the list. Details of the deleted event shown in the status message. -
Execute
delete 0
Expected: No event is deleted. The app should response with “Identifier should be non-zero …”. -
Execute
delete x
where x is an identifier that does not exist in the in the list
Expected: No event is deleted. The app should response with “The event with an identifier of x does not exist.”. -
Execute
delete 1 n/Event1
Expected: No event is deleted. The app should response with “Please ensure your command matches with the guide …”
-
Editing events
Editing an event using the edit
command.
-
Prerequisite: Ensure that a backlog event with the name “Event1”, description “des”, priority “low”, and identifier “1” is present (this may require you to
clear
andexit
and restart the app) -
Test case 1:
-
Switch to Kanban view or List view.
-
Execute
edit 1 n/First Event p/high
Expected: The event will have a new name, priority according to the command. Details of the event are shown in the status message. -
Execute
edit 1 d/Description s/todo
Expected: The event will have a new description, and status according to the command. Details of the event are shown in the status message.For the Kanban View, the event will be moved to the
todo
column. For the List View, the tag will be updated fromBacklog
totodo
accordingly. -
Execute
edit n/name
Expected: No event is edited. The app should respond with “Identifier was not provided …”. -
Execute
edit 1
Expected: No event is edited. The app should respond with “At least one field to edit must be provided.”. -
Execute
edit x p/medium
where x is an identifier that does not exist in the in the list
Expected: No event is edited. The app should response with “The event with an identifier of x does not exist.”.
-
Completing an event using the done
command.
Setting an event to the status done
.
-
Prerequisite: Ensure that a backlog event with the identifier “1” is present (this may require you to
clear
andexit
and restart the app) -
Test case 1:
-
Switch to Kanban view or List view.
-
Execute
done 1
Expected: The event will have an updated status of DONE. Details of the event are shown in the status message.For the Kanban View, the event will be moved to the
done
column. For the List View, the tag will be updated fromBacklog
todone
accordingly. -
Execute
done 1
again
Expected: No event is moved. The app should respond with “This event is already Done.”. -
Execute
done
Expected: No event is moved. The app should respond with “Identifier was not provided …”. -
Execute
done x
where x is an identifier that does not exist in the in the list
Expected: No event is moved. The app should response with “The event with an identifier of x does not exist.”.
-
Finding events based on keyword
Finding events using the find
command.
-
Prerequisite: The app has 3 events: an event named “name1” with description “des1”, an event named “me12” with description “description” and an event named “event12” with description “description”.
-
Test case:
-
Execute
find name1
Expected: the event “name1” is listed. -
Execute
find w
Expected: no events are listed. -
Execute
find description
Expected: the event “me12” and the event “event12” are listed.
-
Listing all events
Listing all events using the list
command.
-
Prerequisite: Same prerequisite used above for finding events.
-
Test case:
-
Execute
find name1
, now 1 event should be listed. -
Execute
list
Expected: all 3 events are listed. -
Execute
list
again
Expected: all 3 events are still listed.
-
Clearing all events
Clearing all current events in the view.
-
Prerequisite: The app have some events.
-
Test case:
-
Execute
clear
Expected: All events are cleared. -
Add some events to the app.
-
Execute
clear all
again
Expected: No event is deleted. The app response with “Please remove extra irrelevant arguments!”.
-
Exiting Focuris
Exiting the app and closing the window.
-
Prerequisite: The app is successfully opened.
-
Test case 1:
- Execute
exit
Expected: The app’s window is closed.
- Execute
Saving data
Dealing with missing/corrupted data files
-
Prerequisite: The app have some events.
-
Test case 1:
-
Close the app.
-
Edit the
eventbook.json
file by editing the description field of some event into “event description”. -
Open the app again
Expected: The change should be reflected in the app.
-
-
Test case 2:
-
Close the app.
-
Edit the
eventbook.json
file by editing the eventName field of some event into “@”. -
Open the app again
Expected: The app now will have no event on it (since “@” is not a valid name for the event).
-