Developer Guide
- Introduction
 - Design
 - Implementation
 - Documentation, Logging, Testing, Configuration, Dev-Ops
 - Glossary
 - Appendices
 
Introduction
Ez-Schedule is a desktop application for managing and scheduling of events, optimized for use via a CLI while still providing an easy way to visualize all events through a GUI.
Ez-Schedule will benefit a fast typist who needs to plan and track upcoming events.
Acknowledgements
- This project is based on the AddressBook Level 3 (AB3) project created by the SE-EDU initiative.
 - Libraries used: JavaFX, JUnit5
 
Setting Up, Getting Started
Refer to the guide Setting Up and Getting Started.
Design
.puml files used to create diagrams in this document can be found in the 
diagrams folder. 
Refer to the PlantUML Tutorial at se-edu/guides 
to learn how to create and edit diagrams.
Architecture

The Architecture Diagram given above explains the high-level design of the App.
Given below is a quick overview of main components and how they interact with each other.
Main components of the architecture
Main has two classes called Main and MainApp.
It is responsible for,
- At app launch: Initializes the components in the correct sequence, and connects them up with each other.
 - At shut down: Shuts down the components and invokes cleanup methods where necessary.
 
Commons represents a collection of classes used by multiple other components.
The rest of the App consists of four components.
- 
UI: The UI of the App. - 
Logic: The command executor. - 
Model: Holds the data of the App in memory. - 
Storage: Reads data from, and writes data to, the hard disk. 
How the Architecture Components Interact With Each
The Sequence Diagram below shows how the components interact with each other for the scenario where the user issues 
the command delete 1.

Each of the four main components (also shown in the diagram above),
- defines its API in an 
interfacewith the same name as the Component. - implements its functionality using a concrete 
{Component Name}Managerclass (which follows the corresponding APIinterfacementioned in the previous point). 
For example, the Logic component defines its API in the Logic.java interface and implements its functionality using 
the LogicManager.java class which follows the Logic interface. Other components interact with a given component 
through its interface rather than the concrete class(reason: to prevent outside component’s being coupled to the 
implementation of a component), as illustrated in the (partial) class diagram below.

UI Component
API : Ui.java

The UI consists of a MainWindow that is made up of parts e.g.CommandBox, ResultDisplay, EventListPanel, 
StatusBarFooter etc. All these, including the MainWindow, inherit from the abstract UiPart class which captures 
the commonalities between classes that represent parts of the visible GUI.
The UI component uses the JavaFx UI framework. 
The layout of these UI parts are defined in matching .fxml files that are in the src/main/resources/view folder. 
For example, the layout of the MainWindow is specified in MainWindow.fxml.
The UI component,
- executes user commands using the 
Logiccomponent. - listens for changes to 
Modeldata so that the UI can be updated with the modified data. - keeps a reference to the 
Logiccomponent, because theUIrelies on theLogicto execute commands. - depends on some classes in the 
Modelcomponent, as it displaysEventobject residing in theModel. 
Logic Component
API : Logic.java
Here’s a (partial) class diagram of the Logic component:

How the Logic component works:
- When 
Logicis called upon to execute a command, it uses theSchedulerParserclass to parse the user command. - This results in a 
Commandobject (more precisely, an object of one of its subclasses e.g.,AddCommand) which is executed by theLogicManager. - The command can communicate with the 
Modelwhen it is executed (e.g. to add a event). - The result of the command execution is encapsulated as a 
CommandResultobject which is returned back fromLogic. 
The Sequence Diagram below illustrates the interactions within the Logic component for the execute("delete 1") API call.

DeleteCommandParser should end at the destroy marker (X) but due to a limitation of PlantUML,
the lifeline reaches the end of diagram.
Here are the other classes in Logic (omitted from the class diagram above) that are used for parsing a user command:

How the parsing works:
- When called upon to parse a user command, the 
SchedulerParserclass creates anXYZCommandParser(XYZis a placeholder for the specific command name e.g.,AddCommandParser) which uses the other classes shown above to parse the user command and create aXYZCommandobject (e.g.,AddCommand) which theAddressBookParserreturns back as aCommandobject. - All 
XYZCommandParserclasses (e.g.,AddCommandParser,DeleteCommandParser, …) inherit from theParserinterface so that they can be treated similarly where possible e.g, during testing. 
Model Component
API : Model.java

