By: SC09-F14-3      Since: Aug 2019      Licence: MIT
1. Setting up
Refer to the guide here.
2. Design
2.1. Architecture
 
The Architecture Diagram given above explains the high-level design of the App.
- 
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 method where necessary. 
Commons represents a collection of classes used by multiple other components.
The following class plays an important role at the architecture level:
- 
LogsCenter: Used by many classes to write log messages to the App’s log file.
The rest of the App consists of four components
The first four components
- 
Defines its API in an interfacewith the same name as the Component.
- 
Exposes its functionality using a {Component Name}Managerclass.
For example, the Logic component (see the class diagram given below) defines it’s API in the Logic.java interface and exposes its functionality using the LogicManager.java class.
 
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 i/1.
 
delete i/1 commandThe sections below give more details of each component.
2.2. UI component
 
API : Ui.java
The UI consists of a MainWindow that is made up of parts e.g.CommandBox, ResultDisplay, EngagementListPanel, StatusBarFooter, HelpWindow
, Tab, TabListPanel, 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.
The UI component,
- 
Executes user commands using the Logiccomponent.
- 
Listens for changes to Modeldata so that the UI can be updated with the modified data.
2.3. Logic component
 
| The package state contains additional packages that represent state machines for each Command. These packages have been
omitted for brevity.XYZ refers to any arbitrary command. For example: XYZEndStatecan beAddEndStateandXYZCommandcan beAddCommand. | 
API :
Logic.java
- 
Logicuses theInteractiveParserclass to parse the user command.
- 
This results in a Commandobject which is executed by theLogicManager.
- 
The command execution can affect the Model(e.g. adding a person).
- 
The result of the command execution is encapsulated as a CommandResultobject which is passed back to theUi.
- 
In addition, the CommandResultobject can also instruct theUito perform certain actions, such as displaying help to the user.
2.4. Model component
 
API : Model.java
The Model,
- 
stores a UserPrefobject that represents the user’s preferences.
- 
stores the engagement list data. 
- 
exposes an unmodifiable ObservableList<Engagement>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. 
2.5. Storage component
 
API : Storage.java
The Storage component,
- 
can save UserPrefobjects in json format and read it back.
- 
can save the engagement list data in json format and read it back. 
2.6. Common classes
Classes used by multiple components are in the com.typee.commons package.
3. Implementation
This section describes some noteworthy details on how certain features are implemented.
3.1. Tab Switch Feature
Tab switch feature is a type of Command that allows users to switch to respective windows for using different features in the system.
Tab switch function is implemented in using both CLI and GUI approach; user can execute tab-switch by typing command in the input text-area or by interaction with the UI component (Button).
3.1.1. Implementation Structure
 
- 
User is required to use a Command;TabCommandin order to switch the window to another window.- 
Upon first startup of the system, system will display the EngagementListwindow by default.
 
- 
- 
New Ui Model class Tabis implemented to contain the respective fxml controller classes in a OOP manner.
MainWindow will have an additional method fetchTabInformation(tabName). After the parser executes the TabCommand, it will return a CommandResult with Tab property.
System will then check whether the input name matches with one of the tab names in the system. If there is a match, system will fetch the tab information and return the Tab object. If no match is found, system will return with an empty tab with only name attached.
3.2. Undo/Redo feature
3.2.1. Implementation
The undo/redo mechanism is facilitated by HistoryManager.
It extends EngagementList with an undo/redo history, stored internally as an historyList and versionPointer.
Additionally, it implements the following operations:
- 
HistoryManager#saveState()— Saves the current engagement list state in its history.
- 
HistoryManager#undo()— Restores the previous engagement list state from its history.
- 
HistoryManager#redo()— Restores a previously undone engagement list state from its history.
These operations are exposed in the Model interface as Model#saveEngagementList(), Model#undoEngagementList() and Model#redoEngagementList() respectively.
Given below is an example usage scenario and how the undo/redo mechanism behaves at each step.
Step 1. The user launches the application for the first time. The HistoryManager will be initialized with the initial engagement list state, and the versionPointer pointing to that single engagement list state.
 
Step 2. The user executes delete i/5 command to delete the 5th person in the engagement list. The delete command calls Model#saveEngagementList(), causing the modified state of the engagement list after the delete 5 command executes to be saved in the historyList, and the versionPointer is shifted to the newly inserted engagement list state.
 
Step 3. The user executes add t/meeting … to add a new engagement. The add command also calls Model#saveEngagementList(), causing another modified engagement list state to be saved into the historyList.
 
| If a command fails its execution, it will not call Model#saveEngagementList(), so the engagement list state will not be saved into thehistoryList. | 
Step 4. The user now decides that adding the person was a mistake, and decides to undo that action by executing the undo command. The undo command will call Model#undoEngagementList(), which will shift the versionPointer once to the left, pointing it to the previous engagement list state, and restores the engagement list to that state.
 
| If the versionPointeris at index 0, pointing to the initial engagement list state, then there are no previous engagement list states to restore. Theundocommand usesModel#hasNoUndoableCommand()to check if this is the case. If so, it will return an error to the user rather than attempting to perform the undo. | 
The following sequence diagram shows how the undo operation works:
 
