Developer Guide
- Acknowledgements
- Setting up, getting started
- Design
- Implementation
- Documentation, logging, testing, configuration, dev-ops
- Appendix: Requirements
- Appendix: Instructions for manual testing
-
Appendix: Planned Enhancements
- Editing a pair by index:
edit_pair
- Deleting a pair by index:
delete_pair
- Display birthdate in person cards
- Enhance display of large number of tags
- Enhance display of pair information
- Enhance effectiveness of autoPair feature
- Enhance available dates feature
- Enhance name to accept special characters
- Enhance warning message for input validation
- Editing a pair by index:
- Appendix: Efforts
- Glossary
Acknowledgements
- AddressBook Level-3 documentation
- AddressBook Level-3 code
- Agolia Documentation
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 here folder. Refer to the PlantUML Tutorial at se-edu/guides to learn how to create and edit diagrams.
Architecture
The General Architecture of FriendlyLink follows that of AddressBook3.
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_elderly S1234567G
.
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
, ElderlyListPanel
, 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 displaysElderly
,Volunteer
andPair
objects 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 theFriendlyLinkParser
class to parse the user command. - This results in a
Command
object (more precisely, an object of one of its subclasses e.g.,AddPairCommand
) which is executed by theLogicManager
. - The command can communicate with the
Model
when it is executed (e.g. to add a pair). - 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_elderly S1234567I")
API call.
DeleteElderlyCommandParser
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
FriendlyLinkParser
class creates anXYZCommandParser
(XYZ
is a placeholder for the specific command name e.g.,AddPairCommandParser
) which uses the other classes shown above to parse the user command and create aXYZCommand
object (e.g.,AddPairCommand
) which theFriendlyLinkParser
returns back as aCommand
object. - All
XYZCommandParser
classes (e.g.,AddPairCommandParser
,DeletePairCommandParser
, …) 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
FriendlyLink
data i.e., allElderly
,Volunteer
andPair
objects (which are contained in aUniqueElderlyList
,UniqueVolunteerList
andUniquePairList
objects respectively). - stores the currently ‘selected’
Elderly
,Volunteer
andPair
objects (e.g., results of a search query) as a separate filtered list which is exposed to outsiders as an unmodifiableObservableList<Elderly>
,ObservableList<Volunteer>
andObservableList<Pair>
respectively 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. - depends on some classes in the
Storage
component (because theModel
component requiresStorage
to save/retrieve objects that belong to theModel
)
This is the detailed implementation of Person
in Model
.
- Both
Elderly
andVolunteer
inherit from the abstract classPerson
. - A
Pair
makes reference to oneElderly
and oneVolunteer
each.
Storage component
API : Storage.java
The Storage
component,
- can save
Elderly
,Volunteer
,Pair
andUserPrefs
data in JSON format, and read them back into corresponding objects. - inherits from
ElderlyStorage
,VolunteerStorage
,PairStorage
andUserPrefStorage
, which means it can be treated as either one (if only the functionality of only one is needed). - does not depend on any of the other three components (as the
Storage
represents data entities on disk, they should make sense on their own without depending on other components)
Common classes
Classes used by multiple components are in the seedu.address.commons
package.
Implementation
This section describes some noteworthy details on how certain features are implemented.
Add and Delete Elderly and Volunteer
In FriendlyLink, Elderly
and Volunteer
are both implemented as subclasses of the abstract class Person
.
The add_elderly
and add_volunteer
commands accept attributes of Elderly
and Volunteer
through prefixes.
Each prefix is followed by the information of one attribute.
Some prefixes, such as availableDates
, tags
, are optional.
- This grants greater flexibility of user input, as the user can key in the attributes in any order.
- The unspecified optional fields will return
null
value. - The
NRIC
attribute for Elderly and Volunteer will be cross-checked to ensure no duplicates. - When the
add
command format is invalid, or the user tries to add a duplicated person, the add operation will be aborted.
The Elderly and Volunteers are stored in separate UniquePersonList
lists.
- Allows for filtering to display a subset of Elderly or Volunteers in UI.
- Allows for easy retrieval of information for pairing.
The delete_elderly
and delete_volunteer
commands make use of the NRIC
attribute of Elderly and Volunteer.
FriendlyLink retrieves the target person uniquely identified by its NRIC,
and removes it from the database.
- Allows more efficient deletion compare to index-based deletion.
- The user don’t need to check the index of the target person before deletion.
If the deleted Elderly or Volunteer has existing pairings, the associated pairs will be automatically removed as well.
Command Recommendation and Autocompletion of Field’s Prefixes
Both autocompletion and recommendation are facilitated by CommandRecommendationEngine.java
. The Logic component registers
individual command parsers, which implement the Parser
interface, to enable recommendations of command inputs. Each parser,
such as {XYZ}CommandParser
, specifies how recommendation should differ for a specific command by overriding the
Parser#getCommandInfo
method. When the user types a valid command, the CommandBox
UI component detects the keystroke
through its KeyPressedHandler
and triggers the CommandRecommendationEngine#generateCommandRecommendations
method.
This method then returns the relevant recommendations. When a KeyEvent.TAB
event is triggered, autocompletion builds
on the method and replaces the user input with the recommended values.
Using the longest prefix match algorithm, the engine first identifies the related command and then verifies the fields associated with it. If there are ambiguities in the recommendations, the recommendation will rank the commands using lexicographical ordering.
In order to simplify implementation, we differentiate between two types of commands: “Full Attribute” commands and “Complete” commands. A “Full Attribute” command is one in which all the fields, both optional and required, have been specified. A “Complete” command, on the other hand, means that the command has been fully typed, but the fields may or may not have been entered. This distinction assists the engine in giving more precise suggestions based on the user’s input.
The following activity diagram describes the activity flow:
Design considerations
Aspect: How recommendation executes:
Alternative 1 (current choice): Custom recommendations for each command
- Requires each
{XYZ}CommandParser
to override theParser#getCommandInfo
method, specifying the exact behaviour on how recommendations should behave. - Recommendations will be more relevant to the current command, and user input can be validated against the set of possible prefixes specified in the overridden method.
Alternative 2: Store all possible prefixes and recommends based on user input
- Cannot enforce that user only inputs relevant prefixes as there is no reference as to what the “correct” prefixes are.
- Likewise, such design is unable to recommend all relevant attributes, which can greatly reduce the user experience.
Edit by index & NRIC
In FriendlyLink, there are 2 methods to choose which elderly/volunteer to edit:
- via index using the
edit_elderly
andedit_volunteer
commands. - via NRIC using the
edit
command.
Similar to adding elderly/volunteers, editing is done by specifying the desired field(s) to edit using their prefixes, and then providing the new value for the field(s). For consistency, the prefixes between the adding and editing commands are kept the same.
For the editing of fields that accept multiple arguments (i.e. AvailableDate
, Tag
and MedicalQualificationTag
),
the specified behaviour is to leaves them unchanged if no new values are provided, else overwrite the existing values
with the newly provided values.
Retrieving of the desired Elderly
/Volunteer
to edit is done differently
depending on whether edit_elderly
/edit_volunteer
or edit
is called:
-
edit_elderly
/edit_volunteer
: TheElderly
/Volunteer
is retrieved directly from thefilteredElderly
/filteredVolunteer
ofModel
. -
edit
: We first check if anElderly
with the specified NRIC exists inModel
. If so, we retrieve it; Otherwise, we perform a similar check forVolunteer
, and retrieve it if such aVolunteer
exists.
These edits are performed primarily through the EditDescriptor
class. This class
contains Optional
types of the union of the fields between Elderly
and Volunteer
. In order to “transform”
a given volunteer/elderly with the edited fields, 2 important static methods are provided:
-
createEditedElderly(Elderly, EditDescriptor)
: returns a newElderly
representing the givenElderly
modified with the values specified in theEditDescriptor
-
createEditedVolunteer(Volunteer, EditDescriptor)
: returns aVolunteer
representing the givenVolunteer
modified with the values specified in theEditDescriptor
The Elderly
/Volunteer
are then edited in the model using the setElderly
/setVolunteer
methods
of Model
respectively.
Design decisions:
- The reason behind the
editDescriptor
class, as opposed to directly using anElderly
orVolunteer
class, is that it better encapsulates the logic behind editing. That is, with the sameeditDescriptor
object, we can easily “edit” multipleElderly
andVolunteer
objects simply through thecreateEditedElderly
/createEditedVolunteer
methods. - Initially, we had created 2 separate descriptor classes
ElderlyEditDescriptor
andVolunteerEditDescriptor
. However, we felt that this was simply unnecessary, and combined them into a singleeditDescriptor
class instead.
As an example, the following sequence diagram shows the sequence for the command edit S1234567I n/Shaun ag/21
, where
the NRIC S1234567I
belongs to an existing volunteer:
EditCommandParser
should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram.
Find by keyword
The find
command allows users to easily filter and locate the relevant elderly and volunteers, together with their related parings.
The results of the find
command are displayed as the filtered version of the elderly, volunteers and pairs lists,
together with the number of entities listed being shown in the command result box.
Volunteers and elderly who match all the provided attributes that they have are filtered out and displayed in their respective list. For each filtered person, Any pairings that they are involved in will be filtered and displayed in the pair list.
Arguments for the find
command involve at least one of the attributes belonging to an elderly or a volunteer.
Any number of attributes can be specified but if multiple of the same attribute is specified then only the last one will be
used in the search.
The Sequence Diagram below illustrates the execution of the find
command.
The command execution flow is as given below
- The
LogicManager
will begin the execution of the command. - Input parsed by
FriendlyLinkParser
which creates and return aFindCommandParser
. - The
FindCommandParser
parses the arguments and returns aFindCommand
with the relevant predicates. - The
LogicManager
executes theFindCommand
. - The
FindCommand
combines the relevant predicates for elderly and volunteers and callsupdateFilteredElderlyList
andupdateFilteredVoolunteerList
ofModel
. - Based on the filtered elderly and volunteers a predicate to get the related pairs is created and
updateFilteredPairList
ofModel
is called. -
CommandResult
with the sizes of the 3 filtered lists is created and returned.
The class diagram below shows the relation of predicates to FindCommandParser
and FindCommand
.
Design decisions:
- Name, address, email, phone, tags and medical qualification attributes allow substring searching.
- Easier to search with only partial information available.
- When multiple attributes and stated, the result must match all instead of any.
- The search should narrow the field with each additional new attribute for a more targeted result.
- Related pairings are also shown during the search.
- Provides a comprehensive search results where all information related to the people found are shown.
- People with available dates that contain the specified dates or have no available dates will be found when searching with the specified dates.
- They are found because they are available on the specified dates.
Pairing and unpairing of elderly and volunteers
Pairs are implemented as a class with 2 referenced attributes, Elderly
and Volunteer
.
- This allows the NRIC of a person in the pair to be automatically updated when the person is updated.
The pairs are stored in a list similar to persons.
- Allows for filtering to display a subset of pairs in the UI.
- Allows for identifying a pair by index.
Two pairs are identical if they have the same elderly and volunteer NRIC.
- Just like persons, we do not allow duplicate pairs (due to add or edit pair)
- Elderly and volunteer NRIC is used to identify a pair for deletion.
Summary Statistics
The stats
command displays summary statistics about FriendlyLink, such as the total number of elderly, volunteers and unpaired persons.
It is implemented using the Summary
and AggregateFunction
class.
The AggregateFunction
- describes a particular statistic of FriendlyLink with a number.
- is an abstract class that requires concrete classes to override the
getDescription()
andgetResult()
method.
The Summary
object
- formats the results to be displayed to the user.
- takes in 0 or more
AggregateFunction
s to show their description and results.
The StatsCommand
keeps a Summary
object. When StatsCommand
’s execute
method is called, it creates all the AggregateFunction
s with appropriate arguments and passes them to the Summary
to be described.
Storage
This section specifies how entities such as Elderly
, Volunteer
and Pair
are stored on disk.
Elderly, volunteers and pairs are stored in separate files to reduces the impact of a corrupted file, since it will only affect either elderly or volunteers.
Persons
Persons saved contains all their attributes such as name, NRIC, in JSON format.
- Single value attributes are stored as key value pairs, such as name and NRIC.
- Multiple value attributes such as tag and available date sets are stored as JSON lists.
Pairs
Pairs saved only contains the NRIC of the elderly and volunteer in JSON format.
Reasons
- Reduce space needed to store pairs.
- Reduce chance of inconsistent data between a person and the corresponding pair.
- Reduce number of files to amend manually when updating person information.
Implications
- A pair is reconstructed on startup by searching the model for the corresponding person.
- Elderly and volunteer files need to be read into the model before pair files.
Documentation, logging, testing, configuration, dev-ops
Appendix: Requirements
Product scope
Target user profile:
- single administrator of a Voluntary Welfare Organisation (VWO) who needs to track volunteers and their assigned elderly.
- works alone in managing volunteer and elderly information.
- adequately tech-savvy.
- has a need to manage a significant number of volunteers and elderly.
- prefers desktop applications over other types.
- can type fast.
- prefers typing to mouse interactions.
- comfortable using CLI applications.
Value proposition: FriendlyLink streamlines volunteer and elderly management for single administrators of VWOs. With its easy-to-use text-based interface and contact management features, say goodbye to manual record-keeping and hello to a more efficient and organised way of managing volunteers’ and elderly’s contact details.
User stories
Priorities: High (must have) - * * *
, Medium (nice to have) - * *
, Low (unlikely to have) - *
Priority | As a … | I want to … | So that I can… |
---|---|---|---|
* * * |
single administrator of a VWO | view the list of volunteers | see all the volunteers and their information readily |
* * * |
single administrator of a VWO | add a new volunteer to the system | track and manage new volunteers |
* * * |
single administrator of a VWO | remove an existing volunteer from the system | stop tracking volunteers that have left |
* * * |
single administrator of a VWO | edit the particulars of a volunteer, such as names or addresses | keep their information up to date and rectify any error |
* * * |
single administrator of a VWO | view the list of elderly | see all the elderly and their information readily |
* * * |
single administrator of a VWO | add a new elderly member to the system | track and manage new elderly |
* * * |
single administrator of a VWO | remove an existing elderly member from the system | stop tracking elderly that have left |
* * * |
single administrator of a VWO | edit the particulars of an elderly, such as names or addresses | keep their information up to date and rectify any error |
* * * |
single administrator of a VWO | find a particular volunteer or elderly by NRIC | uniquely identify and access their information |
* * * |
single administrator of a VWO | remove pairings that elderly and volunteers are involved in when they are removed from the system | maintain accurate and error-free records of pairings |
* * * |
single administrator of a VWO | add a pair of a volunteer and an elderly | track and manage pairings of volunteer and elderly |
* * * |
single administrator of a VWO | find and list unpaired volunteers and elderly | prioritise pairing volunteers and elderly who are unpaired |
* * * |
single administrator of a VWO | remove pairings | to remove pairs that are no longer valid |
* * |
single administrator of a VWO | search for particular volunteers by keywords | quickly see the volunteer’s details |
* * |
single administrator of a VWO | view nursing / medical courses that volunteers have taken in the past | pair an elderly with a more suitable volunteer |
* * |
single administrator of a VWO | filter and list elderly members by keyword search of name | increasing efficiency of finding elderly with certain names |
* * |
single administrator of a VWO | filter pairs by involved elderly members | to quickly find involved volunteers when elderly members are in need of attention |
* * |
single administrator of a VWO | filter and list elderly members by age group | dedicate more attentions to older members |
* * |
single administrator of a VWO | filter and list elderly members by risk level | dedicate more attentions to members with higher risks |
* * |
single administrator of a VWO | filter and list elderly members by region and community | pair volunteers who can better reach out to elderly living close-by |
* * |
single administrator of a VWO | search elderly members by tags | access the information of elderly members with specific tags |
* * |
single administrator of a VWO | autocomplete commands | know what are some possible commands and fields that I need to type |
* * |
single administrator of a VWO | rank elderly members in the order of their medical risk level | better pair volunteers with more medical knowledge with higher-risk elderly |
* * |
single administrator of a VWO | keep track of the region and community of the elderly members | reach out to the elderly members conveniently |
* * |
single administrator of a VWO | view the last visited time/date of the elderly | know when to plan the next visit |
* * |
single administrator of a VWO | set up reminder system for elderly | plan volunteers to assist on those days |
* * |
single administrator of a VWO | find a pair by keyword | to quickly look up important information when required |
* * |
single administrator of a VWO | view overlapping pairs between the same volunteers or elderly members | to take note of overlapping work. |
* * |
single administrator of a VWO | filter pairs by tags | to quickly find certain groups of elderly members for events or routine checkups |
* * |
single administrator of a VWO | see summaries of number of elderly members assigned to each volunteer | to evenly distribute workload of volunteers |
* * |
single administrator of a VWO | see min, max and average number of elderly buddies per volunteer | to evenly distribute workload of volunteers or to request for more resources |
* |
single administrator of a VWO | filter volunteers by tags | access relevant groups of volunteers quickly |
* |
single administrator of a VWO | manage volunteers by region | arrange the volunteers such that they can conveniently reach out to the elderly |
* |
single administrator of a VWO | record the community information of volunteers, but not their specific address | ensure that the volunteers’ privacy is not compromised |
* |
single administrator of a VWO | manage the volunteers’ available dates and time | efficiently find volunteers available for activities |
* |
single administrator of a VWO | see how long a volunteer has been with the program | assess their experience |
* |
single administrator of a VWO | track the befriending history of a volunteer | audit past involvements easily |
* |
single administrator of a VWO | rank elderly members in the order of their loneliness situation | arrange more frequent volunteer visits for more lonely elderly |
* |
single administrator of a VWO | track the befriending history of an elderly | audit past involvements easily |
* |
single administrator of a VWO | view past pairings | to pair up members familiar with each other |
* |
single administrator of a VWO | making recurring pairings | to handle recurrent changes in pairs. |
* |
single administrator of a VWO | adjust frequency and period limit of pairings | to facilitate regular swaps of volunteers and elderly members. |
* |
single administrator of a VWO | track important dates | to facilitate regular volunteer check ins on elderly members. |
* |
single administrator of a VWO | set up reminders | to remind volunteers of their commitments |
* |
single administrator of a VWO | set up version control of the application | trace commands that are executed throughout the lifetime of the application |
* |
lazy single administrator of a VWO | automatically pair up available volunteers to elderly | quickly assign a volunteer to an elderly |
* |
efficient single administrator of a VWO | use natural language dates | quickly assign add a volunteer availability into the database |
* |
organized single administrator of a VWO | add tags to volunteer, elderly and pairs | filter the entities by tags |
* |
organized single administrator of a VWO | assign a random integer ID to each entry | retrieve, modify and delete them directly without looking through the list |
* |
organized single administrator of a VWO who have used the application for a long time | retrieve summary statistics of elderly, volunteers, and pairs in the database | have a better understanding of the organisation and it’s clients |
Use cases
(For all use cases below, the System is the FriendlyLink (FL)
and the Actor is the Admin
, unless specified otherwise)
Use case: UC01- Pair Volunteer and Elderly
Preconditions: Elderly and Volunteer is already in FL.
MSS
- User enters the details of elderly and volunteer to be paired into the application.
- FL feedbacks the successful addition of the pair, and shows the new pair.
-
User sees the new pair in FL.
Use case ends.
Extensions
- 1a. FL detects that the elderly is not in the current database.
- 1a1. FL informs User that the elderly has not been created.
Use case ends.
- 1b. FL detects that volunteer is not in the current database.
- 1b1. FL informs User that the volunteer has not been created.
Use case ends.
- 1c. FL detects missing arguments or an error in the entered command.
- 1c1. FL feedbacks that entered command is incorrect.
Use case ends.
- 1d. FL detects duplicate pair records in the entered command.
- 1d1. FL feedbacks that it is a duplicate record.
Use case ends.
Use case: UC02- Add Elderly
MSS
- User enters the details of elderly to be added into the application.
- FL feedbacks the successful addition of the elderly, and shows the new elderly.
-
User sees the new elderly in FL.
Use case ends.
Extensions
- 1a. FL detects missing arguments or an error in the entered command.
- 1a1. FL feedbacks that entered command is incorrect.
Use case ends.
- 1b. FL detects duplicate elderly records in the entered command.
- 1b1. FL informs it is a duplicate record.
Use case ends.
Use case: UC03- Add Volunteer
MSS
- User enters the details of volunteer to be added into the application.
- FL feedbacks the successful addition of the volunteer and shows the new volunteer.
-
User sees the new volunteer in FL.
Use case ends.
Extensions
- 1a. FL detects missing arguments or an error in the entered command.
- 1a1. FL feedbacks that entered command is incorrect.
Use case ends.
- 1b. FL detects duplicate volunteer records in the entered command.
- 1b1. FL informs it is a duplicate record.
Use case ends.
Use case: UC04- Unpair Volunteer and Elderly
Preconditions: Volunteer and elderly is already paired in FL.
MSS
- User enters the pair details (elderly & volunteer) to be deleted into FL.
- FL feedbacks the successful unpairing and removes the pair from view.
-
User sees that the pair is removed from FL.
Use case ends.
Extensions
- 1a. FL detects that the elderly is not in the current database.
- 1a1. FL informs User that the elderly has not been created.
Use case ends.
- 1b. FL detects that volunteer is not in the current database.
- 1b1. FL informs User that the volunteer has not been created.
Use case ends.
- 1c. FL detects missing arguments or an error in the entered command.
- 1c1. FL feedbacks that entered command is incorrect.
Use case ends.
Use case: UC05- Delete Volunteer
Preconditions: Volunteer is already in FL.
MSS
- User enters the NRIC of the volunteer to be deleted.
- FL feedbacks the successful deletion of the volunteer, and removes the volunteer from view.
-
User sees that the volunteer is removed from FL.
Use case ends.
Extensions
- 1a. FL detects missing arguments or an error in the entered command.
- 1a1. FL feedbacks that entered command is incorrect.
Use case ends.
Use case: UC06- Delete Elderly
MSS
- User enters the NRIC of the elderly to be deleted.
- FL feedbacks the successful deletion of the elderly and removes the elderly from view.
-
User sees that the elderly is removed from FL.
Use case ends.
Extensions
- 1a. FL detects missing arguments or an error in the entered command.
- 1a1. FL feedbacks that entered command is incorrect.
Use case ends.
Use case: UC07- Edit Elderly
Preconditions: Elderly is already in FL.
MSS
- User enters the index of the elderly to be edited, together with the details of the fields to be edited.
- FL feedbacks the successful edit of the elderly and shows the updated elderly.
-
User sees that the elderly is updated in FL.
Use case ends.
Extensions
- 1a. FL detects missing arguments or an error in the entered command.
- 1a1. FL feedbacks that entered command is incorrect.
Use case ends.
Use case: UC08- Edit Volunteer
Preconditions: Volunteer is already in FL.
MSS
- User enters the index of the volunteer to be edited, together with the details of the fields to be edited.
- FL feedbacks the successful edit of the volunteer and shows the updated volunteer.
-
User sees that the volunteer is updated in FL.
Use case ends.
Extensions
- 1a. FL detects missing arguments or an error in the entered command.
- 1a1. FL feedbacks that entered command is incorrect.
Use case ends.
Use case: UC09- Edit Person identified by NRIC
Preconditions: Person is already in FL.
MSS
- User enters the NRIC of the person to be edited, together with the details of the fields to be edited.
- FL feedbacks the successful edit of the person and shows the updated person.
-
User sees that the person is updated in FL.
Use case ends.
Extensions
- 1a. FL detects missing arguments or an error in the entered command.
- 1a1. FL feedbacks that entered command is incorrect.
Use case ends.
Use case: UC10- Find person and related pairs
MSS
- User enters the details of all the fields to be matched.
- FL shows all the matching elderly, volunteer and pairs.
-
User sees all the relevant persons and pairs in FL.
Use case ends.
Extensions
- 1a. FL detects missing arguments or an error in the entered command.
- 1a1. FL feedbacks that entered command is incorrect.
Use case ends.
Use case: UC11- View all persons and pairs
MSS
- User enters the command to list all persons and pairs.
- FL shows all the current elderly, volunteers and pairs.
-
User sees all persons and pairs in FL.
Use case ends.
Extensions
- 1a. FL detects missing arguments or an error in the entered command.
- 1a1. FL feedbacks that entered command is incorrect.
Use case ends.
Use case: UC12- View paired persons
MSS
- User enters the command to list all paired persons.
- FL shows all the paired elderly, paired volunteers and all pairs.
-
User sees all paired persons and all pairs in FL.
Use case ends.
Extensions
- 1a. FL detects missing arguments or an error in the entered command.
- 1a1. FL feedbacks that entered command is incorrect.
Use case ends.
Use case: UC13- View unpaired persons
MSS
- User enters the command to list all unpaired persons.
- FL shows all the unpaired elderly, unpaired volunteers and all pairs.
-
User sees all unpaired persons and all pairs in FL.
Use case ends.
Extensions
- 1a. FL detects missing arguments or an error in the entered command.
- 1a1. FL feedbacks that entered command is incorrect.
Use case ends.
Use case: UC14- View statistics
MSS
- User enters the command to see statistics.
- FL shows the statistics of elderly, volunteer, pairs and their pairing situations.
-
User sees the summary statistics of persons and pairs in FL.
Use case ends.
Extensions
- 1a. FL detects an error in the entered command.
- 1a1. FL feedbacks that entered command is incorrect.
Use case ends.
Use case: UC15- Look up Help Page
MSS
- User enters the command to see more help.
- FL provides a link to direct user to the user guide webpage.
-
User visits the user guide webpage and reads the relevant sections.
Use case ends.
Extensions
- 1a. FL detects an error in the entered command.
- 1a1. FL feedbacks that entered command is incorrect.
Use case ends.
Use case: UC16- Exit the app
MSS
- User enters the command to exit FriendlyLink.
- FL exits.
-
User sees that FL has exited.
Use case ends.
Extensions
- 1a. FL detects an error in the entered command.
- 1a1. FL feedbacks that entered command is incorrect.
Use case ends.
Non-Functional Requirements
- FriendlyLink should work on Microsoft Windows, macOS, and Linux that has
Java 11
is installed. - FriendlyLink should be able to hold up to 100 person (elderly and volunteer) without incurring a delay larger than 3 second for any command.
- A user with above average typing speed (40wpm) for regular English text (i.e. not code, not system admin commands) should be able to perform at least 75% of use cases faster using commands instead of using the mouse.
- FriendlyLink will perform minimal checks on correctness of details entered into FriendlyLink.
- FriendlyLink will not be responsible for the privacy and security of the data stored in FriendlyLink.
- FriendlyLink will not recover from corrupted data files.
- FriendlyLink will only be available in English.
- FriendlyLink does not require internet connection to work.
- FriendlyLink is meant for VWOs in Singapore to store information about elderly and volunteers, and pair them up.
Appendix: Instructions for manual testing
Given below are instructions to test the app manually. You are recommended to start with an empty FriendlyLink and follow the instructions sequentially in order for the example commands provided to be relevant. You can refer to the user guide for more details on the features.
Launch
- Initial launch
- Download the jar file and copy it into an empty folder.
- Double-click the jar file.
- Expected: The program runs and shows the GUI. Note that the window size may not be optimum.
Viewing help
- Opening the help window
- Type the following help command into the text field.
help
- Press enter.
- Expected: The GUI shows a popup with a message and a link to the user guide.
- Type the following help command into the text field.
Adding records
- Adding an elderly
- Type the following add elderly command into the text field.
add_elderly n/John Doe ic/S5583628H bd/1955-11-24 re/NORTH r/LOW p/93456688 e/Jdoe@gmail.com a/Coral street t/single dr/2023-06-03, 2023-06-25
- Press enter.
- Expected: The GUI shows the added elderly in the elderly list.
- Type the following add elderly command into the text field.
- Adding a volunteer
- Type the following add volunteer command into the text field.
add_volunteer n/Jane Doe ic/T0058345F bd/2000-05-14 re/EAST p/91157884 e/Jane45@gmail.com a/Kings street t/strong mt/cpr, BASIC dr/2023-05-03, 2023-09-25
- Press enter.
- Expected: The GUI shows the added volunteer in the volunteer list.
- Type the following add volunteer command into the text field.
- Pairing a volunteer to an elderly
- Type the following pair command into the text field.
pair eic/S5583628H vic/T0058345F
- Press enter.
- Expected: The GUI shows the pairing in the pair list.
- Type the following pair command into the text field.
Editing records
- Editing an elderly by index
- Type the following edit elderly command into the text field.
edit_elderly 1 p/98337512 r/HIGH
- Press enter.
- Expected: The GUI shows the new fields for the elderly at the specified index. (pair list is updated if applicable)
- Type the following edit elderly command into the text field.
- Editing a volunteer by index
- Type the following edit volunteer command into the text field.
edit_volunteer 1 a/Max street
- Press enter.
- Expected: The GUI shows the new fields for the volunteer at the specified index. (pair list is updated if applicable)
- Type the following edit volunteer command into the text field.
- Editing a person by NRIC
- Type the following edit command into the text field.
edit T0058345F e/guest@gmail.com
- Press enter.
- Expected: The GUI shows the new fields for the person with the specified NRIC. (pair list is updated if applicable)
- Type the following edit command into the text field.
Finding records
- Finding people and their related pairs
- Type the following find command into the text field.
find n/John
- Press enter.
- Expected: The elderly, volunteer and pair list are filtered based on the find command.
- Type the following find command into the text field.
- Listing people who are paired
- Type the following list command into the text field.
list paired
- Press enter.
- Expected: The GUI shows elderly and volunteers who have a pairing in their respective lists. (all pairs are shown)
- Type the following list command into the text field.
- Listing people who are not paired
- Type the following list command into the text field.
list unpaired
- Press enter.
- Expected: The GUI shows elderly and volunteers who do not have a pairing in their respective lists. (all pairs are shown)
- Type the following list command into the text field.
- Listing everyone
- Type the following list command into the text field.
list
- Press enter.
- Expected: The GUI shows all elderly, volunteers and pairs that are in FriendlyLink.
- Type the following list command into the text field.
Show summary statistics
- View the statistics of the displayed elderly, volunteers and pairs
- Type the following stats command into the text field.
stats
- Press enter.
- Expected: Statistics are shown in the command result box in the GUI.
- Type the following stats command into the text field.
Deleting records
- Unpair volunteer and elderly
- Type the following unpair command into the text field.
unpair eic/S5583628H vic/T0058345F
- Press enter.
- Expected: The pairing of the elderly and volunteer with the specified NRICs is removed from the pair list in the GUI.
- Type the following unpair command into the text field.
- Deleting an elderly
- Type the following delete elderly command into the text field.
delete_elderly S5583628H
- Press enter.
- Expected: The elderly with the specified NRICs is removed from the elderly list in the GUI.
- Type the following delete elderly command into the text field.
- Deleting a volunteer
- Type the following delete volunteer command into the text field.
delete_volunteer T0058345F
- Press enter.
- Expected: The volunteer with the specified NRICs is removed from the volunteer list in the GUI.
- Type the following delete volunteer command into the text field.
Exit
- Exiting the app
- Use the
exit
command or click the ‘X’ button in the top right corner.
- Expected: The app closes.
- Use the
Saving
- Saving window preferences
- Resize the window to an optimum size, preferably full screen. Close the window.
- Re-launch the app by double-clicking the jar file.
- Expected: The most recent window size and location is retained.
- Note: The window looks best under 1920 x 1080 resolution, 125% scale.
- Saving data
- Launch the app by double-clicking the jar file.
- Execute an add command to add an
elderly
orvolunteer
in the database. - Close the app.
- Expected: A
data
folder is created under the current repository where the jar file is located.
Appendix: Planned Enhancements
When creating software, there are always areas that can be improved upon. In the interest of transparency and keeping our users informed, we have identified some aspects of our product that we recognise as feature flaws. We appreciate your patience as we are actively working to find the best solution to address these feature flaws.
Editing a pair by index: edit_pair
Currently, editing a pair by index has not been implemented. This feature can increase the efficiency of using FriendlyLink. This feature was originally deemed low priority, since a pair only has 2 fields: elderly and volunteer, and thus users can reasonably still achieve this by deleting a pair and adding a new pair. Through user feedback, we acknowledge that this is still a useful feature to have to improve efficiency and user experience.
Proposed usage: Edits an existing pair based on their index in the pairs list.
Proposed format: edit_pair INDEX [eic/ELDERLY_NRIC] [vic/VOLUNTEER_NRIC]
Proposed behaviour:
- Edits the pair at the specified
INDEX
in the displayed pair list. - Any combination of the optional fields is possible but at least one optional field must be specified.
- Existing values will be updated to the input values.
Examples:
-
edit_pair 1 eic/T0245267I
Edits the 1st pair so that the volunteer is paired to the elderly with NRICT0245267I
instead.
Deleting a pair by index: delete_pair
Currently, pairs are deleted by specifying NRIC of both elderly and volunteer. This feature can increase the efficiency of using FriendlyLink, if we allow users to simply specify the index of the pair.
This feature is originally implemented as such to prevent accidental deletion of pairs, as it is easy to enter the wrong index but hard to accidentally enter a pair of incorrect NRICs and delete the wrong pair. Through user feedback, we acknowledge that we should implement it to delete by index and support this with an undo
feature to minimise impact of accidental deletions.
Proposed usage: Deletes an existing pair based on their index in the pairs list.
Proposed format: edit_pair INDEX [eic/ELDERLY_NRIC] [vic/VOLUNTEER_NRIC]
Proposed behaviour:
- Edits the pair at the specified
INDEX
in the displayed pair list. - Any combination of the optional fields is possible but at least one optional field must be specified.
- Existing values will be updated to the input values.
Display birthdate in person cards
When users provide a birthdate for an Elderly or Volunteer profile, only the person’s current age is displayed in the app. To view the specific birthdate, users must refer to the respective JSON file. We should include birthdate in each person’s information card as well.
Enhance display of large number of tags
There are no limits on the number of tags or the character limit for each tag. If large number of tags or tags with excessively long names are used, it affects the UI display and impact user experience. We plan to limit each tag within 50 characters, with the total number of tags being less than 20. This would ensure decent degree of input flexibility, while not severely clogging up the UI display.
Enhance display of pair information
Currently, users need to mouse over the pair card to view information of each pair. This reduces the efficiency of FriendlyLink, which is intended to be optimised for typing. We plan to add a command to view pairing details directly as information cards. This would help to improve efficiency of display.
Enhance effectiveness of autoPair feature
autoPair algorithm for pairing up volunteers and elderly users employs a greedy approach, which may not always be the most optimal in terms of time efficiency or number of pairings we can automatically pair. We are continuously searching for better pairing algorithms.
Enhance available dates feature
Currently, available dates take in dates and not time of day.
We should improve it to also allow users to enter time into the availability fields, such as YYYY-MM-DD HH:MM:SS
to provide greater flexibility in specifying availability period.
Enhance name to accept special characters
Currently, names do not accept .
and \\
. This may cause some problems where a person’s legal name contains these special characters.
We should modify the name to accept these special characters.
Enhance warning message for input validation
Currently, when a wrong command or prefix is entered, the input will simply turn red. While this may be intuitive for experienced users,
it may not provide the best experience for new users. As such, we intend to implement a feature which can convert the current recommendation
feature to also display the warning. For example, if the user enters add_person
, this is currently an invalid command,
so the corresponding error message will be displayed in the same text box (replacing the command recommendation).
Appendix: Efforts
Adding records
- This task is of medium difficulty. We managed to implement a variety of attribute fields, such as available dates as date ranges, medical qualifications as tags, and regions as enums.
- Given the different attribute data types, transferring these fields into formats adaptable for JSON storage become the main challenge.
- Furthermore, as we made many of the fields optional, making the tracking and recording of fields with
NULL
values compatible with JSON, given the various data types, becomes another challenge. - Despite these challenges, we successfully added comprehensive and flexible record-keeping capabilities to the system.
Deleting records
- This task is of medium difficulty. We managed to implement logic checks ensuring the logical correctness of deletion. For example, when deleting an elderly record, we also had to delete all of its existing pairs. To ensure the accuracy and correctness, we wrote many unit test cases.
- Through careful testing and debugging, we successfully implemented a reliable and robust deletion feature.
Pairing feature
- This task is of medium difficulty. The main effort involved taking references of elderly and volunteer information instead of copying it, so that when a person’s information is edited, deleted, or searched, the corresponding pairing situation can be displayed.
Editing records
- This task is of medium difficulty. We had to correctly handle all possible correct and incorrect inputs, particularly when we had an ‘edit’ command that was usable by both elderly and volunteer users.
- Through careful unit testing and debugging, we successfully implemented a feature that automatically ignored non-applicable edit fields and update all applicable information.
Finding records
- Finding information was of high difficulty. We had to correctly handle different possible situations, such as when a user entered a wrong field format or a field that was not applicable to the person or when different searching formats were used for enums, date tags, etc.
- Additionally, we had to simultaneously filter elderly, volunteer, and pair cards and display all possible information.
- Through extensive testing and refinement, we successfully implemented a powerful and flexible searching feature.
Command Recommendation
- Implementing the command recommendation feature was of high difficulty. The main challenges were showing the correct command recommendations as the user typed each character and throwing warnings at the correct times.
- For example, the main challenges include that we had to distinguish between “wrong command” and “incomplete command”, as well as detecting existing attributes to avoid repetitive recommendations.
- For this feature, we make use of the Agolia Documentation
- We successfully achieved this feature, which effectively increased input speed and user satisfaction.
Glossary
These terms have specific meanings in the context of FriendlyLink.
Non-Technical
Term | Meaning |
---|---|
Availability Date | The availability of a person. |
BirthDate | The birth date of a person. |
Command | An instruction given by you to FriendlyLink to perform a specific task. |
Date | The date of an event. |
Duplicate Pairs | Two pairs having the same elderly and volunteer are considered a duplicate entry in FriendlyLink. |
Duplicate Persons | Two persons having the same NRIC are considered a duplicate entry in FriendlyLink. |
Elderly | Elderly are people under the care of your VWO. |
The email of a person. | |
FriendlyLink | The name of our application. |
Field | A field is the information following the slash in a command. |
Index | An index represents the position of the referred item in a displayed list of persons. |
Medical Qualification | The level of care taking or first aid of a volunteer. It consists of the skill name and a skill level. |
NRIC | A unique identifier given to all Singaporeans. It is case-insensitive. |
Pair | A pair consists of an elderly and a volunteer assigned to accompany and take care of the elderly. |
Phone number | The phone number of a person. |
Prefix | Prefix refers to the characters appearing before a slash in a command. Prefix describe the field that it represents. |
Region | The general portion of area in Singapore. |
Risk level | The susceptibility level of an elderly to injury or sickness. |
Tag | A generic description for a group of people. |
Volunteer | Volunteers that signed up to pair up with and accompany elderly members. |
VWO | Voluntary Welfare Organisations such as yourself. |
Technical
Term | Meaning |
---|---|
Java | Java is a programming language that FriendlyLink is written in. It is required to run the application. |
JAR | Java Archive (JAR) is a package file format typically used to aggregate many Java class files and associated metadata and resources (text, images, etc.) into one file for distribution. |
JSON | JavaScript Object Notation. A lightweight data format that is easy for both humans and computers to read and write. |
Terminal | The terminal is an interface that lets you access the command line. |