The Model component,
- stores the scheduler data i.e., all 
Eventobjects (which are contained in auniqueEventListobject). - stores the currently ‘selected’ 
Eventobjects (e.g., results of a search query) as a separate filtered list which is exposed to outsiders as an unmodifiableObservableList<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. - stores a 
UserPrefobject that represents the user’s preferences. This is exposed to the outside as aReadOnlyUserPrefobjects. - does not depend on any of the other three components (as the 
Modelrepresents data entities of the domain, they should make sense on their own without depending on other components) 
Storage Component
API : Storage.java

The Storage component,
- can save both scheduler data and user preference data in json format, and read them back into corresponding objects.
 - inherits from both 
SchedulerStorageandUserPrefStorage, which means it can be treated as either one (if only the functionality of only one is needed). - depends on some classes in the 
Modelcomponent (because theStoragecomponent’s job is to save/retrieve objects that belong to theModel) 
Common Classes
Classes used by multiple components are in the ezschedule.commons package.
Implementation
EZ-Schedule mainly follows the Command design pattern. Elaboration on how the application parses commands is given in the Architecture section above.
This section describes some noteworthy details on how certain features are implemented.
Add Command
For Add command, the noteworthy classes are:
- 
AddCommandParser.java- For parsing the arguments toAddCommand. - 
AddCommand.java- For execution. 
The following exceptions may be thrown during this process, namely:
- ParseException for missing arguments
 - ParseException for invalid arguments
 - InvalidDateException for correct syntax but invalid (do not exist) dates
 - CommandException for identical events
 - CommandException for events with clashing time
 
Given below is an example usage scenario of how the Add command executes.
– user input –
Step 1. User executes add command with correct and valid arguments.
– SchedulerParser –
Step 2. Returns new AddCommandParser.
– AddCommandParser – 
Step 3. Verify that all argument prefixes are present.
Step 4. Verify that all argument format is valid.
Step 5. Verify that the given event start time is before end time.
Step 6. Returns new AddCommand.
– AddCommand – 
Step 7. Verify that the same event has not already been added.
Step 8. Verify that the new event to be added does not have time conflict with another event on the same day.
Step 9. Event is added.
The execution can be seen in the activity diagram given below.
Activity Diagram for a typical add command

Recur Command
For Recur command, the noteworthy classes are:
- 
RecurCommandParser.java- For parsing the arguments toRecurCommand. - 
RecurCommand.java- For execution. 
The following exceptions may be thrown during this process, namely:
- ParseException for missing arguments
 - ParseException for invalid arguments
 - ParseException for index out of range
 - InvalidDateException for correct syntax but invalid (do not exist) dates
 - CommandException for end dates in the past
 - CommandException for recur factor exceeding max allowable
 
Given below is an example usage scenario of how the Recur command executes.
– user input – 
Step 1. User executes Recur command with correct and valid arguments.
– SchedulerParser –
Step 2. Returns new RecurCommandParser.
– RecurCommandParser –
Step 3. Verify that all argument prefixes are present.
Step 4. Verify that all argument format is valid.
Step 5. Returns new RecurCommand.
– RecurCommand –
Step 6. Verify that the given index exist in Ez-Schedule.
Step 7. Verify that the given recurring end time is not in the past.
Step 8. For the given recur factor, verify that it is valid.
Step 9. Check all dates for event to be recurred on for any event clash.
Step 10. Add event into Ez-Schedule on all dates to be recurred.
The execution, with Step 9 in further detail, can be seen in the activity diagrams given below.
Activity Diagram for a typical recur command

Activity: Check for time clash for all recurring dates.

Edit Command
For Edit command, the noteworthy classes are:
- 
EditCommandParser.java- For parsing the arguments toEditCommand. - 
EditCommand.java- For execution. 
The following exceptions may be thrown during this process, namely:
- ParseException for missing arguments
 - ParseException for invalid arguments
 - InvalidDateException for correct syntax but invalid (do not exist) dates
 - CommandException for index out of range
 - CommandException for identical events
 - CommandException for events with clashing time
 