| The lifeline for UndoCommandandUndoStateshould end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram. | 
The redo command does the opposite — it calls Model#redoEngagementList(), which shifts the versionPointer once to the right, pointing to the previously undone state, and restores the engagement list to that state.
| If the versionPointeris at indexhistoryList.size() - 1, pointing to the latest engagement list state, then there are no undone engagement list states to restore. Theredocommand usesModel#hasNoRedoableCommand()to check if this is the case. If so, it will return an error to the user rather than attempting to perform the redo. | 
Step 5. The user then decides to execute the command sort p/start o/ascending. Commands that do not modify the engagement list, such as sort, will usually not call Model#saveEngagementList(), Model#undoEngagementList() or Model#redoEngagementList(). Thus, the historyList remains unchanged.
 
Step 6. The user executes clear, which calls Model#saveEngagementList(). Since the versionPointer is not pointing at the end of the historyList, all engagement list states after the versionPointer will be purged. We designed it this way because it no longer makes sense to redo the add d/meeting … command. This is the behavior that most modern desktop applications follow.
 
The following activity diagram summarizes what happens when a user executes a new command:
 
3.2.2. Design Considerations
Aspect: How undo & redo executes
- 
Alternative 1 (current choice): Saves the entire engagement list. - 
Pros: Easy to implement. 
- 
Cons: May have performance issues in terms of memory usage. 
 
- 
- 
Alternative 2: Individual command knows how to undo/redo by itself. - 
Pros: Will use less memory (e.g. for delete, just save the person being deleted).
- 
Cons: We must ensure that the implementation of each individual command are correct. 
 
- 
Aspect: Data structure to support the undo/redo commands
- 
Alternative 1 (current choice): Use a list to store the history of engagement list states. - 
Pros: Easy to implement. 
- 
Cons: Logic is duplicated twice. For example, when a new command is executed, we must remember to update both historyListandengagementList.
 
- 
- 
Alternative 2: Use jdeveloper.history.HistoryManagerfor undo/redo- 
Pros: We do not need to maintain a separate list, and just reuse what is already in the codebase. 
- 
Cons: Requires dealing with commands that have already been undone: We must remember to skip these commands. Violates Single Responsibility Principle and Separation of Concerns as HistoryManagernow needs to do two different things.
 
- 
3.3. Sort feature
3.3.1. Implementation
The sort mechanism is facilitated by EngagementComparator.
The EngagementComparator is an enum class that implements Java Comparator<Engagement> and specifies the comparing logic of 8 different orders, namely START_TIME, START_TIME_REVERSE, END_TIME, END_TIME_REVERSE, ALPHABETICAL, ALPHABETICAL_REVERSE, PRIORITY, and PRIORITY_REVERSE.
Each positive sequence comparator compares two Engagements with the field specified within its name in ascending order, and _REVERSE comparators compare in descending order.
Additionally, the Model interface is modified to support the following methods:
- 
Model#setComparator(Comparator<Engagement>)— Sets the designated comparator in model.
- 
Model#updateSortedEngagementList()— Executes the sorting method with thecurrentComparatorin model to sort the internal list.
- 
Model#getSortedEngagementList()— Returns the current internal engagement list as an unmodifiableObservableList.
These operations are implemented in the ModelManager class as ModelManager#setComparator(Comparator<Engagement>), ModelManager#updateSortedEngagementList() and ModelManager#getSortedEngagementList() respectively.
Given below is an example usage scenario and how the sort mechanism behaves at each step.
Step 1. The user launches the application for the first time. The currentComparator will be initialized as null.
 
Step 2. The user executes sort p/priority o/ascending command to sort the engagement list in ascending order of priority. The sort command calls Model#setComparator(), causing the currentComparator in ModelManager to assume the value EngagementComparator#PRIORITY. The command then calls Model#updateSortedEngagementList to execute the sorting.
 
| The parsing of sortfollows the interactive parsing structure Typee adopts, where various stages are created while parsing. See Sequence Diagram below. | 
The following sequence diagram shows how the sort operation works:
 
| The lifeline for SortCommandand the 3 Stages should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram. | 
Step 3. The user executes add t/meeting … p/high to add a new engagement. The add command also calls Model#updateSortedEngagementList() with currentComparator, causing the execution of sorting after the new engagement is added to the list, to preserve the current ordering.
 
| If the currentComparatorassumes the initial valuenullwhenModel#updateSortedEngagementListis called, the method will simply catch theNullPointerExceptionthrown byjava.object.requireNonNullwhich will essentially abort the attempt to sort with an empty catch block. The initial chronological order is preserved in this case. | 
Step 5. The user then decides to execute the command list. Commands that do not modify the engagement list or alter the order of the list, such as list, will usually not call Model#setComparator(Comparator<Engagement>), or Model#updateSortedEngagementList(). Thus, the internal ObservableList remains unchanged.
 
The following activity diagram summarizes what happens when a user executes a new command:
 
3.3.2. Design Considerations
Aspect: How sort executes
- 
Alternative 1 (current choice): Use the List.sort(Comparator<T>)function to sort the list.- 
Pros: Has trivial support for features that updates the predicate of FilteredList, likeFind.
- 
Cons: There is a need to sort the list each time a command that modifies the elements of the list is executed, which may result in performance issues in case the list size is large. 
 
