Developer Guide
- Acknowledgements
- Setting up, getting started
- Design
- Implementation
- Documentation, logging, testing, configuration, dev-ops
- Appendix: Requirements
-
Appendix: Instructions for manual testing
- Launch and shutdown
- Adding a resident
- Viewing a resident
- Listing residents by FET/Collection Deadlines
- Finding residents
- Editing residents
- Deleting residents
- Tracing residents
- Sorting residents
- Importing resident data
- Exporting residents’ emails
- Adding an event
- Viewing an event
- Finding an event
- Editing an event
- Deleting an event
- Sorting events
- Adding residents to an Event
- Removing residents from an Event
- Switch between tabs
- Saving data
Acknowledgements
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 other
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
interface
with the same name as the Component. - implements its functionality using a concrete
{Component Name}Manager
class (which follows the corresponding APIinterface
mentioned 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.
The sections below give more details of each component.
UI component
The API of this component is specified in Ui.java
The UI consists of a MainWindow
that is made up of parts e.g.CommandBox
, ResultDisplay
, PersonListPanel
, 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
Logic
component. - listens for changes to
Model
data so that the UI can be updated with the modified data. - keeps a reference to the
Logic
component, because theUI
relies on theLogic
to execute commands. - depends on some classes in the
Model
component, as it displaysPerson
object residing in theModel
.
Logic component
API : Logic.java
Here’s a (partial) class diagram of the Logic
component:
How the Logic
component works:
- When
Logic
is called upon to execute a command, it uses theAddressBookParser
class to parse the user command. - This results in a
Command
object (more precisely, an object of one of its subclasses e.g.,AddCommand
) which is executed by theLogicManager
. - The command can communicate with the
Model
when it is executed (e.g. to add a person). - The result of the command execution is encapsulated as a
CommandResult
object 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
AddressBookParser
class creates anXYZCommandParser
(XYZ
is a placeholder for the specific command name e.g.,AddCommandParser
) which uses the other classes shown above to parse the user command and create aXYZCommand
object (e.g.,AddCommand
) which theAddressBookParser
returns back as aCommand
object. - All
XYZCommandParser
classes (e.g.,AddCommandParser
,DeleteCommandParser
, …) inherit from theParser
interface so that they can be treated similarly where possible e.g, during testing.
Model component
API : Model.java
The Model
component,
- stores the address book data i.e., all
Person
objects (which are contained in aUniquePersonList
object) and allEvent
objects (which are contained in aUniqueEventList
object). - stores the currently ‘selected’
Person
orEvent
objects (e.g., results of a search query) as a separate filtered list which is exposed to outsiders as an unmodifiableObservableList<Person>
orObservableList<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
UserPref
object that represents the user’s preferences. This is exposed to the outside as aReadOnlyUserPref
objects. - does not depend on any of the other three components (as the
Model
represents 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 address book data and user preference data in json format, and read them back into corresponding objects.
- inherits from both
AddressBookStorage
andUserPrefStorage
, which means it can be treated as either one (if only the functionality of only one is needed). - depends on some classes in the
Model
component (because theStorage
component’s job is to save/retrieve objects that belong to theModel
)
Common classes
Classes used by multiple components are in the safeforhall.commons
package.
Implementation
This section describes some noteworthy details on how certain features are implemented.
Add Command
This command allows the user to add residents or events to the SafeFor(H)All application depending on the currently active tab.
The workflow of the Add command is shown in the Activity diagram illustrated below.
Design considerations:
Aspect: Optional LastDate
fields when adding residents
-
Alternative 1 (current choice):
lastFetDate
andlastCollectionDate
are optional fields- Pros:
- Provides more flexibility for users when adding residents to the application, as users have the choice to include or exclude these fields.
- Saves time as all fields can be added in a single command
- Cons: The length of command is increased as there are potentially more fields for the user to type.
- Pros:
-
Alternative 2: Add
lastFetDate
andlastCollectionDate
by editing the Person object- Pros: Makes add command more user-friendly as the command is more succinct
- Cons: User has to go through a two-step process of
add
andedit
to initialise a residents information
Delete Command
This command allows the user to delete residents or events to the SafeFor(H)All application depending on the currently active tab.
The workflow of the Delete command is shown in the Activity diagram illustrated below.
Design considerations:
Aspect: Delete the correct resident/event:
-
Alternative 1 (current choice):
Index
field- Pros: No need to type out the full name of the resident/event, and risk typos.
Index
is also unique, which prevents the user from deleting the wrong resident/event. - Cons: The user needs to scroll through the GUI to find the index of the resident/event to be deleted.
- Pros: No need to type out the full name of the resident/event, and risk typos.
-
Alternative 2:
Name
andeventName
fields for Resident and Event respectively.- Pros: The user does not need to scroll through the GUI to find the index of the resident/event to be deleted.
- Cons: There is a higher risk of erroneous user input, as a
Name
/eventName
field will inevitably be longer than an index.
Edit Command
This command allows the user to edit residents or events to the SafeFor(H)All application depending on the currently active tab.
The workflow of EditPersonCommand
is shown in the Activity diagram illustrated below.
EditEventCommand
follows a similar flow of actions.
Note:
- Mass operations for residents can be carried out by inputting multiple indexes after the command
edit
, each separated by a whitespace. -
Residents
field inEvent
is not editable byedit
command
Design considerations:
Aspect: Edit parameters:
-
Alternative 1 (current choice): Excluding
Residents
parameter for Events.- Pros:
- Simpler implementation as there are less
EditDescriptors
to maintain. -
include
andexclude
commands exist to enhance the updating of theResidents
field.edit
currently replaces the specified fields with the user input, which will not be user-friendly for theResidents
field. It might also cause confusion of possible overlapping functionality on the user’s side.
- Simpler implementation as there are less
- Cons: Increases the number of commands the user has to remember.
- Pros:
-
Alternative 2:
edit
is used to edit the residents involved in an event- Pros: More instinctive, and less commands for the user to remember.
- Cons: Users will have to rewrite the entire list of residents involved in the event whenever they want to modify the list of residents involved.
View Command
This command allows the user to view the additional details of a specific resident or event in the sidebar, depending on the currently active tab.
How it works:
- When the app is started, the
Ui
component calls onLogic
to get theModel
to be displayed in the sidebar.Model
is first set to an empty list. - When a
ViewCommand
with a valid index is executed, theModel
is updated to contain only the specified resident or event. - When the
ViewCommand
is executed without index parameters, the main panel will show all residents or events, and the sidebar will be cleared. - If the command is run in the
ResidentTab
, the details of the resident with the corresponding index being displayed in the sidebar. Vice versa forEventTab
.
The following sequence diagram demonstrates what happens when the ViewPersonCommand
is executed:
ViewEventCommand
follows a similar sequence of interactions.
Design considerations:
Aspect: How to reference residents/ events in the CLI:
-
Alternative 1 (current choice): Reference by
Index
.- Pros:
- Easy to reference and no need to type out the whole
residentName
/eventName
. -
Index
is unique.
- Easy to reference and no need to type out the whole
- Cons: Need to first determine the
Index
of the resident/ event in the UI.View
could become a two-step process if the database is large.
- Pros:
-
Alternative 2: Reference by
residentName
/eventName
.- Pros: Do not have to first determine the
Index
of the resident/ event. - Cons:
- Hard to type when the
residentName
/eventName
is long. -
eventName
is not unique, which might cause issues.
- Hard to type when the
- Pros: Do not have to first determine the
Find Person Command
This command allows searching for residents subjected to 1 or more filters for the different available parameters.
The workflow of the Find Person command can be illustrated with an activity diagram as follows:
How the parsing works:
- When
Logic
is called upon to execute the command, it uses theAddressBookParser
class to parse the user command. - If the command was run in the
ResidentTab
it results in aFindCommandParser
object created and it’sparse
method called with the user input. - The parsing attempts to create a
FindCommand
object. For each existing prefix, it sets the relevant field of a newFindCompositePredicate
object. - Parsing of any of the provided values can throw a
ParseException
if invalid. If at least one field is set, aFindCommand
object is returned. If all are unspecified, an exception is thrown. - The command is executed and the result encapsulated as a
CommandResult
object which is returned back fromLogic
.
Note:
- Name can take in multiple keywords separated by whitespace
-
lastFetDate
andlastCollectionDate
are not included - Room filtering is extended to allow block, level and block-level filtering as well
The following sequence diagram demonstrates what happens when the FindCommand
is executed:
The command extends the Command
class and implements FindCommand#execute()
to execute the command.
The crucial logic underlying is encapsulated in the FindCompositePredicate
class. This class holds the filtering variables and constructs the required predicate for filtering. The test
method creates and combines the predicates as shown:
@Override
public boolean test(Person person) {
List<Predicate<Person>> allPredicates = Arrays.asList(
p -> getName().orElse(x -> true).test(p),
p -> getRoom().orElse(x -> true).test(p),
p -> getPhone().orElse(x -> true).test(p.getPhone()),
p -> getEmail().orElse(x -> true).test(p.getEmail()),
p -> getVaccStatus().orElse(x -> true).test(p.getVaccStatus()),
p -> getFaculty().orElse(x -> true).test(p.getFaculty()));
return allPredicates
.stream()
.reduce(p -> true, Predicate::and)
.test(person);
}
Most variables are checked against using their respective equals
methods except for Name
and Room
for which separate predicates implementing Predicate<Person>
have been created. This is done to support:
- Multiple keywords matching for name and
- Room matching by block, level and block-level.
Design considerations:
Aspect: Filtering parameters:
-
Alternative 1 (current choice): Excluding
lastFetDate
andlastCollectionDate
parameters.- Pros:
- Simpler implementation as there are less filtering predicates to maintain.
-
list
command exists to enhance the usage of these 2 fields to extract information. A simple equality check on date is less likely from the user’s POV andlist
handles this. Thus excluding this, prevents confusion of possible overlapping functionality on the user’s side.
- Cons:
- The user is unable to search for an exact fet/collection date alongside other filters.
- Pros:
Include Command
This command adds multiple residents to an event by referencing the Event
by its Index
and the Person
to
add by their Name
or Room
through the AddressBook#findPerson()
method.
The following activity diagram illustrates how the AddressBook#findPerson()
method works:
The command extends the Command
class and implements IncludeCommand#execute()
to execute the command.
A ResidentList
which contains a list of Person
to add to an Event
, is a field added to an Event
.
When IncludeCommand#createEditedEvent()
is called, two methods of Event
are invoked:
-
Event#getCombinedDisplayString()
creates a display String with just the names of eachPerson
in the combination of currentPerson
in the Eventand all the
Personin
toAdd` with no duplicate. -
Event#getCombinedStorageString()
creates a storage String with the full information of eachPerson
in the combination of currentPerson
in the Eventand all the
Personin
toAdd` with no duplicate.
The following sequence diagram demonstrates what happens when the IncludeCommand
is executed:
The following activity diagram summarizes what happens when the IncludeCommand
is executed:
Design considerations:
Aspect: How to reference event in the CLI:
-
Alternative 1 (current choice): Reference by
Index
.- Pros: Easy to reference and no need to type out the whole
eventName
,Index
is also unique. - Cons: Need to find the
Index
of theEvent
in the UI to know whatIndex
theEvent
has if the number ofEvent
is large.
- Pros: Easy to reference and no need to type out the whole
-
Alternative 2: Reference by
eventName
. itself.- Pros: Do not need to have the
Index
in UI to know whatEvent
it is, can just reference it by its name. - Cons: Hard to type when the
eventName
is long,eventName
not being unique will also cause issues.
- Pros: Do not need to have the
Documentation, logging, testing, configuration, dev-ops
Appendix: Requirements
Product scope
Target user profile:
- administrator of on-campus halls and residences
- has a need to manage a large amount of resident information
- prefer desktop apps over other types
- can type fast
- prefers typing to mouse interactions
- is reasonably comfortable using CLI apps
Value proposition: Manage residents’ information faster than a typical mouse/GUI driven app and allow easy enforcement of Covid-19 restrictions
User stories
Priorities: High (must have) - * * *
, Medium (nice to have) - * *
, Low (unlikely to have) - *
[EPIC] Basic CRUD Functionality
Priority | As a … | I want to … | So that I can… |
---|---|---|---|
* * * |
admin in a hall/ residence | add a new resident | keep track of the residents’ data |
* * * |
admin in a hall/ residence | add a new event | keep track of current and upcoming events happening in the hall/ residence |
* * * |
admin in a hall/ residence | add residents to an event | keep track of the residents attending a specific hall event |
* * * |
admin in a hall/ residence | delete a resident | remove the data of a resident who has moved out |
* * * |
admin in a hall/ residence | delete many residents in a single command | save a lot of time when deleting multiple residents |
* * * |
admin in a hall/ residence | delete an event | remove an event that has been cancelled |
* * * |
admin in a hall/ residence | delete many events in a single command | save a lot of time when deleting multiple events |
* * * |
admin in a hall/ residence | delete residents from an event | remove residents who are no longer attending a specific hall event |
* * * |
admin in a hall/ residence | update a resident’s details | update and reflect any changes in the residents’ details |
* * * |
admin in a hall/ residence | update the particulars of many residents in a single command | save a lot of time when editing the details of multiple residents |
* * * |
admin in a hall/ residence | update an event’s details | update an event’s details if there are any changes |
* * * |
admin in a hall/ residence | add and update a resident’s last FET date | keep track of the residents’ last FET dates and update the dates whenever they take a new FET |
[EPIC] Information Retrieval
Priority | As a … | I want to … | So that I can… |
---|---|---|---|
* * * |
admin in a hall/ residence | view all residents | see all the current residents |
* * * |
admin in a hall/ residence | view all events | see all the current events |
* * * |
admin in a hall/ residence | view a list of residents who were present at an event | identify who is at risk if someone in the group catches COVID |
* * * |
admin in a hall/ residence | search for the residents by their name, room, email, phone number | find a resident based on the information given |
* * * |
admin in a hall/ residence | filter the residents by faculty | easily disseminate faculty-specific information to the residents |
* * * |
admin in a hall/ residence | filter the residents by block and level | easily contact a group of students in order to disseminate group-specific information |
* * * |
admin in a hall/ residence | filter the residents by their vaccination status | use the information to disseminate information or guidelines that may be different for vaccinated and unvaccinated individuals |
* * * |
admin in a hall/ residence | immediately see residents who have missed their FET deadlines | disseminate a reminder to these residents to take a new FET test |
* * * |
admin in a hall/ residence | immediately see which events contain unvaccinated people | ensure that COVID restrictions are adhered to, and that everyone attending the event is vaccinated, by removing the unvaccinated residents from the event list |
* * * |
admin in a hall/ residence | retrieve all residents whose FETs are due within a given date | ensure residents do not miss their FET deadlines by reminding them to do their FETs |
* * * |
admin in a hall/ residence | retrieve a resident’s test kit collection deadlines | ensure residents do not miss their test kit collections by reminding them to collect their kits on time |
* * * |
admin in a hall/ residence | retrieve the date and venue of the events | identify who was in contact with the infected person on the day of the event |
* * * |
admin in a hall/ residence | retrieve the maximum capacity of an event venue and the number of residents attending the event | ensure that the number of residents attending the event will not exceed the capacity of the event venue |
* * * |
admin in a hall/ residence | easily carry out contact tracing | quarantine can be done quickly in the case where one person in the group catches COVID |
* |
admin in a hall/ residence | check which CCA booked a certain facility | find out which CCA is responsible in case trouble arises |
* |
admin in a hall/ residence | check a resident’s prior events | find out which group has come into contact with the infected person |
[EPIC] Miscellaneous
Priority | As a … | I want to … | So that I can… |
---|---|---|---|
* * * |
admin in a hall/ residence | view the help guide whenever I need to | refresh my memory on how to use the app |
* * |
admin in a hall/ residence | view a summary of the app functions | have an overview of what the app does |
* * |
admin in a hall/ residence | import user data from a CSV file | input multiple residents’ information into the system at once without having to add each resident’s information line-by-line |
* * |
admin in a hall/ residence | export the emails of the residents whose FET/collection are due soon into a file | disseminate information to the residents more easily |
* |
admin in a hall/ residence | view all details of a specific resident or event only when I need to | easily find the specific information I am looking for, without having the large amount of information stored cluttering the app |
* |
admin in a hall/ residence | see a auto-suggestion of the command format once I type it | quickly refer to the correct format of the command |
Use cases
(For all use cases below, the System is the SafeFor(H)All app
and the Actor is the Hall admin
, unless specified otherwise)
Use case: UC01 - Delete a resident
MSS
- Actor requests to list residents.
- System shows a list of residents.
- Actor requests to delete a specific resident in the list.
-
System deletes the resident.
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: UC02 - View details of an event
MSS
- Actor navigates to the
Event
tab of the application. - Actor requests to view an event from the list of events.
-
System shows the relevant information of the event and list of residents involved in the event.
Use case ends.
Extensions
- 2a. The given index is invalid.
-
2a1. System shows an error message.
Use case resumes at step 2.
-
-
3a. The list is empty.
Use case ends.
Use case: UC03 - Include a resident to an event
MSS
- Hall admin navigates to the
Event
Tab. - Hall admin views the event to include residents in.
- Hall admin enters the residents to be included in the selected event.
-
SafeFor(H)all reflects the added residents in the side window.
Use case ends.
Extensions
- 3a. SafeFor(H)all detects invalid residents entered.
- 3a1. SafeFor(H)all displays an error message.
- 3a2. SafeFor(H)all requests for valid residents.
-
3a3. Hall admin enters new data.
Steps 3a1-3a2 are repeated until the residents entered are valid. Use case resumes from step 4.
Use case: UC04 - Exclude a resident from an event
MSS
- Hall admin navigates to the
Event
Tab. - Hall admin views the event to exclude residents from.
- Hall admin enters the residents to be excluded in the selected event.
-
SafeFor(H)all reflects the remaining residents in the side window after removing the given residents.
Use case ends.
Extensions
- 3a. SafeFor(H)all detects invalid residents entered.
- 3a1. SafeFor(H)all displays an error message.
- 3a2. SafeFor(H)all requests for valid residents.
-
3a3. Hall admin enters new data.
Steps 3a1-3a3 are repeated until the residents entered are valid.
Use case resumes from step 4.
Use case: UC05 - List residents who missed their FET
MSS
- Hall admin navigates to the
Resident
Tab. - Hall admin filters residents whose FET were due before today.
-
SafeFor(H)all displays the filtered residents.
Use case ends.
Extensions
- 2a. SafeFor(H)all detects invalid date entered.
- 2a1. SafeFor(H)all displays an error message.
- 2a2. SafeFor(H)all requests for a valid date.
-
2a3. Hall admin enters a new date.
Steps 2a1-2a2 are repeated until the date entered are valid.
Use case resumes from step 3.
Use case: UC06 - List residents whose FET or Test Kit collection dates are due soon
MSS
- Hall admin navigates to the
Resident
Tab. - Hall admin filters residents whose FET or Test Kit Collection will be due between two given dates.
-
SafeFor(H)all displays the filtered residents.
Use case ends.
Extensions
- 2a. SafeFor(H)all detects invalid dates entered.
- 2a1. SafeFor(H)all displays an error message.
- 2a2. SafeFor(H)all requests for valid dates.
-
2a3. Hall admin enters new dates.
Steps 2a1-2a2 are repeated until the dates entered are valid.
Use case resumes from step 3.
Use case: UC07 - Update a resident’s last FET date
MSS
- Actor requests to list residents
- System shows a list of residents
- Actor requests to update a specific resident’s last FET date
- System updates the specified resident’s last FET date
- Actor requests to view all details of the specified resident to confirm that the details have been updated correctly
- System shows all details of the specified resident
-
2a. The list is empty.
Use case ends.
- 3a. SafeFor(H)all detects invalid index entered.
- 3a1. SafeFor(H)all displays an error message.
- 3a2. SafeFor(H)all requests for a valid index.
-
3a3. Hall admin enters a new index.
Steps 3a1-3a2 are repeated until the index entered is valid.
Use case resumes from step 4.
- 3b. SafeFor(H)all detects invalid date entered.
- 3b1. SafeFor(H)all displays an error message.
- 3b2. SafeFor(H)all requests for a valid date.
-
3b3. Hall admin enters a new date.
Steps 3b1-3b2 are repeated until the date entered is valid.
Use case resumes from step 4.
- 5a. SafeFor(H)all detects invalid index entered.
- 5a1. SafeFor(H)all displays an error message.
- 5a2. SafeFor(H)all requests for a valid index.
-
5a3. Hall admin enters a new index.
Steps 5a1-5a2 are repeated until the index entered is valid.
Use case resumes from step 6.
Use case: UC08 - Export current list of residents’ email as csv
MSS
- Actor requests for a list of the email addresses of the residents shown.
- Actor enters filename of file to be created.
-
System outputs the list of email addresses in the form of a csv file.
Use case ends.
Extensions
- 2a. System detects duplicate file.
- 2a1. System displays an error message. Use case resumes at step 2.
Use case: UC09 - Remind residents to take FET
MSS
- Actor lists residents who missed their FET (UC05)
- Actor exports current list of residents' email as csv (UC08)
-
Actor sends an email to these residents to remind them to take their FET soon.
Use case ends.
Extensions
-
1a. The list is empty.
Use case ends.
Use case: UC10 - Remind residents to collect FET kits
MSS
- Actor lists residents whose FET or Test Kit collection dates are due soon (UC06)
- Actor exports current list of residents' email as csv (UC08)
-
Actor sends an email to these residents to remind them to collect their FET kits soon.
Use case ends.
Extensions
-
1a. The list is empty.
Use case ends.
Use case: UC11 - Find close contacts of a resident
MSS
- Actor views the list of residents and locates the resident to trace.
- Actor filters the resident list by that resident’s name or room and specifies a number of days to trace back to.
-
System shows a filtered resident list.
Use case ends.
Extensions
- 2a. System cannot find the resident in question.
- 2a1. System displays an error message.
- 2a2. System requests for a valid name or room.
-
2a3. Actor retries with different information.
Use case resumes from step 2.
- 2b. System detects an invalid duration that is negative or more than a month.
- 2b1. System displays an error message.
- 2b2. System requests for a valid duration.
-
2b3. Actor retries with different input.
Use case resumes from step 2.
Use case: UC12 - Inform close contacts of a resident
MSS
- Actor filters for residents who are close contacts of a given resident (UC11)
- Actor exports current list of residents' email as csv (UC08)
-
Actor sends an email to these residents to remind them to self-isolate.
Use case ends.
Extensions
-
1a. The list is empty.
Use case ends.
Use case: UC13 - Find all residents on the same floor as a positive case
MSS
- Actor views all residents.
- Actor locates the positive resident and finds their room number.
- Actor filters the resident list based on the block and floor extracted from the room number.
-
System shows a filtered resident list.
Use case ends.
Extensions
- 3a. System detects and invalid block character or out of range floor number.
- 3a1. System displays an error message.
- 3a2. System requests for a valid block floor combination.
-
3a3. Actor retries with different information.
Use case resumes from step 3.
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 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.
- Should be targeted towards a single user and not multi-users.
- Data stored locally should be in a human editable text file.
- Do not make use of a DBMS to manage data.
- Final software should be platform-independent.
- The software shouldn’t depend on our own remote server.
- Application is to be packaged into a single JAR file.
- JAR file size to be limited to 100MB and documents to 15MB/file.
- UG and DG are to be pdf-friendly.
Glossary
- Mainstream OS: Windows, Linux, Unix, OS-X
- API: An Application Programming Interface is a connection between computers or between computer programs. It is a type of software interface, offering a service to other pieces of software.
- GUI: A Graphical User Interface (GUI) is a form of user interface through which users interact with electronic devices via visual indicator representations.
- CLI: A Command Line Interface (CLI) processes commands to a computer program in the form of lines of text.
- FET: Fast and Easy Test for COVID-19, which is self-administered using Antigen Rapid Test (ART) kits.
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 residents. 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.
-
Adding a resident
-
Adding a resident and their information into the app
- Test case:
add n/Tommy r/A123 p/87654321 e/tom@gmail.com v/t f/SOC fd/10-10-2020 cd/20-10-2020
Expected: A resident namedTom
with the relevant information is added into the app, shown in the GUI. Success message is shown.
- Test case:
-
Adding a duplicate resident with the same name or same room
-
Prerequisites: A resident with the same name
Tommy
or roomA123
is already in the app. -
Test case:
add n/Tommy r/A101 p/87654321 e/bern@gmail.com v/t f/SOC fd/10-10-2020 cd/20-10-2020
Expected: Error message shown,This resident or room already exists in the address book
-
Test case:
add n/Tom r/A123 p/87654321 e/tom@gmail.com v/t f/SOC fd/10-10-2020 cd/20-10-2020
Expected: Error message shown,This resident or room already exists in the address book
-
-
Adding a resident with invalid parameters
-
Test case:
add n/Tom! r/A201 p/87654321 e/tom@gmail.com v/t f/SOC fd/10-10-2020 cd/20-10-2020
Expected: Error message shown,Names should only contain alphabetic characters and spaces, and it should not be blank
-
Test case:
add n/Tom r/A201 p/87654321 e/tom@gmail.com v/true f/SOC fd/10-10-2020 cd/20-10-2020
Expected: Error message shown,Vaccination status can be T or F (case insensitive).
-
Viewing a resident
-
View a list of all the residents in the app, or the information on a specific resident
-
Prerequisites: NIL
-
Test case:
view
Expected: A list of all the residents is displayed in the app’s GUI -
Test case:
view 3
Expected: The details of the resident at index 3 (meaning the 3rd resident in the list whenview
without the index parameter is called) of the address book are displayed in the GUI. -
Other incorrect delete commands to try:
view 0
,view x
(where x is larger than the list size)
Expected: Error message shown
-
Listing residents by FET/Collection Deadlines
-
Listing residents’ deadline with normal keyword and valid dates
-
Prerequisites: There are residents whose FET deadline lies between the 2 gates given
-
Test case:
deadline k/f d1/10-10-2021 d2/15-10-2021
Expected: Residents whose FET deadline lies between these 2 dates are listed.
-
-
Listing residents’ deadline with late keyword and valid dates
-
Prerequisites: There are residents whose FET deadline is due before the given date
-
Test case:
deadline k/lf d1/10-10-2021
Expected: Residents whose FET is due before the given date is listed.
-
-
Listing residents’ deadline with invalid parameters
-
Test case:
deadline k/f d1/10-10-2021
Expected: The result box will indicate that the given command format is invalid. -
Test case:
deadline k/f d1/12-10-2021 d2/10-10-2021
Expected: The result box will indicate that the second date is earlier than the first.
-
Finding residents
-
Finding residents’ who are not vaccinated
-
Prerequisites: A non-empty resident list
-
Test case:
find v/f
Expected: Residents who are not vaccinated (no syringe icon) are listed.
-
-
Finding residents’ who are from
SoC
faculty and are vaccinated-
Prerequisites: A non-empty resident list
-
Test case:
find f/soc v/t
Expected: Residents who are vaccinated (syringe icon) and fromSoC
are listed.
-
-
Finding residents’ who have the word
alex
in their name and are from blockA
-
Prerequisites: A non-empty resident list
-
Test case:
find n/alex r/a
Expected: Residents who fit the criteria are listed.
-
-
Finding residents’ who are in an invalid block
P
- Test case:
find n/alex r/p
Expected: Error message specifying that an invalid room is entered.
- Test case:
Editing residents
-
Edit multiple residents’ details while all residents are being shown
-
Prerequisites: View all residents using the
view
command. Multiple residents in the list. Edited resident does not already exist in the address book. -
Test case:
edit 1 2 v/T
Expected: First and second residents’ vaccination statuses are updated to vaccinated. First and second residents’ names shown in the status message. -
Test case:
edit 0
Expected: No resident is edited. Error details shown in the status message. -
Other incorrect delete commands to try:
edit
,edit x
,...
(where x is larger than the list size)
Expected: Similar to previous.
-
Deleting residents
-
Deleting multiple resident while all residents are being shown
-
Prerequisites: View all resident using the
view
command. Multiple residents in the list. -
Test case:
delete 1 2
Expected: First and second residents are deleted from the list. Names of the deleted residents shown in the status message. -
Test case:
delete 0
Expected: No resident is deleted. Error details shown in the status message. -
Other incorrect delete commands to try:
delete
,delete x
,...
(where x is larger than the list size)
Expected: Similar to previous.
-
Tracing residents
-
Tracing a resident who has been in contact with 2 others in one event over the past week
-
Prerequisites: A resident in room
A213
who shares an event with 2 others in the past week -
Test case:
trace r/a213
Expected: 2 close contact residents are listed.
-
-
Tracing a resident who has been in contact with 2 others in one event over the past week, of which one has been in contact with another in the past 9 days.
-
Prerequisites: A resident in room
A213
who shares an event with 2 others of which one shares another event with one other in the past 9 days. -
Test case:
trace r/a213 d/2 t/9
Expected: 3 close contact residents are listed.
-
-
Tracing a resident for a 0 depth
- Test case:
trace r/a213 d/0
Expected: Error message specifying that an invalid depth is entered.
- Test case:
-
Tracing a resident for over 31 days
- Test case:
trace r/a213 t/58
Expected: Error message specifying that an invalid duration is entered.
- Test case:
Sorting residents
-
Sorting the list of residents by valid fields and order
- Test case:
sort by/n o/a
Expected: List of residents are sorted by their names in the alphabetical order.
- Test case:
-
Sorting the list of residents by invalid fields or order
-
Test case:
sort by/z o/a
Expected: Error message shown,FIELD should be one of the following: n, e, r, p, f, v, fd, cd
-
Test case:
sort by/n o/z
Expected: Error message shown,ORDER should be one of the following: a, d
-
Importing resident data
-
Import 5 residents from a correctly formatted csv
-
Prerequisites: A correctly formatted csv with 6 rows named
safeforhall
-
Test case:
import safeforhall
Expected: 5 residents displayed with correct information and all resident lists cleared from events.
-
-
Non existent filename provided
- Prerequisites: csv file
nonexistent.csv
should not be present in thedata/
folder - Test case:
import nonexistent
Expected: Error message shown specifying the csv file has not been found.
- Prerequisites: csv file
-
Missing fields for a specific resident row
-
Prerequisites: csv file
safeforhall.csv
has one resident row with missing vaccination status -
Test case:
import safeforhall
Expected: Error message shown specifying the row at which the error occurred.
-
Exporting residents’ emails
-
Export email addresses of list of residents
- Test case:
export testEmailExport
Expected: Csv file filled with column of email addresses of the residents displayed in the app.
- Test case:
-
Duplicate filename provided
- Prerequisites: csv file
testDuplicateExport.csv
is already in existing/data/exports
directory - Test case:
export testDuplicateExport
Expected: Error message shown,This filename already exists
- Prerequisites: csv file
Adding an event
-
Adding an event and its information into the app
- Test case:
add n/Swim v/Pool d/10-10-2021 t/1900 c/10
Expected: An event namedswim
with the relevant information is added into the app, shown in the GUI. Success message is shown.
- Test case:
-
Adding a duplicate event
- Prerequisites: An event with the same name, venue, date and time exists.
- Test case:
add n/Swim v/Pool d/10-10-2021 t/1900 c/10
Expected: Error message shown specifying that such an event already exists.
-
Adding an event with invalid parameters
-
Test case:
add n/Swim v/Pool d/10-10-2021 t/1900 c/0
Expected: Error message shown specifying that capacity needs to be a positive integer. -
Test case:
add n/Swim v/Pool d/10-10-2021 t/2500 c/5
Expected: Error message shown specifying that time provided is invalid. -
Test case:
add n/Swim v/Pool d/30-02-2021 t/1900 c/0
Expected: Error message shown specifying that date provided is invalid.
-
Viewing an event
-
View a list of all the events in the app, or the information of a specific event
-
Test case:
view
Expected: A list of all the events is displayed in the app’s GUI -
Test case:
view 3
Expected: Additional details of the event currently at index 3 will be displayed in the GUI.
-
-
Invalid indexes provided
- Test case:
view x
(where x is larger than the list size)
Expected: Error message shown,The event index provided is invalid
- Test case:
Finding an event
-
Shows a list of events that match the provided keywords for different available parameters.
-
Prerequisites: NIL
-
Test case:
find c/5
Expected: A list of all the events with capacity 5 is displayed in the app’s GUI -
Test case:
find n/Football Training
Expected: A list of all the events which contain the words “Football” and “Training” is displayed in the app’s GUI -
Other incorrect delete commands to try:
find
,find d/03-01
(invalid date input)
Expected: Error message shown
-
Editing an event
-
Edit an event’s details while all events are being shown
-
Prerequisites: View all events using the
view
command. Multiple events in the list. Edited event does not already exist in the address book. -
Test case:
edit 1 c/5
Expected: First event capacity is updated to 5. Updated event details shown in the status message. -
Test case:
edit 0
Expected: No event is edited. Error details shown in the status message. -
Other incorrect delete commands to try:
edit
,edit x
,...
(where x is larger than the list size)
Expected: Similar to previous.
-
Deleting an event
-
Deleting an event while all persons are being shown
-
Prerequisites: List all events using the
view
command (without any parameters). Multiple events in the list. -
Test case:
delete 3
Expected: The third event is deleted from the list. Details of the deleted event shown in the status message. -
Test case:
delete 0
Expected: No event is deleted. Error details shown. -
Other incorrect delete commands to try:
delete -1
,delete x
(where x is larger than the list size)
Expected: Similar to previous.
-
Sorting events
-
Sorting the list of events by valid fields and order
- Test case:
sort by/n o/a
Expected: List of events are sorted by their names in the alphabetical order.
- Test case:
-
Sorting the list of events by invalid fields or order
-
Test case:
sort by/z o/a
Expected: Error message shown,FIELD should be one of the following: n, d, c, v
-
Test case:
sort by/n o/z
Expected: Error message shown,ORDER should be one of the following: a, d
-
Adding residents to an Event
- Add a single valid resident by name to a valid Event
- Prerequisites: There is resident with name “Alex Yeoh” and room “A101”, and an event with index 1.
- Test case:
include 1 r/Alex Yeoh
Expected: The given resident will be added to the event. Sidebar will reflect that the resident is in the event.
- Add a single valid resident by room to a valid Event
- Prerequisites: There is resident with name “Alex Yeoh” and room “A101”, and an event with index 1.
- Test case:
include 1 r/A101
Expected: The given resident will be added to the event. Sidebar will reflect that the resident is in the event.
- Add multiple valid residents by names to a valid Event
- Prerequisites: There are two residents with names “Alex Yeoh” and “Bernice Yu”, with rooms “A101” and “A102” respectively, and an event with index 1.
- Test case:
include 1 r/Alex Yeoh, Bernice Yu
Expected: The given residents will be added to the event. Sidebar will reflect that the residents are in the event.
- Add multiple valid residents by rooms to a valid Event
- Prerequisites: There are two residents with names “Alex Yeoh” and “Bernice Yu”, with rooms “A101” and “A102” respectively, and an event with index 1.
- Test case:
include 1 r/A101, A102
Expected: The given residents will be added to the event. Sidebar will reflect that the residents are in the event.
- Add a valid resident to an valid Event but without comma separating the rooms
- Prerequisites: There are two residents with names “Alex Yeoh” and “Bernice Yu”, with rooms “A101” and “A102” respectively, and an event with index 1.
- Test case:
include 1 r/A101 A102
Expected: The given residents are not added to the event. The result box will indicate that names/rooms have to be separated by a comma.
- Add a valid resident to an invalid Event
- Prerequisites: There is resident with name “Alex Yeoh” and room “A101”, and there is no event with index 1.
- Test case:
include 1 r/Alex Yeoh
Expected: The given resident is not added to the event. The result box will show that the given index is invalid.
- Add an invalid resident to a valid Event
- Prerequisites: There is no resident with name “Alex Yeoh” or room “A101”, but there is an event with index 1.
- Test case:
include 1 r/A101
Expected: The given resident is not added to the event. The result box will show that no residents with the given information could be found.
Removing residents from an Event
- Remove a single valid resident by name from a valid Event
- Prerequisites: There is resident with name “Alex Yeoh” and room “A101”, and an event with index 1.
- Test case:
exclude 1 r/Alex Yeoh
Expected: The given resident will be removed from the event. Sidebar will reflect that the resident is no longer in the event.
- Remove a single valid resident by room from a valid Event
- Prerequisites: There is resident with name “Alex Yeoh” and room “A101”, and an event with index 1.
- Test case:
exclude 1 r/A101
Expected: The given resident will be removed from the event. Sidebar will reflect that the resident is no longer in the event.
- Remove multiple valid residents by names from a valid Event
- Prerequisites: There are two residents with names “Alex Yeoh” and “Bernice Yu”, with rooms “A101” and “A102” respectively, and an event with index 1.
- Test case:
exclude 1 r/Alex Yeoh, Bernice Yu
Expected: The given residents will be removed from the event. Sidebar will reflect that the residents are no longer in the event.
- Remove multiple valid residents by rooms from a valid Event
- Prerequisites: There are two residents with names “Alex Yeoh” and “Bernice Yu”, with rooms “A101” and “A102” respectively, and an event with index 1.
- Test case:
exclude 1 r/A101, A102
Expected: The given residents will be removed from the event. Sidebar will reflect that the residents are no longer in the event.
- Remove a valid resident from an valid Event but without comma separating the rooms
- Prerequisites: There are two residents with names “Alex Yeoh” and “Bernice Yu”, with rooms “A101” and “A102” respectively, and an event with index 1.
- Test case:
exclude 1 r/A101 A102
Expected: The given residents are not removed from the event. The result box will indicate that names/rooms have to be separated by a comma.
- Remove a valid resident from an invalid Event
- Prerequisites: There is resident with name “Alex Yeoh” and room “A101”, and there is no event with index 1.
- Test case:
exclude 1 r/Alex Yeoh
Expected: The given resident is not removed from the event. The result box will show that the given index is invalid.
- Remove an invalid resident from a valid Event
- Prerequisites: There is no resident with name “Alex Yeoh” or room “A101”, but there is an event with index 1.
- Test case:
exclude 1 r/A101
Expected: The given resident is not removed from the event. The result box will show that no residents with the given information could be found.
Switch between tabs
-
Switch between the event and resident tabs
-
Prerequisites: NIL
-
Test case:
switch
when the user is at the Event tab Expected: The GUI switches from displaying the Event tab to the Resident tab
-
Saving data
-
Dealing with missing/corrupted data files
- {explain how to simulate a missing/corrupted file, and the expected behavior}
-
{ more test cases … }