Given below is an example usage scenario of how the Edit command executes.
– user input –
Step 1. User executes edit command with correct and valid arguments.
– SchedulerParser –
Step 2. Returns new EditCommandParser.
– EditCommandParser – 
Step 3. Verify that at least one of the argument prefixes is present.
Step 4. Verify that provided arguments are valid.   
Step 5. Returns new EditCommand.
– EditCommand – 
Step 6. Verify that the given index exist in Ez-Schedule.
Step 7. Verify that the same event has not already been added.
Step 8. Verify that the new event to be added does not have time conflict with another event on the same day.
Step 9. Event is edited.
The execution can be seen in the activity diagram given below.
Activity Diagram for a typical edit command

Delete Command
For Delete command, the noteworthy classes are:
- 
DeleteCommandParser.java- Parse the arguments forDeleteCommand - 
DeleteCommand.java- Execute command 
The following exceptions may be thrown during this process, namely:
- 
ParseExceptionfor missing arguments - 
ParseExceptionfor invalid arguments - 
CommandExceptionfor index exceeding list size 
Given below is an example usage scenario of how the Delete command executes.
– user input –
Step 1. User executes delete command with multiple valid arguments.
– SchedulerParser –
Step 2. Returns new DeleteCommandParser.
– DeleteCommandParser –
Step 3. Verifies that provided arguments is valid.
Step 4. Parses provided arguments into List<Index>.
Step 5. Returns new DeleteCommand.
– DeleteCommand – 
Step 6: Sorts and Reverses provided List<Index>.
Step 7: Verifies that none of the Index exceeds size of list of Event.
Step 8: Delete the Event(s) according the List<Index>.
Other alternative path of execution can be traced in the activity diagram below.
Activity Diagram for a typical delete command

Find Command
For Find command, the noteworthy classes are:
- 
FindCommandParser.java- For parsing the arguments toFindCommand. - 
FindCommand.java- For execution. 
The following exceptions may be thrown during this process, namely:
- ParseException for missing arguments
 - ParseException for invalid arguments
 - InvalidDateException for correct syntax but invalid (do not exist) dates
 
Given below is an example usage scenario of how the Find command executes.
– user input –
Step 1. User executes find command with correct and valid arguments.
– SchedulerParser –
Step 2. Returns new FindCommandParser.
– FindCommandParser –
Step 3. Verify that at least one of the argument prefixes is present.
Step 4. Verify that provided arguments are valid.
Step 5. Creates a FindEventDescriptor
Step 6. Returns new FindCommand.java using FindEventDescriptor.
– FindCommand –
Step 7. Determine if Name, Date or both are present from FindEventDescriptor.
Step 8. Create one of the following predicates, depending on the arguments provided: 
EventMatchesKeywordsAndDatePredicate, EventContainsKeywordsPredicate orEventMatchesDatePredicate.
Step 9. Updates the ObservableList using the predicate.
The execution can be seen in the activity diagram given below.
Activity Diagram for a typical find command

Next Command
To keep track of the next upcoming event, we have opted to keep Events sorted in chronological order.
Events are kept chronologically sorted by:
- 
Eventwas made comparable via aComparable<Event>interface. The comparison criteria areEvent#DateandEvent#StartTime. - In 
Scheduler, attached ajavafx.collections.ListChangeListenertoUniqueEventList(the underlying run-time storage of the list ofEvents) to know wheneverUniqueEventListis changed (possibly as a result ofadd,edit,delete, or even a sorting action). - When a change is detected, we would sort the 
Events viaFXCollections#sort. 
Sequence Diagram for how UniqueEventList maintains a chronological order of Event

For Next command, the noteworthy classes are:
- 
ShowNextCommandParser.java- Parse the arguments forShowNextCommand - 
ShowNextCommand.java- Execute command - 
UpcomingEventPredicate.java- Check ifEventshould be displayed as ongoing/upcoming 
During this process, ParseException may be thrown for invalid arguments.
No exception is thrown for no arguments, as there is a default behaviour.
Given below is an example usage scenario of how the Next command executes.
– user input –
Step 1. User executes next command with valid arguments.
– SchedulerParser –
Step 2. Returns new ShowNextCommandParser.
– ShowNextCommandParser –
Step 3. Verifies that provided argument is valid.
Step 4. Returns new ShowNextCommand.
– ShowNextCommand –
Step 5. Creates an UpcomingEventPredicate using the provided argument.
Step 6. Uses the created UpcomingEventPredicate to filter for ongoing/upcoming Event(s).
Step 7. Updates EventListPanel with filtered Event(s).
Other alternative path of execution can be traced in the activity diagram below.
Activity Diagram for a typical next command