- 
- 
Alternative 2: Replace the FilteredListinModelManagerwith aSortedList.- 
Pros: Sorting the list is more intuitive, and the ordering of the engagements is automatically preserved whenever a command that modifies the list elements is executed. 
- 
Cons: Features like findcommand may lose functionality and needs extra modification.
 
- 
3.4. Engagement Report Generation
This feature allows user to generate a pre-selected engagement in to a report and save it as a document file. The document file will be created in a .pdf format.
3.4.1. Implementation Structure
 
The feature will be implemented as an additional type of Command; PdfCommand
- 
Proposed syntax of the PdfCommand is as follow: pdf i/ENGAGEMENT_LIST_INDEX t/RECEIVER f/SENDER.
Util class PdfUtil will be implemented for handling all pdf document creation related methods. It will be implemented under util package and it will be able to deliver few essential features
that are necessary for document creation.
- 
Able to generate a full report document based on the Engagementas input.
- 
Use different templates for each other types of Engagementsuch asAppointment,InterviewandMeeting. Document template will follow general email format: Receiver, Engagement Information written in a table, Sender and signature with address and company logo.To fulfill the document format, Reportclass needs to be implemented in order to model all necessary properties that has to be in the document. It 3 following properties;- 
engagement: specific engagement information to include in the document
- 
to: APersonwho is receiving the document
- 
from: APersonwho is either a receptionist or a secretary who is sending the document.
 
- 
Below is the sequence diagram for document generation which displays the concept of how this feature will be implemented by multiple interaction between different architecture components.
 
3.4.2. UI Design
ReportWindow will be the UI container which helps the user to interact using PdfCommand.
The window will include dynamic tree-view that is directly linked to the external directory in the file-system; reports/
UI Components & Features
Table below explains the components that are included in the ReportWindow with its purpose and features.
| UI Component | Feature | Purpose | |
|---|---|---|---|
| 
 | Button | Refreshes the tree-view file directory. | To help user refresh the directory when there is a system glitch or when document (.pdf) is manually added in the  | 
| 
 | Button | Deletes the selected document item in the tree-view file directory. | To assist users who prefer using mouse instead of typing command in keyboard can delete documents easily. | 
| 
 | Scrollable Tree View | 1. Displays the list of document generated previously and stored under the directory  2. Each list item is clickable with a mouse click action of opening the document. | To allow user to manage documents more time efficiently. | 
3.5. Calendar Window
The CalendarWindow provides a visual representation of stored engagements over a monthly period.
Users can choose to change the month being displayed and also open scrolling text windows which
show more detailed descriptions of the stored engagements for a particular day.
3.5.1. Implementation Structure
 
The CalendarWindow is part of the MainWindow. Specifically, it is one possible Tab which can be
displayed. The CalendarWindow class and any of its associated UI components can be found under the com.typee.ui.calendar package.
The following sequence diagram shows the creation of a CalendarWindow instance when the user switches to the
calendar window tab.
 
3.5.2. UI Design
The CalendarWindow class was designed with the observer pattern in mind. The calendar’s display and any open engagements
list windows are automatically updated as engagements are added to or deleted from the application. CalendarDateCell and
EngagementListViewCell both have a reference to an ObervableList of engagements in order to conform to the observer pattern.
The following table shows all UI components which are used and their respective purposes.
| UI Component Type | Feature | Purpose | |
|---|---|---|---|
| 
 | GridPane | Displays a grid which represents 35 calendar dates. | Shows the user the days of the month which is currently being displayed. | 
| 
 | StackPane | Displays the date of a single  | Provides the user with some general engagement information for a particular date. | 
| 
 | Button | Switches the calendar’s display to the previous month. | Allows the user to navigate to the previous month. | 
| 
 | Text | Indicates the month and year currently being displayed by the calendar window. | Informs the month and year currently being displayed by the calendar window. | 
| 
 | Button | Switches the calendar’s display to the next month. | Allows the user to navigate to the next month. | 
| 
 | ListView | Displays a list of engagements for a particular date. | Lets the user see more detailed information about all of his/her engagements for a particular date | 
| 
 | ListCell | Displays information for a single engagement. | Allows the user to see detailed information about a single engagement. This is used as the cell factory for ListView. | 
3.5.3. Command Execution Workflows
The following are the four commands which interact with CalendarWindow. They are accompanied by their respective activity diagrams
which are used to model their workflows:
- 
CalendarOpenDisplayCommand— Opens the engagements list window for the specified date.
 
- 
CalendarCloseDisplayCommand— Closes the engagements list window for the specified date.
 
- 
CalendarNextMonthCommand— Changes the calendar window’s display to the month after the currently displayed month.
 
- 
CalendarOpenDisplayCommand— Changes the calendar window’s display to the month prior to the currently displayed month.
 
3.5.4. Design Considerations
Aspect: Deciding whether to let engagements list windows from other months remain open when changing the displayed month
- 
Alternative 1 (current choice): Only engagements list windows from the current month can be opened. Switching to other months causes all opened engagements list windows to be closed. - 
Pros: Easier to implement and does not take up much memory. 
- 
Cons: Does not let users view engagement lists from different months simultaneously. 
 
- 
- 
Alternative 2: Letting engagements list windows remain open, regardless of the month, until they are closed by users. - 
Pros: Users are able to view side-by-side comparisons of their engagement lists across different months. 
- 
Cons: Introduces additional dependencies because many references to ObervableListinstances must be maintained.
 
