Developer Guide
Table of Contents
- Table of Contents
- Acknowledgements
- Setting up, getting started
- Design
- Implementation
- Documentation, logging, testing, configuration, dev-ops
- Appendix A: Requirements
-
Appendix B: Instructions for manual testing
- Launch and shutdown
- View sample Volunteer and Befriendee profiles and sample Logs
- Find a specific person based on name keywords, pairing status, or tags
- Adding a person
- Editing a person
- Deleting a person
- Pairing two persons
- Unpairing two persons
- Adding a log
- Editing a log
- Deleting a log
- Finding Logs associated with a person
- Undo previously executed commands
- Redo changes made by previous Undo command
- Clearing Elder Scrolls data
- Exiting Elder Scrolls
- Opening the Help Window
- Appendix C: Effort
- Appendix D: Planned Enhancements
Acknowledgements
- Elder Scrolls is based on the AddressBook-Level3 project created by the SE-EDU initiative.
- The design of the Elder Scrolls user interface takes cues from Google’s Material Design system.
Setting up, getting started
Refer to the guide Setting up and getting started.
Design
.puml
files used to create diagrams in this document docs/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
(consisting of classes Main
and MainApp
) is in charge of the app launch and shut down.
- At app launch, it initializes the other components in the correct sequence, and connects them up with each other.
- At shut down, it shuts down the other components and invokes cleanup methods where necessary.
The bulk of the app’s work is done by the following 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.
Commons
represents a collection of classes used by multiple other components.
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 r/volunteer
.
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
, LogListPanel
, 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
andLog
objects that reside in theModel
.
Logic component
API : Logic.java
Here’s a (partial) class diagram of the Logic
component:
The sequence diagram below illustrates the interactions within the Logic
component, taking execute("delete 1 r/volunteer")
API call as an example.
DeleteCommandParser
should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline continues till the end of diagram.
How the Logic
component works:
- When
Logic
is called upon to execute a command, it is passed to anAddressBookParser
object which in turn creates a parser that matches the command (e.g.,DeleteCommandParser
) and uses it to parse the command. - This results in a
Command
object (more precisely, an object of one of its subclasses e.g.,DeleteCommand
) which is executed by theLogicManager
. - The command can communicate with the
Model
when it is executed (e.g. to delete a person).
Note that although this is shown as a single step in the diagram above (for simplicity), in the code it can take several interactions (between the command object and theModel
) to achieve. - The result of the command execution is encapsulated as a
CommandResult
object which is returned back fromLogic
.
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 all in-memory application data (i.e.,
Datastore
andUserPref
objects) - stores a
UserPref
object that represents the user’s preferences. This is exposed to the outside as aReadOnlyUserPref
objects. - stores a
Datastore
object that represents the functional data in an application. This is exposed to the outside as aReadOnlyDatastore
object. - 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)
Datastore
Contains the PersonStore
:
- stores the currently ‘selected’
Person
objects (e.g., results of a search query) as a separate filtered list which is exposed to outsiders as an unmodifiableObservableList<Person>
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.
Contains the LogStore
:
- stores the currently ‘selected’
Log
objects (e.g., results of a search query) as a separate filtered list which is exposed to outsiders as an unmodifiableObservableList<Log>
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.
Tag
list in the AddressBook
, which Person
references. This allows AddressBook
to only require one Tag
object per unique tag, instead of each Person
needing their own Tag
objects.Storage component
API : Storage.java
The Storage
component,
- can save both application data and user preference data in JSON format, and read them back into corresponding objects.
- inherits from both
DatastoreStorage
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 scrolls.elder.commons
package.
Implementation
This section describes some noteworthy details on how certain features are implemented.
Add Person feature
Implementation
AddCommand
Class:
The AddCommand
class is responsible for adding a new Person
into the application and the AddCommandParser
class is responsible for parsing the user input to create a AddCommand
object.
The following sequence diagram shows how an add operation goes through the Logic
component:
Design considerations:
Aspect: Should the name attribute be case-sensitive?:
-
Alternative 1 (current choice): Name attribute is not case-sensitive.
- Pros: Prevents accidental capitalization or de-capitalization of names.
- Cons: In cases where two people have the same name with different capitalization, it is not accepted.
-
Alternative 2: Name attribute is case-sensitive.
- Pros: Two people who have the same name with different capitalization is allowed in the application.
- Cons: Accidental capitalization can cause duplicate entries in the application.
Edit Person feature
Implementation
EditCommand
Class:
The EditCommand
class is responsible for editing the attributes of an existing Person
in the application and the EditCommandParser
class is responsible for parsing the user input to create a EditCommand
object.
The following sequence diagram shows how an edit operation goes through the Logic
component:
Design considerations:
Aspect: How should the name in latest logs and log list be updated if name is edited:
-
Alternative 1 (current choice): Logs are updated during the execution of EditCommand.
- Pros: Edited name is reflected in the latest logs and log list immediately.
- Cons: Increases the complexity of implementation of the EditCommand.
-
Alternative 2: Logs are updated in a subsequent command
itself.
- Pros: Simplifies the implementation of the EditCommand and a separation of log and person commands.
- Cons: Real-time information in logs may not be updated.
Delete Person feature
Implementation
DeleteCommand
Class:
The DeleteCommand
class is responsible for removing an existing Person
from the application and the DeleteCommandParser
class is responsible for parsing the user input to create a DeleteCommand
object.
The following sequence diagram shows how a delete operation goes through the Logic
component:
Design considerations:
Aspect: Should users be allowed to delete a person with an existing pair and logs:
-
Alternative 1 (current choice): Only allow deletion of a person if they are not paired with anyone and have no logs.
- Pros: Prevents accidental deletion who is still a part of the volunteer programme.
- Cons: To delete a person with logs, the user must first delete logs associated with that person.
-
Alternative 2: Deletion of a person with an existing pair and logs is allowed.
itself.
- Pros: Simplifies the deletion process.
- Cons: Accidental deletion of a person who is still a part of the volunteer programme is possible.
Find feature
Implementation
FindCommandParser
Class:
The FindCommandParser
class is responsible for parsing user input and creating a corresponding FindCommand
object for execution. The implementation involves several key steps:
-
Role Parsing: The parser first identifies the roles specified in the user input, such as “volunteer” or “befriendee”, using predefined flags (
SEARCH_VOLUNTEER_FLAG
andSEARCH_BEFRIENDEE_FLAG
). It determines whether the search should be restricted to a specific role, both roles, or neither. - Pair Flag Parsing: Next, the parser extracts any flags indicating whether the search should include paired or unpaired individuals. It determines whether the search should include paired individuals, unpaired individuals, both, or neither.
-
Tag Parsing: The parser then parses any tags specified in the user input, which are prefixed with a tag indicator (
t/
). Tags are extracted and used to create aTagListContainsTagsPredicate
object for filtering. - Name Parsing: After extracting roles, pair flags, and tags, the parser processes the remaining input as potential name keywords for filtering.
-
Search Criteria Combination: The parser combines the parsed search criteria (roles, pair flags, tags, and name keywords) into a single
FindCommand
object. -
Handling Search Exceptions: The parser checks for any invalid command formats or missing input parameters and throws a
ParseException
if necessary. -
Return
FindCommand
Object: Finally, the parser returns the constructedFindCommand
object, encapsulating the parsed search criteria, for further execution.
FindCommand
Class:
The find command finds all persons whose names contain any of the given keywords, supports searches in separate Volunteer and Befriendee lists, search by tags, and by pairing status. The FindCommand
class is responsible for executing the find operation based on parsed user input.
-
Command Execution: The
execute()
method overrides the parent class Command method to perform the actual find operation. It retrieves the PersonStore from the model to access the list of persons. -
Search Criteria: The class contains boolean flags (
isSearchingVolunteer
,isSearchingBefriendee
) to determine whether to search volunteers, befriendees, or both. Similar flags (isSearchingPaired
,isSearchingUnpaired
) are used to filter persons based on their pairing status. -
Search Methods:*
searchAllPersons()
,searchVolunteerOnly()
, andsearchBefriendeeOnly()
methods are used to perform searches based on the specified criteria. These methods update the filtered person list in the PersonStore based on the search predicates. -
Result Handling: The search results are wrapped in a
CommandResult
object, which contains a message indicating the number of persons found. The message is formatted using the Messages class constants.
The following sequence diagram shows how a Find operation goes through the Logic
component:
Design Considerations
Aspect: Tag Parsing in FindCommandParser:
-
Alternative 1: (Current Choice): Parsing tags separately from other search criteria.
- Pros: Allows users to specify additional search criteria based on tags.
- Cons: Requires additional parsing logic and potentially increases complexity in handling multiple search parameters.
-
Alternative 2: Incorporating tags into the main search query without separate parsing.
- Pros: Simplifies parsing logic by integrating tags directly into the search query.
- Cons: May limit flexibility in specifying tag-based search criteria or require more sophisticated parsing algorithms.
Aspect: Handling Search Criteria in FindCommand:
-
Alternative 1 (Current Choice): Implementing separate predicates for name and tag search criteria.
- Pros: Offers flexibility in defining and combining different search parameters.
- Cons: May lead to redundant filtering or increased complexity in managing multiple predicates.
-
Alternative 2: Consolidating search criteria into a single unified predicate.
- Pros: Simplifies filtering logic by reducing the number of separate predicates.
- Cons: May limit the flexibility to apply different search parameters independently or require more complex predicate structures.
Pair/Unpair feature
Implementation
PairCommand
& UnpairCommand
Class:
The PairCommand
class is responsible for pairing two persons, and the UnpairCommand
class is responsible for unpairing two persons. The PairCommand
and UnpairCommand
classes are executed by the Logic
component.
The pair and unpair commands are facilitated by updating the pairedWithName
and pairedWithId
fields of the Person
object. Two paired Person
s will have their pairedWithName
and pairedWithId
fields updated to reflect the name
and personId
of the Person
they are paired with, or removed when they are unpaired
The name
is saved to facilitate easy identification of the paired Person
when displaying the Person
object. The personId
is saved to facilitate easy retrieval of the paired Person
object when needed.
The following sequence diagram shows how a pair operation goes through the Logic
component:
For the unpair operation, the sequence diagram is similar to the pair operation, with the UnpairCommand
class executing the unpair operation.
Design considerations:
Aspect: What attribute(s) should be saved in the Person
object:
-
Alternative 1 (current choice): Save the
name
andpersonId
of the pairedPerson
.- Pros: Might need extra steps to search for the paired
Person
as only thename
andpersonId
are saved. - Cons: Uses less memory.
- Pros: Might need extra steps to search for the paired
-
Alternative 2: Save the paired
Person
within thePerson
object. itself.- Pros: Easy to access and manipulate the paired
Person
. - Cons: Uses more memory and includes redundant information.
- Pros: Easy to access and manipulate the paired
Add Log feature
Implementation
The Add Log feature allows users to add a new log entry to the application.
The LogEditCommand
class is responsible for creating a new log entry, and the LogAddCommandParser
class is responsible for parsing the user input to create a LogAddCommand
object.
The following sequence diagram shows how a LogAdd operation goes through the Logic
component:
Design Considerations
Aspect: Whether to use unique logId
for each Log
object:
-
Alternative 1 (current choice): The
logId
is automatically generated for eachLog
object, ensuring that each log entry has a unique identifier.- Pros: Ensures that each log entry is uniquely identified.
- Cons: Adds complexity to the implementation of the
LogStore
(e.g., maintaining alogIdSequence
to generate uniquelogId
values)
-
Alternative 2: The
logId
is not used, and theLog
object is identified by its position in the list of logs.- Pros: Simplifies the process of adding a log entry.
- Cons: May lead to confusion if log entries are deleted or reordered.
Here’s an example of how you can use the Add Log feature:
-
To add a log entry, use the
addlog
command followed by thevolunteerId
,befriendeeId
,startdate
,duration
andremarks
. For example,addlog v/1 b/2 s/2022-03-01-10:00 d/2 r/Visited Mr. Tan
. -
The application will create a new log entry with the provided details and add it to the list of logs.
-
If the command is successful, the application will display a message indicating that the log entry has been added.
Please note that the volunteerId
and befriendeeId
must correspond to existing volunteers and befriendees in the application. The startdate
should be in the format YYYY-MM-DD
and the duration
should be the number of hours the visit lasted. The remarks
field is optional and can be used to add any additional notes about the visit.
Edit log feature
Implementation
The edit log feature allows user to modify the details of an existing log entry in the address book. The index of the log entry has to be edited is specified by the user in order to execute the LogEditCommand
.
The LogEditCommand
class is responsible for editing the details of a log entry,
and the LogEditCommandParser
class is responsible for parsing the user input to create a LogEditCommand
object.
The following sequence diagram shows how a LogEdit operation goes through the Logic
component:
Design Considerations
Aspect: What attribute(s) can be edited in the Log
object:
-
Alternative 1 (current choice): The
volunteerId
,befriendeeId
,startdate
,duration
andremarks
of theLog
can be edited.- Pros: Provides flexibility for users to update various attributes of a log entry.
- Cons: Accidental edits when editing contact ids in
Log
may lead to cascading effects in other attributes displayed, such as timeServed in volunteer contacts.
-
Alternative 2: The
startdate
,duration
andremarks
of theLog
can be edited, while thevolunteerId
,befriendeeId
is kept immutable.- Pros: Prevents cascading modifications of attributes displayed in
Person
contact. - Cons: Restricts the flexibility of the
LogEdit
feature
- Pros: Prevents cascading modifications of attributes displayed in
Delete Log feature
Implementation
The Delete Log feature allows users to remove an existing log entry from the application.
The LogDeleteCommand
class is responsible for deleting an existing log entry, and the LogDeleteCommandParser
class is responsible for parsing the user input to create a LogDeleteCommand
object.
The following sequence diagram shows how a LogDelete operation goes through the Logic
component:
Design Considerations
Aspect: How to update the latestLogId
attribute of Persons when log is deleted:
-
Alternative 1 (current choice): A helper function that finds the
latestLogId
attribute of thePerson
objects when a log is deleted, in order to update the latest log if necessary.- Pros: Ensures that
latestLogId
is accurately updated and displayed when logs are deleted. - Cons: Two new
Person
objects are created whenever a log is deleted
- Pros: Ensures that
-
Alternative 2: Leave the updating of the latest log to the
Model
component- Pros: Simplifies the process of deleting a log entry.
- Cons: Another component of the application must be responsible for updating the
latestLogId
attribute of thePerson
objects.
Find Log feature
Implementation
The Find Log feature allows users to find a particular log entry that is displayed in the log list in the application.
The LogFindCommand
class is responsible for finding an existing log entry, and the LogFindCommandParser
class is responsible for parsing the user input to create a LogFindCommand
object.
The following sequence diagram shows how a LogFind operation goes through the Logic
component:
Design Considerations
Aspect: How to specify what logs to find:
-
Alternative 1 (current choice): Logs of a specified person are displayed in the log list.
- Pros: Allows for the display of a particular person’s logs
- Cons: Cannot search for a particular log
-
Alternative 2: Search via the attributes of a log entry.
- Pros: Allows for searching of logs with a particular attribute
- Cons: Does not allow for the display of a particular person’s logs
Undo/Redo feature
Implementation
The undo/redo mechanism is facilitated by DatastoreVersionStorage
. It is a data structure storing the undo/redo history of the datastores stored in the model, stored internally as an datastoreVersions
and currentStatePointer
. Additionally, it implements the following operations:
-
DatastoreVersionStorage#commitDatastore()
— Saves the current datastore state in its history. -
DatastoreVersionStorage#executeUndo()
— Returns the previous address book state from its history, for the model to reset the datastore -
DatastoreVersionStorage#executeRedo()
— Returns a previously undone address book state from its history, for the model to reset the datastore
DatastoreVersionStorage#commitDatastore()
is exposed in the Model
interface as Model#commitDatastore()
while Model#undoChanges()
and Model#redoChanges()
call DatastoreVersionStorage#executeUndo()
and DatastoreVersionStorage#executeRedo()
respectively to carry out the undo and redo actions.
Given below is an example usage scenario and how the undo/redo mechanism behaves at each step.
Step 1. The user launches the application for the first time. The DatastoreVersionStorage
will be initialized with the initial datastore state, and the currentStatePointer
pointing to that single datastore state.
Step 2. The user executes delete 5 r/volunteer
command to delete the 5th volunteer in the datastore. The delete
command calls Model#commitDatastore()
, causing the modified state of the datastore after the delete 5 r/volunteer
command executes to be saved in the datastoreVersions
, and the currentStatePointer
is shifted to the newly inserted datastore state.
Step 3. The user executes add n/David …
to add a new person. The add
command also calls Model#commitDatastore()
, causing another modified datastore state to be saved into the datastoreVersions
.
Model#commitDatastore()
, so the datastore state will not be saved into the datastoreVersions
.
Step 4. The user now decides that adding the person was a mistake, and decides to undo that action by executing the undo
command.
The undo
command will call Model#undoChanges()
, which will shift the currentStatePointer
once to the left, pointing it to the previous datastore state, and restores the datastore to that state.
currentStatePointer
is at index 0, pointing to the initial Datastore state, then there are no previous Datastore states to restore. The undo
command uses Model#canUndoDatastore()
to check if this is the case. If so, it will return an error to the user rather
than attempting to perform the undo.
The following sequence diagram shows how an undo operation goes through the Logic
component:
UndoCommand
should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram.
Similarly, how an undo operation goes through the Model
component is shown below:
The redo
command does the opposite — it calls Model#redoChanges()
, which shifts the currentStatePointer
once to the right, pointing to the previously undone state, and restores the datastore to that state.
currentStatePointer
is at index datastoreVersions.size() - 1
, pointing to the latest datastore state, then there are no undone Datastore states to restore. The redo
command uses Model#canRedoDatastore()
to check if this is the case. If so, it will return an error to the user rather than attempting to perform the redo.
Step 5. The user then decides to execute the command list
. Commands that do not modify the datastore, such as list
, will usually not call Model#commitDatastore()
, Model#undoChanges()
or Model#redoChanges()
. Thus, the datastoreVersions
remains unchanged.
Step 6. The user executes clear
, which calls Model#commitDatastore()
. Since the currentStatePointer
is not pointing at the end of the datastoreVersions
, all address book states after the currentStatePointer
will be purged. Reason: It no longer makes sense to redo the add n/David …
command. This is the behavior that most modern desktop applications follow.
The following activity diagram summarizes what happens when a user executes a new command:
Design considerations:
Aspect: How undo & redo executes:
-
Alternative 1 (current choice): Saves the entire address book.
- Pros: Easy to implement.
- Cons: May have performance issues in terms of memory usage.
-
Alternative 2: Individual command knows how to undo/redo by
itself.
- Pros: Will use less memory (e.g. for
delete
, just save the person being deleted). - Cons: We must ensure that the implementation of each individual command are correct.
- Pros: Will use less memory (e.g. for
Documentation, logging, testing, configuration, dev-ops
Appendix A: Requirements
Product scope
Target user profile:
- is a manager of a befriending volunteer organisation
- has a need to keep track of many befriendees/elderly of the volunteer programme
- has a need to keep track of volunteers in the organisation
- has a need to keep track of logs of activities/visits made by volunteers to befriendees
- prefer desktop apps over other types
- can type fast
- prefers typing to mouse interactions
- is reasonably comfortable using CLI apps
Value proposition: manage the volunteer organisation faster than a typical mouse/GUI driven app. Our application aims to provide fast access to all contacts with intuitive search and filtering, enable pairing of volunteers to elderly befriendees, show multiple lists to enable multitasking and support efficient adding of logs between pairs of volunteers and befriendees.
User stories
Priorities: High (must have) - * * *
, Medium (nice to have) - * *
, Low (unlikely to have) - *
Priority | As a … | I want to … | So that I can… |
---|---|---|---|
* * * |
manager | add volunteers’ and elderly befriendees’ contacts | |
* * * |
manager | edit volunteers’ and elderly befriendees’ details | |
* * * |
manager | delete volunteer and elderly befriendee contacts | |
* * * |
manager | view list of volunteers and elderly befriendees | keep track of the roster |
* * * |
manager | tag elderly befriendees with relevant details | accommodate for any special circumstances |
* * * |
manager | pair and unpair volunteers with befriendee contacts | assign the pairings |
* * * |
manager | add log entries for each visit made by a volunteer to an elderly befriendee | keep track of the visits |
* * * |
manager | search for specific elderly befriendee or volunter befriender | find and view the details of befriendee or volunteer |
* * * |
manager | search log entries based on a befriendee or volunteer | find and view the details of relevant log entries |
* * |
manager | have a one-stop view of all important information regarding elderly and volunteers | contact each person easily |
* * |
manager | undo and redo changes made to the contacts, pairings, and logs | revert changes made in error |
* * |
first-time user | access a help page | refer to the features that come along with the application |
* * |
first-time user | see sample befriendee and volunteer profiles | try out the features with pre-loaded data |
* |
first-time user | follow a guided tour | be aware of how to use and access features in the application |
Use cases
(For all use cases below, the System is the Elder Scrolls
and the Actor is the
volunteer organisation manager
, unless specified otherwise)
Use case: UC01 - Add a contact
MSS
- User requests to add contact, entering contact information
- Elder Scrolls adds the contact
-
Elder Scrolls displays the details of the contact added
Use case ends.
Extensions
-
2a. The given contact details are invalid.
-
2a1. Elder Scrolls shows an error message.
Use case ends.
-
-
3a. The given contact details are already in the contact book
- 3a1. Elder scrolls shows an error message.
Use case ends.
Use case: UC02 - Delete a contact
MSS
- User requests to list all contacts
- Elder Scrolls shows a list of all contacts
- User requests to delete a specific contact.
-
Elder Scrolls deletes the specified contact.
Use case ends.
Extensions
-
3a. The specific contact given by the user is invalid.
-
3a1. Elder Scrolls shows an error message.
Use case resumes at step 2.
-
-
4a. The contact requested to be deleted is still paired.
-
4a1. Elder Scrolls shows an error message.
Use case resumes at step 2.
-
Use case: UC03 - List all contacts and logs
MSS
- User requests to list all contacts and logs
-
Elder Scrolls shows a list of all contacts and logs
Use case ends.
Use case: UC04 - Pair a volunteer and befriendee
MSS
- User requests to list all contacts and logs (UC03).
- Elder Scrolls shows a list of contacts and logs.
- User requests to pair a specific volunteer and befriendee in the list.
-
Elder Scrolls pairs the specified volunteer and befriendee.
Use case ends.
Extensions
-
3a. One or both of the specified persons are invalid.
-
3a1. Elder Scrolls shows an error message indicating that the specified person(s) given are invalid.
Use case resumes at step 2.
-
-
3b. One or both of the specified persons are already paired.
-
3b1. Elder Scrolls shows an error message indicating that the specified person(s) are already paired.
Use case resumes at step 2.
-
Use case: UC05 - Edit field for a specific contact
MSS
- User requests to list all contacts and logs (UC03).
- Elder Scrolls shows a list of contacts and logs.
- User requests to edit a field for a specific contact, with a new specified value.
-
Elder Scrolls edits the field for the specified person in the list with the new specified value.
Use case ends.
Extensions
- 3a. The specific contact given by the user is invalid.
- 3a1. Elder Scrolls shows an error message. Use case resumes at step 2.
- 3b. The field that the user wants to edit is not specified
- 3b1. Elder Scrolls shows an error message to prompt the user to specify a field to edit. Use case resumes at step 2.
- 3c. The new specified value is not provided by the user
- 3c1. Elder Scrolls shows an error message to prompt the user to specify a new value for the field the user wishes to edit. Use case resumes at step 2.
Use case: UC06 - Add a log entry for volunteer-befriendee pairs
MSS
- User requests to list all contacts and logs (UC03).
- Elder Scrolls shows a list of contacts and logs.
- User requests to add a log entry for two paired individuals, and enters details of the activity log, including date, time, and remarks.
-
Elder Scrolls records the log entry for the selected pair.
Use case ends.
Extensions
- 3a. The selected pair is not currently paired.
- 3a1. Elder Scrolls displays an error message indicating that the selected pair is not currently paired. Use case resumes at step 2.
- 3b. The entered details for the log are incomplete or invalid.
- 3b1. Elder Scrolls shows an error message to prompt user to correct the incomplete or invalid details. Use case resumes at step 2.
Use case: UC07 - Find a person based on name keyword
MSS
- User requests to find a person based on a name keyword.
-
Elder Scrolls displays a list of contacts matching the name keyword.
Use case ends.
Extensions
- 1a. User wants to find person specifically amongst the volunteer.
- 1a1. User specifies the role as volunteer.
- 1a2. Elder Scrolls displays a list of volunteers matching the name keyword. Use case ends.
- 1b. User wants to find persons that are paired.
- 1b1. User specifies the pairing status as paired.
- 1b2. Elder Scrolls displays a list of paired persons matching the name keyword. Use case ends.
- 1c. User wants to find persons that are tagged with a specific tag.
- 1c1. User specifies the tag as a property.
- 1c2. Elder Scrolls displays a list of persons tagged with the specified tag. Use case ends.
Use case: UC08 - Find associated logs to a specific person
MSS
- User requests to find logs associated with a specific person.
-
Elder Scrolls displays a list of logs associated with the specific person.
Use case ends.
Use case: UC09 - Edit field for a specific log
MSS
- User requests to list all contacts and logs (UC03).
- Elder Scrolls shows a list of contacts and logs.
- User requests to edit a field in a specific log, with a new specified value.
-
Elder Scrolls edits that field for that specific log in the list with the new specified value.
Use case ends.
Extensions
- 3a. The given specific log is invalid.
- 3a1. Elder Scrolls shows an error message. Use case resumes at step 2.
- 3b. The field that the user wants to edit is not specified
- 3b1. Elder Scrolls shows an error message to prompt the user to specify a field to edit. Use case resumes at step 2.
Use case: UC10 - Undo a command
MSS
- User requests to execute a command.
- Elder Scrolls executes the command.
- User requests to undo the command.
-
Elder Scrolls undoes the command.
Use case ends
Extensions
- 3a. The command that was previously executed does not mutate data in the application
- 1a1. Elder Scrolls shows an error message to tell the user there is no previous operation to be undone. Use case resumes at step 2.
Use case: UC11 - Redo a command
MSS
- User requests to undo a command (UC10).
- Elder Scrolls undoes the command.
- User requests to revert the effects of the undo command.
-
Elder Scrolls reverts the effect of the undo command.
Use case ends.
Non-Functional Requirements
- Should work on any mainstream OS as long as it has Java
11
or above installed. - Should be able to hold up to 1000 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 have a simple menu structure with clear labels, guiding users to key actions without extensive tutorials.
- Should have graceful error handling with clear human-readable messages to the user to guide them in fixing their command.
- Should have a robust data storage mechanism that can handle data corruption and large data sets.
Glossary
- Volunteer: An individual who offers their time and services to social service agencies or causes without financial compensation, in this context they carry out befriending activities with the beneficiaries.
- Befriendee: An individual who receives support, companionship, or assistance from volunteers, in this context they are the beneficiaries of the befriending activities.
- Elder Scrolls: The Volunteer Management System (VMS) developed by our team for efficient management and bookkeeping of volunteers, befriendees, and their interactions.
- Tagging: Adding an arbitrary detail(s) to a volunteer or befriendee profile to aid in identifying special conditions
- Index: The position or number assigned to each item in a list, used for reference when performing actions such as editing or deleting entries in Elder Scrolls.
- Pairing: The process of associating a volunteer with a befriendee in Elder Scrolls, allowing them to work together on activities or support services.
- Logs: Records of interactions, activities, or events between volunteers and befriendees in Elder Scrolls, used for tracking service hours, progress, and communication.
- Command Line Interface (CLI): A text-based interface used for interacting with Elder Scrolls through commands typed into a terminal or command prompt.
- Graphical User Interface (GUI): A visual interface used for interacting with Elder Scrolls, providing intuitive controls and displays for managing volunteers, befriendees and logs.
Appendix B: 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
- Launch Elder Scrolls: Open a command terminal,
cd
into the folder you put the jar file in, and use thejava -jar elderscrolls.jar
command to run the application. Expected: Shows the GUI with a set of sample contacts and logs. 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.
View sample Volunteer and Befriendee profiles and sample Logs
- Close Elder Scrolls.
- Delete the file
./data/datastore.json
if it exists. - Launch Elder Scrolls. Expected: Lists of sample volunteers, befriendees and logs are shown.
Find a specific person based on name keywords, pairing status, or tags
- Find a volunteer by name keywords
- Prerequisites: Starting with sample data. Refer to the previous test case to load sample data. Use
list
to reset the view before each testcase. - Test case:
find
Expected: No change in list. Error displayed show an invalid command format, where at least one of the optional parameters must be entered. - Test case:
find David
Expected: Shows the list of volunteers and befriendees with the name “David”. - Test case:
find david alex
Expected: Shows the list of volunteers and befriendees with either the name “David” or “Alex”.
- Prerequisites: Starting with sample data. Refer to the previous test case to load sample data. Use
- Find a person by pairing status
- Prerequisites: Starting with sample data. Refer to the previous test case to load sample data. Use
list
to reset the view before each testcase. - Test case:
find --paired
Expected: Shows a list of all paired volunteers and befriendees. The list may contain multiple paired persons. - Test case:
find --unpaired
Expected: Shows a list of all unpaired volunteers and befriendees. The list may contain multiple unpaired persons.
- Prerequisites: Starting with sample data. Refer to the previous test case to load sample data. Use
- Find a person by tags
- Prerequisites: Starting with sample data. Refer to the previous test case to load sample data. Use
list
to reset the view before each testcase. - Test case:
find t/student
Expected: Shows a list of all volunteers and befriendees with the tag “student”.
- Prerequisites: Starting with sample data. Refer to the previous test case to load sample data. Use
- Restrict find operation to volunteers or befriendees
- Prerequisites: Starting with sample data. Refer to the previous test case to load sample data. Use
list
to reset the view before each testcase. - Test case:
find r/volunteer --paired
Expected: Shows list of all volunteers that are paired. Befriendee list is untouched. - Test case:
find r/befriendee t/handicapped
Expected: Shows list of all befriendees that have taghandicapped
. Volunteer list is untouched.
- Prerequisites: Starting with sample data. Refer to the previous test case to load sample data. Use
Adding a person
-
Adding a person while all befriendees and volunteers are being shown
-
Prerequisites: List all persons using the
list
command. Multiple persons in both the befriendees and volunteers list. -
Test case:
add n/Michelle r/volunteer p/98909221 e/mich@gmail.com a/Wow street, blk 123, t/smart
Expected: Contact with the above details is added to the volunteer list. Details of the added contact shown in the status message. -
Test case:
add n/Giggs p/88221143 e/gig@hotmail.com a/Hello street, block 4, #04-01
Expected: No person is added. Error details indicating “Invalid command format!” shown in the status message. Status bar remains the same. -
Other incorrect add commands to try:
add
,add n/
Expected: Similar to previous.
-
-
Adding a person where the name already exists in the volunteer list
-
Prerequisites: List all persons using the
list
command. There exists a volunteer contact where the name is “Michelle”. -
Test case:
add n/Michelle r/volunteer p/98909221 e/mich@gmail.com a/Wow street, blk 123, t/smart
Expected: No person is added. Error details shown in the status message. Status bar remains the same.
-
Editing a person
-
Editing a person while all befriendees and volunteers are being shown
-
Prerequisites: List all persons using the
list
command. The person indicated to be edited should exist in the volunteer or befriendee list. -
Test case:
edit 1 r/befriendee p/91225454 e/zhuoran@example.com
Expected: Details of the first befriendee on the befriendee list are edited. Updated details of the edited contact shown in the status message. -
Test case:
edit 1 n/Josh
Expected: No contact is edited. Error details indicating “Role must be specified…” shown in the status message. Status bar remains the same. -
Test case:
edit 0
Expected: No contact is edited. Error details indicating “Invalid command format!” shown in the status message. Status bar remains the same. -
Other incorrect edit command to try:
edit x r/volunteer n/James
(where x is larger than the volunteer list size)
Expected: No contact is edited. Error details indicating “The person index provided is invalid” shown in the status message. Status bar remains the same.
-
Deleting a person
-
Deleting a person while all befriendees and volunteers are being shown
-
Prerequisites: List all persons using the
list
command. Multiple persons in both the befriendees and volunteers list. The index indicated exists, the contact at that index is not paired with anyone and does not have any logs. -
Test case:
delete 3 r/volunteer
Expected: Third contact is deleted from the volunteer list. Details of the deleted contact shown in the status message. -
Test case:
delete 1
Expected: No person is deleted. Error details indicating “Role must be specified…” shown in the status message. Status bar remains the same. -
Test case:
delete 0 r/volunteer
Expected: No person is deleted. Error details indicating “Index is not a non-zero” shown in the status message. Status bar remains the same.
-
-
Deleting a person where the contact is paired
-
Prerequisites: List all persons using the
list
command. Multiple persons in both the befriendees and volunteers list. The befriendee at index 1 of the befriendee list is paired with the volunteer at index 1 of the volunteer list. -
Test case:
delete 1 r/volunteer
Expected: No person is deleted. Error details indicating “Unable to delete contact: Contact is paired…” shown in the status message. Status bar remains the same.
-
-
Deleting a person where the contact has a log
-
Prerequisites: List all persons using the
list
command. Multiple persons in both the befriendees and volunteers list. The befriendee at index 2 of the befriendee list exists, is not paired but has a log in the log list. -
Test case:
delete 2 r/befriendee
Expected: No person is deleted. Error details indicating “Unable to delete contact: Contact has a log in Elder Scrolls…” shown in the status message. Status bar remains the same.
-
Pairing two persons
-
Pairing two persons while all befriendees and volunteers are being shown
-
Prerequisites: List all persons using the
list
command. Multiple persons in both the befriendees and volunteers list. The contacts at the indicated indices exist and are not paired. -
Test case:
pair 1 1
Expected: The befriendee at index 1 of the befriendee list and the volunteer at index 1 of the volunteer list are paired. Details of the two persons shown in the status message. -
Test case:
pair
Expected: No person is paired. Error details indicating “Invalid command format!” shown in the status message. Status bar remains the same. -
Other incorrect pair command to try:
pair 1 x
(where x is larger than the volunteer list size)
Expected: No person is paired. Error details indicating “The person index provided is invalid” shown in the status message. Status bar remains the same.
-
-
Pairing two persons where one or both of the persons are already paired
-
Prerequisites: List all persons using the
list
command. Multiple persons in both the befriendees and volunteers list. The contacts at the indicated indices exist and one or both are already paired. -
Test case:
pair 1 2
Expected: No person is paired. Error details indicating “One or both of the persons are already paired…” shown in the status message. Status bar remains the same.
-
Unpairing two persons
-
Unpairing two persons while all befriendees and volunteers are being shown
-
Prerequisites: List all persons using the
list
command. Multiple persons in both the befriendees and volunteers list. The contacts at the indicated indices exist and are paired with each other. -
Test case:
unpair 1 1
Expected: The befriendee at index 1 of the befriendee list and the volunteer at index 1 of the volunteer list are unpaired. Details of the two persons shown in the status message. -
Test case:
unpair 3
Expected: No person is unpaired. Error details indicating “Invalid command format!” shown in the status message. Status bar remains the same. -
Other incorrect unpair command to try:
unpair 1 x
(where x is larger than the volunteer list size)
Expected: No person is unpaired. Error details indicating “The person index provided is invalid” shown in the status message. Status bar remains the same.
-
-
Unpairing two persons where the persons are not paired with each other
-
Prerequisites: List all persons using the
list
command. Multiple persons in both the befriendees and volunteers list. The contacts at the indicated indices exist and are not paired with each other. -
Test case:
unpair 2 3
Expected: No person is unpaired. Error details indicating “The two persons are not paired…” shown in the status message. Status bar remains the same.
-
Adding a log
-
Adding a log while all befriendees and volunteers are being shown
-
Prerequisites: List all persons using the
list
command. Multiple persons in both the befriendees and volunteers list. The first index refers to the befriendee and the second index refers to the volunteer. The contacts at the indicated indices exist and are paired with each other. -
Test case:
logadd 1 1 t/Icebreaker session s/2022-03-05 d/2 r/got to know more about befriendee
Expected: A log is added for the paired befriendee at index 1 of the befriendee list and the volunteer at index 1 of the volunteer list. -
Test case:
logadd 1 1 t/Icebreaker session d/2
Expected: No log is added. Error details indicating “Invalid command format!” shown in the status message. Status bar remains the same. -
Other incorrect logadd command to try:
logadd 1 x t/Icebreaker session s/2022-03-05 d/2 r/got to know more about befriendee
(where x is larger than the volunteer list size)
Expected: No log is added. Error details indicating “The person index provided is invalid.” shown in the status message. Status bar remains the same.
-
Editing a log
-
Editing a log while all logs are being shown
-
Prerequisites: List all logs using the
list
command. Multiple logs in logs list. The log at the indicated index should exist in the logs list. -
Test case:
logedit 1 t/Cinema visit
Expected: The log at index 1 of the log list is edited. Updated details of the edited log shown in the status message. -
Test case:
logedit 1
Expected: No log is edited. Error details indicating “At least one field to edit must be provided.” shown in the status message. Status bar remains the same. -
Other incorrect logedit command to try:
logedit x t/Cinema visit
(where x is larger than the log list size)
Expected: No log is edited. Error details indicating “The log index provided is invalid.” shown in the status message. Status bar remains the same.
-
Deleting a log
-
Deleting a log while all logs are being shown
-
Prerequisites: List all logs using the
list
command. Multiple logs in logs list. The log at the indicated index should exist in the logs list. -
Test case:
logdelete 3
Expected: The log at index 3 of the log list is deleted. Details of the deleted log shown in the status message. -
Test case:
logdelete
Expected: No log is deleted. Error details indicating “Invalid command format!” shown in the status message. Status bar remains the same. -
Other incorrect logdelete command to try:
logdelete x
(where x is larger than the log list size)
Expected: No log is deleted. Error details indicating “Unable to delete log: The log index provided is invalid.” shown in the status message. Status bar remains the same.
-
Finding Logs associated with a person
- Find Logs for a person while all volunteers and befriendees are shown
- Prerequisites: Starting with sample data. Refer to the previous test case to load sample data. Use
list
to reset the view before each testcase. The contact at the indicated index should exist in the volunteer or befriendee list. - Test case:
findlog
Expected: No change in list. Error displayed show an invalid command format, where at least one of the optional parameters must be entered. - Test case:
findlog 1 r/volunteer
Expected: Shows the list of logs associated with the volunteer at the index 1. - Test case:
findlog 2 r/befriendee
Expected: Shows the list of logs associated with the befriendee at the index 2.
- Prerequisites: Starting with sample data. Refer to the previous test case to load sample data. Use
Undo previously executed commands
- Undo a command that mutates the data in Elder Scrolls (
add
,edit
,delete
,pair
,unpair
,logadd
,logedit
,logdelete
,clear
)-
Prerequisites: Starting with sample data. Refer to the previous test case to load sample data. Use
list
to reset the view before each testcase. -
Test case:
delete 3 r/volunteer
followed byundo
Expected: After the first command, the third contact in the volunteer list is deleted.
Subsequently after the second command is executed, the deletion of the third contact in the volunteer list is undone. The status bar displays that the previous operation has been undone. -
Test case:
edit 1 r/volunteer n/alex
followed byundo
Expected: After the first command is executed, the first person in the volunteer list has their name edited to “alex”, the logs previously associated with “Alex Yeoh” now display “alex” as the volunteer associated with them.
Subsequently, after the second command is executed, the edit made on the name of the first volunteer in the volunteer list is undone, and their name is back to being “Alex Yeoh”. The status bar displays that the previous operation has been undone.
-
Prerequisites: Starting with sample data. Refer to the previous test case to load sample data. Use
- Executing an undo command when the application is newly launched
- Prerequisites: Exit the application and launch it again, making sure to not execute any commands before the testcase.
-
Test case:
undo
Expected: No operation is undone. Error details indicating “No previous operation to be undone” shown in the status message. Status bar remains the same.
- Executing an undo command after an operation that does not modify data in Elder scrolls is executed
- Prerequisites: Exit the application and launch it again, making sure to not execute any commands before the testcase. Start with sample data. Refer to the previous test cases on how to load sample data.
-
Test case:
list
followed byundo
Expected: All persons should be listed after the first command, with a success message displayed in the status message.
Subsequently, after executing the second command, no operation is undone, the user’s view of the volunteer, befriendee and log lists remains the same. Error details indicating “No previous operation to be undone” shown in the status message. Status bar remains the same. -
Test case:
find --paired
followed byundo
Expected: After the first command, lists of all paired befriendees and volunteers should be shown.
Subsequently, after executing the second command, no operation is undone, the user’s view of the volunteer, befriendee and log lists remains the same. Error details indicating “No previous operation to be undone” shown in the status message. Status bar remains the same. -
Test case:
findlog 1 r/volunteer
followed byundo
Expected: After the first command, the list of logs associated with the volunteer at index 1 should be shown.
Subsequently, after executing the second command, no operation is undone, the user’s view of the volunteer, befriendee and log lists remains the same. Error details indicating “No previous operation to be undone” shown in the status message. Status bar remains the same.
Redo changes made by previous Undo command
- Redo a command that has been undone
-
Prerequisites: Start with the sample data. Refer to the previous test case to load sample data. Use
list
to reset the view before each testcase. -
Test case:
delete 3 r/volunteer
followed byundo
followed byredo
Expected: After the first command, the third volunteer in the volunteer list is deleted. After the second command, the deletion of the third volunteer is undone.
Subsequently, after theredo
command is executed, the third volunteer in the volunteer is once again deleted, reverting the effects of the undo command that was executed. The status bar displays that the previous undo operation has been reversed. -
Test case:
edit 1 r/volunteer n/alex
followed byundo
followed byredo
Expected: After the first command, the first volunteer in the volunteer list will have their name edited to “alex” from “Alex Yeoh”. After the second command, the edit made on the first volunteer’s name will be undone, and their name will be reverted back to “Alex Yeoh”.
Subsequently, after theredo
command is executed, the first volunteer in the volunteer list will once again have their name edited to “alex”, reverting the effects of the undo command that was executed. The status bar displays that the previous undo operation has been reversed.
-
Prerequisites: Start with the sample data. Refer to the previous test case to load sample data. Use
- Executing a redo command when the application is newly launched
- Prerequisites: Exit the application and launch it again, making sure to not execute any commands before the testcase.
-
Test case:
redo
Expected: No undo operation is reversed. Error details indicating “No previous undo operation to be reversed” shown in the status message. Status bar remains the same.
- Executing a redo command after executing an undo command followed by a command mutating the data in Elder Scrolls.
-
Prerequisites: Start with the sample data. Refer to the previous test cases to load sample data. Execute
delete 3 r/volunteer
followed byundo
as done in the test case for theundo
command -
Test case:
edit 1 r/volunteer n/alex
followed byredo
Expected: After the first command, the first volunteer in the volunteer list will have their name edited to “alex” from “Alex Yeoh”.
Subsequently, when theredo
command is executed, theundo
operation of thedelete 3 r/volunteer
command will not be reversed. Error details indicating “No previous undo operation to be reversed” shown in the status message. Status bar remains the same.
-
Prerequisites: Start with the sample data. Refer to the previous test cases to load sample data. Execute
Clearing Elder Scrolls data
- Clearing all data
- Prerequisites: At least one volunteer or one befriendee is present in the lists.
-
Test case:
clear
Expected: The lists of befriendees, volunteers and logs are cleared. The lists are empty.
Exiting Elder Scrolls
- Exiting the application
-
Test case:
exit
Expected: The application window closes.
-
Test case:
Opening the Help Window
- Accessing the help window
-
Test case:
help
Expected: The help window opens.
-
Test case:
Appendix C: Effort
Difficulty Estimation
Overall, the team believes that the features we have chosen to undertake are fairly complex, as they involve fundamental changes to the application state, as is the case with undo
and redo
. Additionally, the addition of log
features and separation of person types meant that the existing relationships between entities inherited from AB3 had to be restructured significantly.
The team also made significant changes to the UI, in an attempt to modernise the look and feel of the application. With meticulous reference to modern design systems, the team made significant changes to the styling of the application. These changes were challenging as they required a good understanding of JavaFX and the ability to work within the confines of the existing codebase.
Challenges Faced
- Global ID vs Indexed ID: We initially decided on using a global ID for each person, but later realised upon further exploration of the codebase that refactoring all instances of list indexing would be an outsized task. Thus, the team compromised by using global IDs for identifications, but still using list indices for client-facing commands.
-
Adding Logs: The team faced challenges in adding logs to the application, as it required a significant restructuring of the existing codebase. Given that logs were an entirely new set of entities to be stored in the application, where AB3 had only a single entity, we quickly realised that the existing structure of the
model
was not sufficient to handle the new requirements. This led to a significant amount of refactoring and restructuring of theModel
andStorage
classes. -
Relationships between entities: Given that the new features included two different classes of
Person
as well as aLog
class associated with both, the team spent a significant amount of time planning and testing the correctness of the relations between these entities. Through defensive programming and good test coverage, we were able to ensure that all user operations modifying these relationships were correctly reflected in the application state.
Effort Required
Overall, over the thousands of lines of code changed, the team estimates that a few dozen man-hours were spent on the project. The team met regularly to discuss the project, and each member contributed significantly to the project through an even distribution of work over the main areas: adding commands, restructuring logic and backend, UI. The team also spent a significant amount of time on testing, as the new features added to the application were complex and required a significant amount of additional test code to ensure that they worked as expected.
As a result, we were able to deliver on planned features while increasing our code coverage over the inherited project.
Achievements
A robust and extensible application was delivered, with a significant amount of new features added to the application. The team was able to deliver on planned features, and the performance of new features, such as log
operations, were significantly improved over old features of the inherited project.
Appendix D: Planned Enhancements
Our current version of Elder Scrolls enables users to efficiently manage volunteers, befriendees, and their interactions. However, we have identified planned enhancements that will further improve the user experience and functionality of the application.
- Team size: 5. (Max 10 planned enhancements)
-
Even more flexible Log Entry Editing: The current
logedit
command does not allow users to reassign the volunteer or befriendee involved in a log, with the only way being to delete and re-add a new log. This could be inconvenient if someone accidentally inputs the wrong pair of indices resulting in a wrong pair being referenced. Hence, we plan to makelogedit
support reassignment of logs to other, valid pairs. -
Enhanced find feature: The current
find
command returns valid entries based on full matching of user inputs. We plan to enhance ourfind
command with partial name keyword/tag search functionality, enabling users to find contacts based on partial name/tag matches. Improves search efficiency and usability in case a user may not fully remember a contact’s name or tag. -
Better find command format: While the current
find
command supports a more concise and naturalised search, users may feel that the parameter format is not standardised across all commands, leading to inconvenience for those with bad memory. We plan to implement and support standardisedfind
command parameters (such asn/NAME_KEYWORD
,p/PAIR_STATUS
etc.) that would help streamline the formatting across all our commands. This would also naturally include appropriate exception handling for invalid input parameters as well. -
Add customizability to constraints of logs added: Currently, logs added can have dates in the future. While this may be desirable (for e.g. to log a planned visit with todos, and subsequently update remarks after the visit), it may also be undesirable (for e.g. to prevent accidental future date inputs). We plan to add a configuration option to allow users to set constraints on the dates of logs added, such that users can customize the behavior to suit their needs.
-
Flexible Grouping of Volunteer and Befriendee: Currently, our system only supports 1-1 pairing of volunteer and befriendee. We recognise that expanding beyond will bring stronger flexibility and generalizability, and hence plan to expand the current 1-to-1 pairing system to allow for more flexible grouping of volunteers and befriendees. Specifically, this would allow multiple volunteers to be paired with a single befriendee, vice versa, or allow a group of volunteers to be paired with a group of befriendees. This would be consistent with logadd, logedit, and logdelete commands.
-
More Informative Pairing and Unpairing Outputs: Currently, the
pair
andunpair
commands do not provide exact and detailed feedback during failure of the operation (e.g. person already paired, or persons are not paired together). While the user can thereafter search to find these details using thefind
command, we plan to enhance these commands to provide stronger feedback, including which person is paired, whom each person is currently paired with, and provide shortcuts for a user to easily unpair that person (e.g. by providing copy-paste formatted commands in the output). -
More Customizable UI for output: Currently, while the entire window is adjustable with each list scaling individually, the output message window is not height adjustable. To improve user experience, we plan to make the output message window height adjustable, allowing users to adjust the height of the output message window to their preference.
-
More Specific Error Messages showing specific parameter absence/invalidity: While the current error messages are informative, they do not provide specific details on which parameter is missing or invalid. We plan to enhance the error messages to provide more specific details on which parameter is missing or invalid, allowing users to quickly identify and rectify the issue. (E.g. for
add
command, the error message will specify which parameter is missing or invalid). -
Better duplicate person detection: Currently, our application disallows duplicate people without case sensitivity, meaning 2 contacts with names
John Doe
andjohn doe
respectively are considered duplicate people. However, extra white spaces in the name will cause contacts to be considered different people, even if everything else is equal. Thus, we plan to enhance the duplicate detection in our application to warn the user when inputting such near match cases. This will give users the ability to confirm if they intend to add a new contact resembling an existing one, with extra white spaces.