Undo Command
For Undo command, the noteworthy classes are:
- 
UndoCommand.java- For execution. 
The following exceptions may be thrown during this process, namely:
- CommandException for attempting to execute undo when recent command is empty
 
Given below is an example usage scenario of how the Undo command executes.
– user input –
Step 1. User executes a valid add command.
– AddCommand –
Step 2. Adds the add command as recent command.
Step 3. Adds the added Event as recent event.
– user input –
Step 4. User executes undo command.
– UndoCommand –
Step 5. Verify that recent command is not empty.
Step 6. Undo the recent command (deletes the recent event).
The execution can be seen in the activity diagram given below.
Activity Diagram for a typical undo command

Documentation, Logging, Testing, Configuration, Dev-Ops
Glossary
- Clashing Events: One or more events where any duration of the event overlaps with the another event
 - CLI: Command Line Interface
 - Event: A task with a starting time and an ending time
 - Mainstream OS: Windows, Linux, Unix, OS-X
 - GUI: Graphical User Interface
 - Ongoing Event: An event that has started, but not ended
 - Upcoming Event: An event that has not started
 
Appendices
Appendix A: Project Requirements
Product Scope
Target user profile:
- has a need to manage a significant number of events
 - prefer desktop apps over other types
 - prefers visual representation of output
 - is reasonably comfortable using CLI apps
 - can type fast
 
Value proposition: manage events at high-level, provides faster event analysis with graphical outputs.
User Stories
Priorities: High (must have) - * * *, Medium (nice to have) - * *, Low (unlikely to have) - *
| Priority | As a … | I want to … | So that I can… | 
|---|---|---|---|
* * * | 
      new user | see usage instructions | refer to instructions when I forget how to use the App | 
* * * | 
      user | add a event’s schedule into the app | see their schedules | 
* * * | 
      user | delete an event from the app | remove events that are no longer scheduled | 
* * * | 
      user | list all events | have a high-level overview of all events that I currently have | 
* * * | 
      regular user | save my scheduler on exit | reload them again next time | 
* * * | 
      regular user | load my events in the scheduler on start | use the scheduler immediately without having to reenter all events | 
* * | 
      clumsy user | undo a command | reset the scheduler to the previous state before I made a mistake | 
* * | 
      forgetful user | see my next event clearly | readily see what is upcoming for me without having to type any commands | 
* * | 
      user | sort my events based on date and time | readily see my upcoming events chronologically | 
* * | 
      regular user | repeat an event over a certain period of time | easily repeated events in my scheduler for the same type of events | 
* * | 
      long term user | see my monthly schedule easily | readily see which days I am more available, or which are my busier days | 
* * | 
      forgetful user | find my next event | check on the next event in the scheduler | 
* * | 
      clumsy user | undo accidental deletions | easily restore accidents in scheduling | 
* * | 
      user | find an event by name | locate details of events without having to go through the entire list | 
* * | 
      user | find an event by date | locate details of events without having to go through the entire list | 
* * | 
      user | edit my schedule | make changes to events | 
* * | 
      busy user | be able to schedule many events | schedule as many events as I want | 
Use Cases
(For all use cases below, the System is the EZ-Schedule and the Actor is the user, unless specified otherwise)
Use case: Add an event
MSS
- User requests to add an event
 - System adds the event
Use case ends. 
Extensions
- 1a. The event already exist.
      
- 1a1. System shows an error message.
Use case ends. 
 - 1a1. System shows an error message.
 - 1b. The given event format invalid.
      
- 1b1. System shows an error message.
Use case ends. 
 - 1b1. System shows an error message.
 - 1c. The given end time of the event is before start time.
      
- 1c1. System shows an error message.
Use case ends. 
 - 1c1. System shows an error message.
 
Use case: Recur an event
MSS
- User requests to recur an event over a period of time
 - System repeatedly adds the event