- 
Aspect: Information being displayed in each calendar cell
- 
Alternative 1 (current choice): Only display the number of engagements for each date. - 
Pros: Does not take up a lot of on-screen space. More detailed information about each day’s engagements can be viewed by opening the engagements list window for that particular date. 
- 
Cons: The information shown in the calendar window is very generalized. 
 
- 
- 
Alternative 2: Display the descriptions (and maybe more detailed information) of each date’s engagements. - 
Pros: Shows more detailed information in the calendar window. 
- 
Cons: Might end up distorting the shape of the calendar window’s cells since some engagements have more information than others. The alternative would be to add fixed constraints to the size of each cell but then information would get cut off. 
 
- 
3.6. Game Feature
3.6.1. Implementation
The game feature is implemented using the singleton pattern using the singleton class GameWindow which is created
by button-click in StartWindow. This means that there can only be one gameInstance at any given time with the exception
of the game being over. The two diagrams below show the UML sequence diagram and activity diagram of the game window, which
gives a high level overview of the game.
 
 
GameWindow has three main components PlayerInformation, GameBody and Player.
 
The component GameBody makes use of javafx.animation.AnimationTimer API to continuously loop MovingWords objects moving from top
to bottom of the window using GameBody#loopWords(). MovingWords are created using
HighlighterUtil#convertToTextFlowUsing(String word)
, which appears as a TextFlow object of javafx.scene.text API.
Player input is represented as  a javafx.beans.property.StringProperty in Player.
Based on player input, MovingWords are updated using
HighlighterUtil#convertToTextFlowUsing(String playerInput, String word)
, which appears as a highlighted TextFlow object. In order to update the MovingWords object, the API
javafx.animation.AnimationTimer is used by calling MovingWords#continuouslyUpdate().
The component PlayerInformation is bound to Player using javafx.beans.property API and is also updated when
MovingWords#continuouslyUpdate() is called.
The table below summarises the various purposes of the 3 main Game Window UI components.
| UI Component Type | Feature | Purpose | |
|---|---|---|---|
| 
 | Scrollable Stack Pane | Displays the user’s score and health points. | To inform user about the in-game progress. | 
| 
 | AnchorPane | Displays the animation of the game. | To allow the user to view the animation of the moving words in a continuous manner. | 
| 
 | Scrollable Stack Pane | Displays the individual word. | To allow user to know the next word to type. | 
3.6.2. Design Considerations
Aspect: Singleton pattern design of Game Window
- 
Alternative 1 (current choice): Game Window with Singleton pattern design - 
Pros: - 
Prevent users from instantiating multiple Game Windows which may cause performance issues or even cause the application to crash. 
 
- 
- 
Cons: - 
Reduced testability as it is difficult to replace Singleton objects with stubs, and increased coupling across code base. 
 
- 
 
- 
- 
Alternative 2: Game Window without Singleton pattern design - 
Pros: Increased testability and reduced coupling. 
- 
Cons: There could be the risk of users being able to instantiate hundreds or thousands of GameWindows which would cause performance issues or application crash issues. 
 
- 
3.7. Interactive Parsing
3.7.1. Overview
Interactive parsing allows users to build a command sequentially, as opposed to doing it entirely in one shot. A user that wishes to
add an interview can simply type add t/interview to receive prompts on what to enter next.
This feature was conceived to make the application easy to use for amateur users.
3.7.2. Design & Implementation
Important Classes:
- 
InteractiveParser- The interface exposed toLogicManager. The parser implements this interface.
- 
Parser- A concrete implementation ofInteractiveParserthat enables interactive parsing.
- 
State- An abstract class that represents the individual states the application can be in while parsing and building aCommand.
- 
EndState- An abstract class that extends fromState. Represents the finalStateof a parsed command, from which aCommandobject can be built.
The interface InteractiveParser is the connecting interface between the LogicManager and the main Parser. This interface is
designed by contract (DbC - proposed by Bertrand Meyer). The interface exposes four methods to the LogicManager, namely:
- 
parseInput()- Parses the entered input.
- 
fetchResult()- Returns the response to be showed to the user in aCommandResultobject.
- 
hasParsedCommand()- Returns true if theParserhas finished parsing aCommandfully.
- 
makeCommand()- Makes and returns theCommandthe user intends to execute.
To achieve interaction, the Parser keeps track of the State of the current Command being built. State is an abstract class that represents
the individual states the application can be at in the midst of building a Command. EndState is an abstract class that extends from State,
from which Command objects can be built. As and when valid inputs are entered, the Parser updates
the current State to the subsequent States of the corresponding Command.
The Parser starts at an idle, inactive State Upon entering add t/meeting, the State being tracked is changed twice - first
to the State corresponding to the type of the Engagement and then to the State responsible for the start date-time.
Such State changes happen sequentially until all the arguments necessary for the Command have been supplied. When all necessary arguments are present,
the State being tracked transitions into an EndState. Once the tracked State transitions into an EndState, the Parser builds the Command
which is executed by the LogicManager.
The structure of the interactive parser is detailed in the UML diagram below.
 