Use case ends. 
Extensions
- 1a. The length of time to recur is not appropriate.
      
- 1a1. System shows an error message.
Use case ends. 
 - 1a1. System shows an error message.
 - 1b. The given event format invalid.
      
- 1b1. System shows an error message.
Use case ends. 
 - 1b1. System shows an error message.
 - 1c. The given end date of recur is in the past.
      
- 1c1. System shows an error message.
Use case ends. 
 - 1c1. System shows an error message.
 - 1d. There is a clash of events in an upcoming day.
      
- 1d1. System shows an error message.
Use case ends. 
 - 1d1. System shows an error message.
 
Use case: Edit an event
MSS
- User requests to edit an event
 - System edits the event
Use case ends. 
Extensions
- 1a. The event already exist.
      
- 1a1. System shows an error message.
Use case ends. 
 - 1a1. System shows an error message.
 - 1b. The given format invalid.
      
- 1b1. System shows an error message.
Use case ends. 
 - 1b1. System shows an error message.
 
Use case: Delete an event
MSS
- User requests to delete an event/ events
 - System deletes the event(s)
Use case ends. 
Extensions
- 1a. The given index/ indices is invalid.
      
- 1a1. System shows an error message.
Use case ends. 
 - 1a1. System shows an error message.
 - 1b. The given format invalid.
      
- 1b1. System shows an error message.
Use case ends. 
 - 1b1. System shows an error message.
 
Use case: Find an event by name
MSS
- User requests to find an event by name
 - System finds events with matching name
 - System displays events with matching name
Use case ends. 
Extensions
- 1a. The given event format invalid.
      
- 1a1. System shows an error message.
Use case ends. 
 - 1a1. System shows an error message.
 
Use case: Show next event(s) by name
MSS
- User requests to show next x number of event(s)
 - System displays the next x number of events in chronological order
Use case ends. 
Extensions
- 1a. The given event format invalid.
      
- 1a1. System shows an error message.
Use case ends. 
 - 1a1. System shows an error message.
 
Use case: Undo a delete
MSS
- User requests to undo the recent delete
 - System restores the most recent delete
Use case ends. 
Extensions
- 1a. Undo is the first command given to the scheduler.
      
- 1a1. System shows an error message.
Use case ends. 
 - 1a1. System shows an error message.
 
Use case: List all events
MSS
- User requests to list all events
 - System shows all events in the scheduler
Use case ends. 
Use case: Get help instructions
MSS
- User requests for help instructions
 - System shows help instructions
Use case ends. 
Use case: Exit the application
MSS
- User requests to exit the application
 - System saves all events
 - System exits the application
Use case ends. 
Non-Functional Requirements
- Should work on any mainstream OS as long as it has Java 
11or 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.
 - A user with colour blindness may require a high-contrast setting for graphical outputs.
 
Appendix B: Planned Enhancements
To resolve certain known feature flaws, we have planned to add some enhancements in the near future:
Data Verification when loading save files
Currently, the program reads and loads the data from the save files directly. As long as the data is in the correct format, the data can be loaded successfully. We plan to enhance this by verifying the validity of the data, that is making sure the saved events does not violate constraints such as overlapping time.
This will help to prevent errors made by advanced user who decided to modify the save files directly. While the advanced user may be aware of the structure of the file, knowing if the event added has conflict with any existing events can be hard, especially if there are many existing events.
Increasing the minimum size of the windowed screen
Currently, if a user sets their windowed screen to the minimum size, it can potentially cut off access to the local storage path where all event data is stored.

We plan to increase the minimum size of the windowed screen to ensure that the path to the local storage is always visible. This will provide convenience to users who wish to modify the event data from the local storage
Reformatting the display in events panel and upcoming events panel
Currently, if the event names are too long, they may overflow onto the date portion, which can make it difficult to view both the full event name and date.

We plan to improve the display of event names by wrapping the text and continuing it on the next line. This will prevent the issue of long event names overflowing onto the date portion
Changing the display of events in calendar date boxes
Currently, if event names exceed 5 characters in length, the characters beyond the fifth are replaced with “…” in the display.

The original purpose was to give users a quick overview and inform them of the presence of events on certain dates. However, this truncated display does not provide much value to users as it fails to show the full event name.
We plan to change the way calendar date boxes display events. Rather than showing event names, we will use dots to represent events. Each dot will have a different color within the same day to represent different events. This approach will allow users to quickly see an overview of the number of events on a given day. An example is given below.

If users are interested in knowing more about the events, 
they can use the find command or click on the calendar date box to view the event details.
Increase flexibility in event names
Currently, event names only support alphanumeric characters and spaces. This may cause inconvenience to users as we anticipate that event names may include special characters such as brackets, colons, and dashes.
We plan to increase the number of characters supported in event names. 
However, certain characters such as / and \ will not be supported as they may potentially cause conflicts
Appendix C: Instructions for Manual Testing
Presented below are a series of instructions, organized in Context, Action, Result (CAR) format, that can be followed to perform manual testing of the application.
Launch and Shutdown
Scenario 1
Context: Initial launch
Action:
- Download the jar file and copy into an empty folder
 - Double-click the jar file
 - Ensure that it is launched in 
Java 11 
Result: Displays the GUI with the application opened to full-screen
Scenario 2
Context: Normal launch
Action: Launch the application again (follow from scenario 1 step 2)
Result: Displays the GUI with the application opened to full-screen
Scenario 3
Context: Restarting the application with existing data
Action:
- Click on the ‘X’ button located in the top-right corner of the screen
 - Double-click the jar file
 
Result: The existing data should remain unchanged
Adding an Event
Scenario 1
Context: The Event has not yet been added to Ez-Schedule
Action: Execute the command add n/Tennis d/2023-05-01 s/10:00 e/12:00
Result:
- The 
Eventhas been successfully added to Ez-Schedule - Details of the 
Eventis also added to the Events Panel and the Calendar 
Scenario 2
Context: An identical Event to the one being added, already exists in Ez-Schedule
Action:  Execute the command add n/Tennis d/2023-05-01 s/10:00 e/12:00
Result: The Response Box will display the message “This event already exists in the scheduler”
Scenario 3
Context: The selected time slot is already occupied by another Event in Ez-Schedule
Action:  Execute the command add n/Tennis d/2023-05-01 s/10:00 e/12:00
Result: The Response Box will display the message “Another event already exists at the chosen time”
Recurring an Event
Scenario 1
Context: No conflicting Event scheduled during the recurring time frame specified
Action: Execute the command: recur 1 d/2023-05-10 every/day
Result:
- The 
Eventwill be added repeatedly until the specified end date - Details of all the 
Eventis also added to the Events Panel and the Calendar 
Scenario 2
Context: Another Event already exist in the recurring time frame specified by the Event being added
Action: Execute the command: recur 1 d/2023-05-10 every/day
Result: The Response Box will display the message “Unable to recur. 10 May has a clashing event.”
Editing an Event
Scenario 1
Context: There exists an Event with the index 1 in Ez-Schedule
Action: Execute the command: edit 1 n/Basketball
Result: The name of the Event has been updated to Basketball
Scenario 2
Context: Modify an Event to make it identical to another Event already present in Ez-Schedule
Action: Execute edit command with arguments identical to another existing Event
Result: The Response Box will display the message “This event already exists in the scheduler”
Deleting Events
Scenario 1
Context: There exists an Event with the index 1 in Ez-Schedule
Action: Execute the command: delete 1
Result:
- The 
Eventis removed from Ez-Schedule - Details of the 
Eventis also removed from the Events Panel, Upcoming Events Panel, and the Calendar 
Scenario 2
Context: There exists multiple Event with the indexes 1, 2 and 3 in Ez-Schedule
Action: Execute the command: delete 1 2 3
Result:
- All the 
Eventis removed from Ez-Schedule - Details of the 
Eventis also removed from the Events Panel, Upcoming Events Panel, and the Calendar 
Scenario 3
Context: One of the specified indexes, index 10, does not exist in Ez-Schedule
Action: Execute the command: delete 1 2 3 10
Result:
- The Response Box will display the message “The event index 10 provided is invalid”
 - None of the 