State.| The above diagram only shows the component of the package Statethat handles thePdfCommand. The other packages have been
omitted for brevity. | 
Parsing of user entered inputs can be viewed as parsing a small, finite context-free language. The command built by a sequence of inputs
is uniquely determined by the sequence of inputs entered by the user and happens to be deterministic.
This observation allows the Parser to be modeled by a finite state machine. A finite state machine is an
abstract computational model which consists of a machine comprising several states. At a particular point in time, only one state
of the state machine is active. The machine transitions from one state to another state if certain conditions are met.
In the context of Typee’s Parser, the parser of each individual Command is a distinct finite state machine. The condition to be
satisfied to transition to another state is the validation of user-entered inputs.
The incorporation of state machines into the Parser is done by implementing a slightly modified version of the state pattern
documented by the Gang of Four (GoF).
Upon initiating the parsing (building) of a Command, the state machine that corresponds to the required Command is instantiated and set
to its initial state. This state becomes the State tracked by the Parser Subsequent inputs are tokenized by the ArgumentTokenizer class,
processed by the InputProcessor class and forwarded to the current State. If the input is deemed valid, the Parser invokes the transition()
method of the current State to proceed to the next State. This process is repeated until an EndState is reached. Throughout this process, the
user receives feedback from the Parser in the form of an encapsulated CommandResult object.
Below is a sequence diagram illustrating the processes that occur when the user enters add t/meeting s/15/11/2019/1500 e/15/11/2019/1600.
 
Parser parses the entered input and returns the result to the GUI in the form of a CommandResult object.| The sequence diagram incorrectly extends the life-line of the three destroyed Stateclasses. This is due to a limitation of PlantUML. | 
The high-level working of the Parser can be summarized by the activity diagram shown below.
 
| "parameter present" refers to the parameter required by a particular state. | 
3.7.3. Design Considerations
Aspect : Abstract model
- 
Alternative 1 (current design) : Finite state machine - 
Pros: - 
Highly flexible - Entire command, one argument at a time and multiple arguments at a time - all are supported. 
- 
Easily extensible - Adding a new command will require almost no changes in any of the existing classes. 
- 
Supports optional arguments with the help of the OptionalStateinterface.
 
- 
- 
Cons: - 
Tedious to implement a state machine for each individual command. 
 
- 
 
- 
- 
Alternative 2 : Use a list based implementation to keep track of arguments entered. - 
Pros: - 
Easy to implement and keep track of arguments 
 
- 
- 
Cons: - 
Very hard to implement optional states. 
- 
Cannot execute commands like Helpat any point in time without hard-coding it in theParser.
 
- 
 
- 
3.8. Logging
We are using java.util.logging package for logging. The LogsCenter class is used to manage the logging levels and logging destinations.
- 
The logging level can be controlled using the logLevelsetting in the configuration file (See Section 3.9, “Configuration”)
- 
The Loggerfor a class can be obtained usingLogsCenter.getLogger(Class)which will log messages according to the specified logging level
- 
Currently log messages are output through: Consoleand to a.logfile.
Logging Levels
- 
SEVERE: Critical problem detected which may possibly cause the termination of the application
- 
WARNING: Can continue, but with caution
- 
INFO: Information showing the noteworthy actions by the App
- 
FINE: Details that is not usually noteworthy but may be useful in debugging e.g. print the actual list instead of just its size
3.9. Configuration
Certain properties of the application can be controlled (e.g user prefs file location, logging level) through the configuration file (default: config.json).
4. Documentation
Refer to the guide here.
5. Testing
Refer to the guide here.
6. Dev Ops
Refer to the guide here.
Appendix A: Product Scope
Target user profile:
- 
receptionists / secretaries in corporations. 
- 
can type fast 
- 
prefers typing over mouse input 
- 
is reasonably comfortable using CLI apps 
- 
requires submitting large amount of structured reports or documents 
Value proposition: increase productivity by managing appointments faster than a typical mouse/ GUI driven app and by increasing typing speed.
Appendix B: User Stories
Priorities: High (must have) - * * *, Medium (nice to have) - * *, Low (unlikely to have) - *
| Priority | As a … | I want to … | So that I can… | 
|---|---|---|---|
| 
 | secretary | add an appointment | organise and schedule meetings/appointments | 
| 
 | secretary | request ro edit a specific appointment | fix any misinformation that I typed wrongly | 
| 
 | secretary under a busy manager | find specific appointments fast | schedule appointments efficiently | 
| 
 | secretary | have the option to clear the appointment list | restart from scratch | 
| 
 | secretary | undo my previous commands | recall commands made by mistake | 
| 
 | secretary | redo recalled commands | retrieve the commands undone by mistake | 
| 
 | secretary | select and delete a specific appointment from the list | manage inactive or cancelled appointments | 
| 
 | busy secretary | able to see the appointments in calendar view | enjoy better convenience | 
| 
 | user | save and load data from a local file | keep the appointment list locally | 
| 
 | secretary under a busy manager | sort all appointments | see them in the order I want | 
| 
 | user | have a command to terminate the application | |
| 
 | advanced user | be able to execute compound statements | improve efficiency | 
| 
 | highly motivated secretary | have a typing warm-up | prepare myself for an important events like important meetings. | 
| 
 | highly driven secretary | have a way to practice typing | improve my efficiency during work by increasing my typing speed | 
| 
 | fast-typer | have a way to amend trivial spelling errors | improve typing efficiency | 
| 
 | secretary | generate a PDF file of a selected appointment | make a distributable copy of the appointment | 
Appendix C: Use Cases
(For all use cases below, the System is the Typee and the Actor is the user,
unless specified otherwise)
Use case: (UC01) Add appointment
MSS
- 
User requests to add an appointment. 
- 
System adds the corresponding appointment to the existing appointment list. 
- 
System displays the updated appointment list and notifies the user. Use case ends 
Extensions
- 
1a. User supplies the necessary information. Use case ends 
- 
1b. User supplies invalid information. - 
1b1. System notifies user about the invalid information. Use case ends 
 
- 
- 
1c. Appointment clashes with an existing appointment. - 
1c1. System notifies user about the conflict. Use case ends 
 
- 
Use case: (UC02) List appointments
MSS
- 
User requests to list appointments 
- 
System displays the list of appointments Use case ends. 
Extensions
- 
1a. The list of appointments is empty Use case ends. 
- 
2a. The list is empty Use case ends. 
Use case: (UC03) Find appointment
MSS
- 
User requests to find appointments 
- 
User provides fields that the user wants to use to find appointments 
- 
System finds and displays the list of relevant appointments Use case ends. 
Extensions
- 
2a. The list is empty. Use case ends. 
Use case: (UC04) Delete appointment
MSS
- 
User requests to list appointments 
- 
System displays the list of appointments 
- 
User requests to delete a specific appointment in the list 
- 
System deletes the appointment Use case ends. 
Extensions
- 
2a. The list is empty. Use case ends. 
- 
3a. The given index is invalid. - 
3a1. System shows an error message. Use case resumes at step 2. 
 
- 
Use case: (UC05) Exit application
MSS
- 
User requests to exit the application 
- 
System displays exit message 
- 
System exits Use case ends 
Use case: (UC06) Request help information
Use case: (UC07) Save updated Appointment data
MSS
- 
User make changes in the appointment list, or a specific appointment via CRUD. 
- 
System saves the updated data 
- 
System displays the updated appointment data Use case ends 
Use case: (UC08) Edit selected appointment
MSS
- 
User requests to list appointments 
- 
System displays the list of appointments 
- 
User keys in index and provide fields that the user wants to edit 
- 
System edits the selected appointment accordingly Use case ends. 
Extensions
- 
2a. The list is empty Use case ends. 
- 
3a. User keys in invalid index - 
3a1. System shows error message. Use case resumes at step 2. 
 
- 
- 
3b. User does not provide any field to edit. - 
3b1. System shows error message. Use case resumes at step 2. 
 
- 
Use case: (UC09) Undo previous command
MSS
- 
User requests to undo command 
- 
System reverts the appointment list to its previous state Use case ends. 
Extensions
- 
2a. There is no previous command Use case ends. 
Use case: (UC10) Redo previous command
MSS
- 
User requests to redo command 
- 
System reverts the appointment list to its previous undone state Use case ends. 
Extensions
- 
2a. There is no previous undone command Use case ends. 
Use case: (UC11) Switch tabs
MSS
- 
User requests to switch to a specified tab. 
- 
System switches to the appropriate tab. Use case ends. 
Extensions
- 
1a. Requested tab is invalid. - 
1a1. System shows error message. Use case resumes at step 1. 
 
- 
Use case: (UC12) Calendar mode
MSS
- 
User specifies a date to view engagements for. 
- 
System shows the engagements for the specified date. 
Extensions
- 
1a. User specifies an invalid date. - 
1a1. System shows error message. Use case resumes at step 1. 
 
- 
Use case: (UC13) Calendar mode month switching
MSS
- 
User specifies a month to switch the display to. 
- 
System updates the calendar view to display appointments for the specified month. 
Extensions
- 
1a. User specifies an invalid month. - 
1a1. System shows error message. Use case resumes at step 1. 
 
- 
Use case: (UC14) Typing game
MSS
- 
User requests to start the typing game 
- 
System shows typing game window which displays the specific word(s) to type. 
- 
User plays the game by typing the word(s). 
- 
Typing game updates the User’s score and health points accordingly. Steps 2-4 are repeated for as many rounds as required until User runs out of health points. 
- 
Typing game shows the final score of the User when the game ends. Use case ends. 
Extensions
- 
2a. User exits game Use case ends. 
Use case: (UC15) Generate appointment document in PDF format
MSS
- 
User enters information for generating PDF of an engagement for a selected engagement. 
- 
System generates a PDF file in a specific external directory 
- 
System shows successful message 
- 
System opens the generated document. Use case ends. 
Extensions
- 
2a. System receives invalid input. - 
2a1. System shows error message. Use case resumes at step 1. 
 
- 
- 
2b. User inputs duplicate information that already exists in the directory. - 
2b1. System shows error message. Use case resumes at step 1. 
 
- 
Use case: (UC16) Sort appointments
MSS
- 
User requests to sort appointments 
- 
User specifies the property to sort regarding to 
- 
User specifies the order of ascending or descending 
- 
System sorts the list of appointments by the specified order Use case ends. 
Extensions
- 
2a. User does not specify property - 
2a1. System shows error message Use case ends. 
 
- 
- 
2b. User specifies an invalid property - 
2b1. System shows error message Use case ends. 
 
- 
- 
3a. User does not specify order - 
3a1. System shows error message Use case ends. 
 