Eventwith valid index will be removed from Ez-Schedule 
Finding Events
Scenario 1
Context: There exists at least one Event whose Name includes the word Tennis
Action: Execute the command: find n/Tennis
Result:
- The Events Panel will be updated to display only those 
EventwhoseNameincludes the word Tennis - The Calendar will highlight all the date boxes that correspond to days on which the found 
Eventare scheduled 
Scenario 2
Context: There exists at least one Event whose Name partially matches the word ‘Ten’
Action: Execute the command: find n/Ten
Result:
- The Events Panel will be updated to display only 
EventwhoseNameincludes Ten, which may includeNamesuch as Tennis - The Calendar will highlight all the date boxes that correspond to days on which the found 
Eventare scheduled 
Scenario 3
Context: There exists at least 1 Event whose Date correspond to May 1, 2023
Action: Execute the command: find d/2023-05-01
Result:
- The Events Panel will be updated to display only those 
EventwhoseDateare May 1, 2023 - The date box for May 1, 2023 will be highlighted on the Calendar
 
Scenario 4
Context: There exists at least one Event whose Name includes the word Tennis and Date corresponds to May 1, 2023
Action: Execute the command: find n/Tennis d/2023-05-01
Result:
- The Events Panel will be updated to display only those 
EventwhoseNameincludes the word Tennis andDateare May 1, 2023 - The date box for May 1, 2023 will be highlighted on the Calendar
 
Show Next Events
Scenario 1
Context: None needed
Action: Execute the command: next
Result:
- The Response Box will display the message “1 events listed!”
 - The Upcoming Events Panel will display the next upcoming or ongoing event that you have
 
Scenario 2
Context: There exists at least two upcoming or ongoing Event
Action: Execute the command: next 2
Result:
- The Response Box will display the message “2 events listed!”
 - The Upcoming Events Panel will display the next 2 upcoming or ongoing event that you have
 
Undo a Command
Scenario 1
Context: None needed
Action:
- Execute the command: 
add n/Tennis d/2023-05-01 s/10:00 e/12:00 - Execute the command: 
undo 
Result:
- The Response Box will display the message “Action undone: add”
 - The Tennis 
Eventthat was added will be removed from Ez-Schedule 
Scenario 2
Context: No conflicting Event scheduled during the recurring time frame specified
Action:
- Execute the command: 
recur 1 d/2023-05-10 every/recur - Execute the command: 
undo 
Result:
- The Response Box will display the message “Action undone: recur”
 - All the 
Eventthat was added will be removed from Ez-Schedule 
Scenario 3
Context: There exists an Event with an index 1 and a Name of Tennis in Ez-Schedule
Action:
- Execute the command: 
edit 1 n/Basketball - Execute the command: 
undo 
Result:
- The Response Box will display the message “Action undone: edit”
 - The Tennis 
Eventthat was edited to Basketball will be changed back to Tennis 
Scenario 4
Context: There exists an Event with an index 1 in Ez-Schedule
Action:
- Execute the command: 
delete 1 - Execute the command: 
undo 
Result:
- The Response Box will display the message “Action undone: delete”
 - The 
Eventwith index 1 that was deleted is added back into Ez-Schedule 
Appendix D: Effort
Difficulty Level: Overall Medium difficulty (averaged total votes by all members)
Challenges Faced:
- During the first milestone, we decided to “morph” by creating a parallel package and using AB3 as code reference.
We would copy over whichever code we deem relevant. Halfway through the milestone, one of us realised that doing this
possibly violated 
Constraint-Brownfield. After checking with our tutor/prof, we had to restart again, effectively wasting our effort and restricting our duration formilestone 1by half. - During morphing, the refactor of 
PersontoEvent, as well asAddressBooktoSchedulerwas tedious and required a lot of careful checking. Despite using IDE features like refactor and find-and-replace, there were still variable name and comments which we had to change, and we had to painstakingly double-check everything. - Furthermore, the morphing process also invalidated many of the existing test cases (from AB3) resulting in the 
Java CI failing for a prolonged period. We spend a lot of time in 
milestone 2changing/fixing the broken test cases, which left us with not a lot of time to implement new features inmilestone 2andmilestone 3. 
Effort Required: High effort for the morphing process.
Achievements of Project:
- Created a working product
 - Experienced using GitHub Issues and PRs
 - Experienced making UML diagrams digitally
 - Practiced debugging & testing skills taught
 - Practiced workflows & design approaches taught
 - Collaborated with a group on a huge project (~13kLoC)