- 
- 
3b. User specifies an invalid order - 
3b1. System shows error message Use case ends. 
 
- 
Appendix D: Non Functional Requirements
- 
Should work on any mainstream OS as long as it has Java 11or above installed.
- 
Should come with automated unit tests and open source code. 
- 
Should work on both 32-bit and 64-bit environments. 
- 
Application should not exceed 100MB in size. 
- 
Should be able to hold up to 1000 persons without a noticeable sluggishness in performance for typical usage. 
- 
A user with above average typing speed for regular English text (i.e. not code, not system admin commands) should be able to accomplish most of the tasks faster using commands than using the mouse. 
Appendix E: Glossary
- Mainstream OS
- 
Windows, Linux, Unix, OS-X 
- Secretary
- 
A person employed by an individual or in an office to assist with correspondence, make appointments, and carry out administrative tasks. 
- Manager
- 
The person that the secretary is assigned to work for. 
- Engagement
- 
An arrangement, meeting or interview managed and maintained by a secretary, for the manager to meet someone at a particular time and place. 
Appendix F: Instructions for Manual Testing
Given below are instructions to test the app manually.
| These instructions only provide a starting point for testers to work on; testers are expected to do more exploratory testing. | 
F.1. Launch and Shutdown
- 
Initial launch - 
Download the jar file and copy into an empty folder 
- 
Double-click the jar file 
 Expected: Shows the GUI with a set of sample contacts. The window size may not be optimum.
 
- 
- 
Saving window preferences - 
Resize the window to an optimum size. Move the window to a different location. Close the window. 
- 
Re-launch the app by double-clicking the jar file. 
 Expected: The most recent window size and location is retained.
 
- 
F.2. Adding an engagement
(i) Test case: add t/meeting s/16/11/2019/1500 e/16/11/2019/1600 l/Meeting Room 2 d/Team Meeting a/John | Smith p/High
Expected: Status bar shows the successful addition of engagement with its details. The engagement list is updated accordingly.
(ii) Test case: add t/ s/16/11/2019/1500 e/16/11/2019/1600 l/Meeting Room 2 d/Team Meeting a/John | Smith p/High
Expected: The engagement is not added. Status bar shows prompt for a valid engagement type due to invalid engagement type.
(iii) Test case: add t/meeting s/ e/16/11/2019/1600 l/Meeting Room 2 d/Team Meeting a/John | Smith p/High
Expected: The engagement is not added. Status bar shows prompt for a valid start time due to invalid start time.
(iv) Test case: add t/meeting s/16/11/2019/1500 e/ l/Meeting Room 2 d/Team Meeting a/John | Smith p/High
Expected: The engagement is not added. Status bar shows prompt for a valid end time due to invalid end time.
(v) Test case: add t/meeting s/16/11/2019/1500 e/16/11/2019/1600 l/ d/Team Meeting a/John | Smith p/High
Expected: The engagement is not added. Status bar shows prompt for a valid location due to invalid location.
(vi) Test case: add t/meeting s/16/11/2019/1500 e/16/11/2019/1600 l/Meeting Room 2 d/ a/John | Smith p/High
Expected: The engagement is not added. Status bar shows prompt for due to invalid description.
(vii) Test case: add t/meeting s/16/11/2019/1500 e/16/11/2019/1600 l/Meeting Room 2 d/Team Meeting a/ p/High
Expected: The engagement is not added. Status bar shows prompt for a valid attendees due to invalid attendees.
(vii) Test case: add t/meeting s/16/11/2019/1500 e/16/11/2019/1600 l/Meeting Room 2 d/Team Meeting a/John | Smith p/高
Expected: The engagement is not added. Status bar shows prompt for a valid priority due to invalid priority.
(viii) Test case:
The sequence of commands is as follows:
add
t/meeting
s/16/11/2019/1500
e/16/11/2019/1600
l/Meeting Room 2
d/Team Meeting
a/John | Smith
p/HighExpected: Status bar shows the successful addition of engagement with its details. The engagement list is updated accordingly.
(ix) Test case:
The sequence of commands is as follows:
add
t/appointment
s/01/01/2019/0900
e/01/01/2019/1000
l/Meeting Room 3
d/Team Discussion
a/John Smith
p/NoneExpected: Status bar shows the successful addition of engagement with its details. The engagement list is updated accordingly.
(x) Test case:
The sequence of commands is as follows:
add
t/meeting
s/16/11/2019/1500
e/16/11/2019/1600
l/Meeting Room 2
d/Team Meeting
a/John | Smith
p/😄Expected: The engagement is not added. Status bar shows prompt for a valid priority due to invalid priority.
F.3. Listing an engagement
(i) Test case: list
Expected: Status bar shows the successful listing of engagement. The full engagement list is shown.
(ii) Test case: 123 list
Expected: Status bar shows the successful listing of engagement. The full engagement list is shown.
(iii) Test case: list 123
Expected: Status bar shows the successful listing of engagement. The full engagement list is shown.
F.4. Deleting an engagement
(i) Test case: delete i/3
Expected: If there are 3 or more engagements in the engagement list, the 3rd engagement is deleted. Status bar shows the successful deletion of engagement with its details. The engagement list is updated accordingly. Otherwise, the engagement is not deleted due to invalid index.
(ii) Test case:
The sequence of commands is as follows:
delete
i/3Expected: If there are 3 or more engagements in the engagement list, the 3rd engagement is deleted. Status bar shows the successful deletion of engagement with its details. The engagement list is updated accordingly. Otherwise, the engagement is not deleted due to invalid index.
(ii) Test case: delete i/-1
Expected: The engagement is not deleted due to invalid index.
(iii) Test case:
The sequence of commands is as follows:
delete
i/-1Expected: The engagement is not deleted due to invalid index.
F.5. Finding an engagement
(i) Test case: find d/Singapore based
Expected: Engagements containing description keyword will be shown. e.g.  will show
all engagements containing the description Singapore based.
e.g. singapore based internship appointment, Singapore based project meeting
(ii) Test case:
The sequence of commands is as follows:
find
d/Singapore basedExpected: Engagements containing description keyword will be shown. e.g.  will show
all engagements containing the description Singapore based.
e.g. singapore based internship appointment, Singapore based project meeting
(iii) Test case: find l/Com Basement
Expected: Engagements matching the full exact keyword will be shown. e.g. will show
all engagements containing the location Com Basement. Note that engagement with location Basement Room 6 will not be shown.
(iv) Test case:
The sequence of commands is as follows:
find
l/Com BasementExpected: Engagements matching the full exact keyword will be shown. e.g. will show
all engagements containing the location Com Basement. Note that engagement with location Basement Room 6 will not be shown.
(v) Test case: find a/Hans
Expected: Engagements containing attendee keyword will be shown. e.g. find a/Hans will show
all engagements containing the attendee Hans.
e.g. Hansen Gruber, hans christian
(vi) Test case: find a/Hans
The sequence of commands is as follows:
find
a/HansExpected: Engagements containing attendee keyword will be shown. e.g. find a/Hans will show
all engagements containing the attendee Hans.
e.g. Hansen Gruber, hans christian
(vii) Test case: find p/High
Expected: Engagements containing high priority will be shown.
(viii) Test case:
The sequence of commands is as follows:
find
p/HighExpected: Engagements containing high priority will be shown.
(ix) Test case: find a/Hans p/high
Expected: Engagements containing the attendee Hans and with high priority will be shown.
(ix) Test case:
The sequence of commands is as follows:
find
a/Hans p/high`Expected: Engagements containing the attendee Hans and with high priority will be shown.
F.6. Sorting the engagement list
(i) Test case:
The sequence of commands is as follows:
sort
p/start
o/ascendingExpected: The list should be sorted in ascending order of start time.
(ii) Test case: Executing the sort command by giving all attributes at once
sort p/start o/ascendingExpected: This should give the exact same result as the previous stepwise command.
F.7. Undo and Redo
(i) Test case: Executing the undo command
The sequence of commands is as follows:
delete i/1 (provided there is at least 1 engagement in the list)
undoExpected: The previously deleted engagement should reappear in the list.
(ii) Test case: Executing the redo command
The sequence of commands is as follows:
delete i/1 (provided there is at least 1 engagement in the list)
undo
redoExpected: The recovered engagement should disappear in the list.
F.8. Calendar commands
All listed commands assume that the application is in the calendar tab.
(i) Test case:
The sequence of commands is as follows:
calendar c/opendisplay d/11/11/2019Expected: The engagements display window for 11/11/2019 opens up.
(ii) Test case:
The sequence of commands is as follows:
calendar c/closedisplay d/11/11/2019Expected: When executed immediately after executing the command in (i), the engagements display window for 11/11/2019 closes.
(iii) Test case:
The sequence of commands is as follows:
calendar c/opendisplay d/10/10/2019Expected: The calendar window switches from the currently displayed month (assuming that it is not displaying October 2019) to October 2019. The engagements display window for 10/10/2019 opens up.
(iii) Test case:
The sequence of commands is as follows:
calendar c/nextmonthExpected: All open engagements list windows are closed and the calendar displays the month after the currently displayed month.
(iv) Test case:
The sequence of commands is as follows:
calendar c/previousmonthExpected: All open engagements list windows are closed and the calendar displays the month prior to the currently displayed month.
F.9. Tab
(i) Test case: tab b/engagement
Expected: The current tab switches to engagement tab
(ii) Test case: tab b/calendar
Expected: The current tab switches to calendar tab
(iii) Test case: tab b/game
Expected: The current tab switches to game tab
(iv) Test case: tab b/report
Expected: The current tab switches to report tab
F.10. Game
(i) Test case: Click on Start button of the starting window of the game tab.
Expected: New game window opens.
(ii) Test case: Click on Close button of the game window.
Expected: Game window closes.
F.11. Generating PDF
(i) Test case:
pdf
i/1 (provided at least 1 engagement in the list)
f/Jason
t/Gi HunExpected: A PDF file is generated with the content of the first engagement in list, with sender set to Gi Hun and reciver set to Jason. The file can be seen in the documents explorer tree view.
(ii) Test case:
Click the refresh buttonExpected: Documents explorer tree view refreshes.
(iii) Test case:
Single click on an existing document in documents explorer tree view
Click the delete button
Select OK in pop-up dialogExpected: Selected document is deleted from directory.
(iv) Test case:
Double click on an existing document in documents explorer tree viewExpected: Selected document opens in the default .pdf file viewer