GourmetGrid is adapted from AddressBook-Level3.
Libraries used: JavaFX, Jackson, JUnit5.
AI was used to autocomplete content and occasionally code where appropriate, but always refined by the team and used with caution. In particular, the GitHub Copilot tool was used as an IDE plugin to provide hints on how to complete our sentences.
Refer to the guide Setting up and getting started.
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.
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
.
Each of the four main components (also shown in the diagram above),
interface
with the same name as the Component.{Component Name}Manager
class (which follows the corresponding API interface
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.
The API of this component is specified in Ui.java
The UI consists of a MainWindow
that is made up of parts e.g.CommandBox
, ResultDisplay
, PersonListPanel
, StatusBarFooter
etc. All these, including the MainWindow
, inherit from the abstract UiPart
class which captures the commonalities between classes that represent parts of the visible GUI.
The UI
component uses the JavaFx UI framework. The layout of these UI parts are defined in matching .fxml
files that are in the src/main/resources/view
folder. For example, the layout of the MainWindow
is specified in MainWindow.fxml
The UI
component,
Logic
component.Model
data so that the UI can be updated with the modified data.Logic
component, because the UI
relies on the Logic
to execute commands.Model
component, as it displays Person
object residing in the Model
.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")
API call as an example.
Note: The lifeline for 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:
Logic
is called upon to execute a command, it is passed to an AddressBookParser
object which in turn creates a parser that matches the command (e.g., DeleteCommandParser
) and uses it to parse the command.Command
object (more precisely, an object of one of its subclasses e.g., DeleteCommand
) which is executed by the LogicManager
.Model
when it is executed (e.g. to delete a person).Model
) to achieve.CommandResult
object which is returned back from Logic
.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:
AddressBookParser
class creates an XYZCommandParser
(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 a XYZCommand
object (e.g., AddCommand
) which the AddressBookParser
returns back as a Command
object.XYZCommandParser
classes (e.g., AddCommandParser
, DeleteCommandParser
, ...) inherit from the Parser
interface so that they can be treated similarly where possible e.g, during testing.API : Model.java
The Model
component,
Person
objects (which are contained in a UniquePersonList
object).Person
objects (e.g., results of a search query) as a separate filtered list which is exposed to outsiders as an unmodifiable ObservableList<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.UserPref
object that represents the user’s preferences. This is exposed to the outside as a ReadOnlyUserPref
objects.Model
represents data entities of the domain, they should make sense on their own without depending on other components)Note: An alternative (arguably, a more OOP) model is given below. It has a 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.
API : Storage.java
The Storage
component,
AddressBookStorage
and UserPrefStorage
, which means it can be treated as either one (if only the functionality of only one is needed).Model
component (because the Storage
component's job is to save/retrieve objects that belong to the Model
)Classes used by multiple components are in the seedu.address.commons
package.
This section describes some noteworthy details on how certain features are implemented.
The add
command allows users to create and add a new contact to the list.
Its process largely follows from the previous address book implementation, but with slight modifications for GourmetGrid's unique functions.
Below is the sequence diagram for the add
command process:
The addfav
feature allows users to add suppliers as favourites.
Aspect: How a contact being set as favourite is represented:
Alternative 1 (current choice): A boolean field in the Person
class is used to indicate whether a Person
is a favourite
Person
class by adding a simple primitive boolean to store information about favourites.Person
class given that all other fields are their own defined classes.Alternative 2: A custom class field is created in the Person
class to indicate whether a Person
is a favourite
Person
classFavourite
wrapper class to store information on whether a person is a favourite. This may result in unnecessary abstraction given that the field and information to be stored are quite rudimentary.AddFavouriteCommandParser
interprets the user input, extracts the specified indices and creates an instance of AddFavouriteCommand
.AddFavouriteCommand
fetches the contacts specified by the indices and adds them as favourites by modifying the isFavourite
field.Below is the sequence diagram for the addfav
command process:
The removefav
feature allows users to remove suppliers from favourites.
Aspect: How a contact being removed from favourite is managed within Person objects:
Alternative 1 (current choice): Directly remove a contact from favourite by setting its corresponding boolean field in the Person
class, which indicates whether a Person
is a favourite, to false
Pros: Utilises the current Person
class by modifying a simple primitive boolean to store information about favourites.
Cons: Not a uniform way of representing information in the Person
class given that all other fields are their own defined classes.
Alternative 2: Remove a contact from favourite by interacting with a custom class field in the Person
class whose role is to indicate whether a Person
is a favourite
Pros: Aligns with the information representation of other fields in the Person
class
Cons: Necessitates a new Favourite
wrapper class to store information on whether a person is a favourite. This may result in unnecessary abstraction given that the field and information to be stored are quite rudimentary.
RemoveFavouriteCommandParser
interprets the user input, extracts the specified indices and creates an instance of RemoveFavouriteCommand
.RemoveFavouriteCommand
fetches the contacts specified by the indices and removes them from favourites by modifying the isFavourite
field.Below is the sequence diagram for the removefav
command process:
The listfav
feature allows users to filter the contacts such that only the favourites are shown.
Aspect: How the end result of filtering manifests:
Alternative 1 (current choice): The filtering logic follows closely from that of the find
feature.
Pros: Simple and easy to implement given the existing find
feature.
Cons: May result in some similar functionality between find
and listfav
features.
Alternative 2: Favourite contacts can be sorted to be above, with non-favourites below but still visible.
Pros: Allows users to see all contacts, with favourites at the top for easy access.
Cons: May result in confusion regarding the ordering of contacts.
ListFavouriteCommandParser
interprets the user input and creates an instance of ListFavouriteCommand
.ListFavouriteCommand
updates the filtering rule through the model to show only favourite contacts.Below is the sequence diagram for the listfav
command process:
The addorder
feature allows users to add orders to a contact.
Aspect: How orders are stored:
Alternative 1 (current choice): Orders are stored as a list in Person
class.
Pros: Utilises the current Person
class by allowing it to store a list of orders.
Cons: Person
class become more complicated as more attributes are added.
Alternative 2: Orders are stored in a different storage class such as OrderStorage
.
Pros: Person
class remains simple.
Cons: Necessitates a new OrderStorage
storage class to store orders. This may result in duplicated code since the implementation of AddressBookStorage
is similar.
AddOrderCommandParser
interprets the user input, extracts the index of the specified contact and the date and remark of the order. Then, it creates an instance of Order
and AddOrderCommand
.AddOrderCommand
fetches the selected contact from the model and adds the order to the contact.Below is the sequence diagram for the addorder
command process:
The listorder
feature allows users to list all orders associated with a contact in the address book, sorted by date in ascending order first, then tiebroken by the sequence they were added in. This is particularly useful for users to track incoming orders of contacts efficiently.
Aspect: Sorting orders by date.
Aspect: Integration with existing data models.
Person
and new implemented Order
models minimizes code redundancy and maintains consistency within the application.ListOrderCommandParser
interprets the user input, extracts the index of the specified person, and creates an instance of ListOrderCommand
.ListOrderCommand
fetches the selected person's orders from the model, sorts them by date, and prepares the output string.Below is the sequence diagram for the listorder
command process:
The deleteorder
feature allows users to delete a specific order from a supplier's list of orders, ensuring accurate and up-to-date record-keeping.
Aspect: How order deletion is managed within Person objects
Alternative 1 (current choice): Directly manage orders within the Person class by removing them from the person's order list.
Pros: Utilises the existing structure of the Person class, allowing for straightforward access and modification of a person's order list.
Cons: Adds complexity to the Person class, which now handles both personal information and order management.
Alternative 2: Implement a dedicated order management system within the model.
Pros: Separates concerns, making the system more modular and potentially easier to maintain.
Cons: Increases system complexity by introducing new components and possibly duplicating list management functionality.
DeleteOrderCommandParser
interprets user input to identify the target person and order indices, then creates an instance of DeleteOrderCommand
.DeleteOrderCommand
locates the target person in the model, identifies the correct order based on the provided index (accounting for sorting by date, then addition sequence), and removes it from the person's orders.Below is the sequence diagram for the deleteorder
command process:
The proposed undo/redo mechanism is facilitated by VersionedAddressBook
. It extends AddressBook
with an undo/redo history, stored internally as an addressBookStateList
and currentStatePointer
. Additionally, it implements the following operations:
VersionedAddressBook#commit()
— Saves the current address book state in its history.VersionedAddressBook#undo()
— Restores the previous address book state from its history.VersionedAddressBook#redo()
— Restores a previously undone address book state from its history.These operations are exposed in the Model
interface as Model#commitAddressBook()
, Model#undoAddressBook()
and Model#redoAddressBook()
respectively.
Given below is an example usage scenario and how the undo/redo mechanism behaves at each step.
Step 1. The user launches the application for the first time. The VersionedAddressBook
will be initialized with the initial address book state, and the currentStatePointer
pointing to that single address book state.
Step 2. The user executes delete 5
command to delete the 5th contact in the address book. The delete
command calls Model#commitAddressBook()
, causing the modified state of the address book after the delete 5
command executes to be saved in the addressBookStateList
, and the currentStatePointer
is shifted to the newly inserted address book state.
Step 3. The user executes add n/David …
to add a new person. The add
command also calls Model#commitAddressBook()
, causing another modified address book state to be saved into the addressBookStateList
.
Note: If a command fails its execution, it will not call Model#commitAddressBook()
, so the address book state will not be saved into the addressBookStateList
.
Step 4. The user now decides that adding the contact was a mistake, and decides to undo that action by executing the undo
command. The undo
command will call Model#undoAddressBook()
, which will shift the currentStatePointer
once to the left, pointing it to the previous address book state, and restores the address book to that state.
Note: If the currentStatePointer
is at index 0, pointing to the initial AddressBook state, then there are no previous AddressBook states to restore. The undo
command uses Model#canUndoAddressBook()
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:
Note: The lifeline for 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#redoAddressBook()
, which shifts the currentStatePointer
once to the right, pointing to the previously undone state, and restores the address book to that state.
Note: If the currentStatePointer
is at index addressBookStateList.size() - 1
, pointing to the latest address book state, then there are no undone AddressBook states to restore. The redo
command uses Model#canRedoAddressBook()
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 address book, such as list
, will usually not call Model#commitAddressBook()
, Model#undoAddressBook()
or Model#redoAddressBook()
. Thus, the addressBookStateList
remains unchanged.
Step 6. The user executes clear
, which calls Model#commitAddressBook()
. Since the currentStatePointer
is not pointing at the end of the addressBookStateList
, 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:
Aspect: How undo & redo executes:
Alternative 1 (current choice): Saves the entire address book.
Alternative 2: Individual command knows how to undo/redo by itself.
delete
, just save the contact being deleted).Target user profile:
Value proposition:
Priorities: High (must have) - * * *
, Medium (nice to have) - * *
, Low (unlikely to have) - *
Priority | As a … | I want to … | So that I can… |
---|---|---|---|
* * * | restaurant owner | add contacts with detailed information | better manage relationship with contacts |
* * * | restaurant owner | immediately see a list of contacts | access or contact them more easily |
* * * | restaurant owner | search by name, tag and company | quickly find the person I want to contact |
* * * | restaurant owner | add orders to a contact | keep track of my orders with the contact |
* * * | restaurant owner | views orders of a contact | keep track of my orders with the contact |
* * * | restaurant owner | mark certain contacts as favourites | access them more easily in the future |
* * * | restaurant owner | unmark certain contacts as favourites | keep my favourite contact list clean |
* * * | frequent user | view my favourite contacts | access or contact them more easily |
* * * | long time user | edit contact details | keep my address book up to date |
* * * | long time user | delete contacts | keep my address book relevant and clean |
* * * | long time user | delete orders | keep my order list relevant and clean |
* * * | potential user exploring the app | see examples with sample data on the app | easily visualize how the app will look like when handling data that is typical for my use case |
* * * | potential user exploring the app | delete all sample data | easily add my own data to a clean slate |
* * | restaurant owner | receive notifications of incoming orders | know the orders that I am expecting today |
* | careless user | undo my commands | reduces the number of actions I have to take |
(For all use cases below, the System is GourmetGrid
and the Actor is the User
, unless specified otherwise)
Use case: UC1 - List contacts
MSS
User requests to list contacts.
GourmetGrid shows a list of contacts.
Use case ends.
Extensions
1a. GourmetGrid detects an error in the user command.
1a1. GourmetGrid shows an error message.
Use case ends.
Use case: UC2 - Delete a contact
MSS
User lists contacts (UC1).
User requests to delete a specific contact in the list.
GourmetGrid deletes the contact.
Use case ends.
Extensions
1a. The list is empty.
Use case ends.
2a. GourmetGrid detects an error in the user command.
2a1. GourmetGrid shows an error message.
Use case ends.
2b. GourmetGrid detects that the contact does not exist.
2b1. GourmetGrid shows an error message.
Use case ends.
Use case: UC3 - Find contacts
MSS
User enters a command to find contacts by name, tag, or company with one or more keywords.
GourmetGrid searches and displays all contacts matching all the given keywords.
Use case ends.
Extensions
1a. GourmetGrid detects an error in the user command.
1a1. GourmetGrid shows an error message.
Use case ends.
1b. No contacts match the search criteria.
1b1. GourmetGrid shows a message indicating no contacts were found.
Use case ends.
Use case: UC4 - Add an order
MSS
User requests to add an order to a contact
GourmetGrid adds the order to the contact
Use case ends.
Extensions
1a. GourmetGrid detects an error in the user command.
1a1. GourmetGrid shows an error message.
Use case ends.
Use case: UC5 - List orders
MSS
User requests to list orders for a specific contact.
GourmetGrid displays all orders associated with the contact.
Use case ends.
Extensions
1a. GourmetGrid detects an error in the user command.
1a1. GourmetGrid shows an error message.
Use case ends.
1b. The specified contact has no orders.
1b1. GourmetGrid shows a message indicating there are no orders for the contact.
Use case ends.
Use case: UC6 - Delete an order
MSS
User requests to delete a specific order from a specific contact’s list of orders.
GourmetGrid deletes the order.
Use case ends.
Extensions
1a. GourmetGrid detects an error in the user command.
1a1. GourmetGrid shows an error message.
Use case ends.
Use case: UC7 - List favourites
MSS
User requests to list favourite contacts
GourmetGrid lists favourite contacts
Use case ends.
Extensions
1a. GourmetGrid detects an error in the user command.
1a1. GourmetGrid shows an error message.
Use case ends.
Use case: UC8 - Add a contact as favourite
MSS
User requests to add a contact as favourite
GourmetGrid marks the contact as favourite
Use case ends.
Extensions
1a. GourmetGrid detects an error in the user command.
1a1. GourmetGrid shows an error message.
Use case ends.
1b. GourmetGrid detects that the contact is already marked as favourite.
1b1. GourmetGrid shows a warning message.
Use case resumes from Step 2.
Use case: UC9 - Removing a contact from favourites
MSS
User requests to remove a contact from favourites
GourmetGrid removes the contact from favourites
Use case ends.
Extensions
1a. GourmetGrid detects an error in the user command.
1a1. GourmetGrid shows an error message.
Use case ends.
1b. GourmetGrid detects that the contact is not marked as favourite.
1b1. GourmetGrid shows a warning message.
Use case resumes from Step 2.
11
or above installed.Given below are instructions to test the app manually.
Note: These instructions only provide a starting point for testers to work on; testers are expected to do more exploratory testing.
Initial launch
Prerequisites: Ensure you have followed the setup instructions above.
Download the jar file and copy into an empty folder
Double-click the jar file
Expected: Shows the GUI with a set of sample contacts.
Saving window preferences
Resize the window to an optimal 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.
Deleting a contact while all contacts are being shown
Prerequisites: List all contacts using the list
command. There should be at least one contact in the list.
Test case: delete 1
Expected: First contact is deleted from the list. Details of the deleted contact shown in the result display.
Test case: delete 0
Expected: No contact is deleted. Error details shown in the result display. List of visible contacts remains the same.
Other incorrect delete commands to try: delete
, delete x
, ...
(where x is larger than the list size)
Expected: Similar to previous.
Finding contacts by names, tags, or companies
Prerequisites: List all contacts using the list
command. There should be multiple contacts in the address book with varying names, tags, and company affiliations.
Test case: find n/Alice
Expected: The list is filtered to include only contacts with names containing "Alice" as a substring. The details of the contacts found are shown in the result display.
Test case: find t/friend
Expected: The list is filtered to show only contacts tagged with "friend" as a substring. Details of the contacts found are displayed in the result display.
Test case: find c/Acme
Expected: The list is filtered to show only contacts associated with a company containing the "Acme" substring. Result display shows the details of the contacts found.
Test case: find n/Bob c/XYZ
Expected: Contacts with name containing "Bob" as a substring and with company containing "XYZ" as a substring are displayed. This is a compound query demonstrating the logical AND operation.
Adding an order to a contact
Prerequisites: List all contacts using the list command. There is only 1 contact in the address book.
Test case: addorder 1 d/ 2025-01-01 r/ 100 chicken wings
Expected: The number of orders of the first contact increases by 1. Details of the contact, with the new order, are shown in the result display. The date of the new order is 2025-01-01 and the remark is 100 chicken wings.
Test case: addorder 0 d/ 2025-01-01 r/ 100 chicken wings
Expected: No new order is added. An error indicating invalid command format is shown in the result display.
Test case: addorder 5 d/ 2025-01-01 r/ 100 chicken wings
Expected: No new order is added. An error indicating invalid contact index is shown in the result display.
Test case: addorder 1 d/ 2025-99-99 r/ 100 chicken wings
Expected: No new order is added. An error indicating invalid date format is shown in the result display.
Viewing orders after adding order to a contact.
listorder 1
command.Listing orders for a specific contact
Prerequisites: There must be at least one contact in the address book who has orders. Use addorder
command to add orders if necessary.
Test case: listorder 1
Expected: All orders associated with the first contact in the list are displayed. Details of the orders are shown in the result display.
Test case: listorder 0
Expected: No orders are listed. An error message indicating invalid command format is shown in the result display.
Test case: listorder x
(where x is larger than the list size)
Expected: No orders are listed. An error message indicating invalid contact index is shown in the result display.
Deleting an order from a person's list of orders
Prerequisites: List all contacts using the list
command. Ensure that at least the first contact has multiple orders. You may use addorder
to add orders to a person.
Test case: deleteorder 1 o/1
Expected: The first order from the first person’s order list is deleted. The details of the deleted order are shown in the result display.
Test case: deleteorder 1 o/x
(where x is larger than the number of orders the contact has)
Expected: No order is deleted. An error message indicating an invalid order index is shown in the result display.
Test case: deleteorder 0 o/1
Expected: No order is deleted. An error message indicating invalid command format is shown.
Test case: deleteorder x o/1
(where x is larger than the list size)
Expected: No order is deleted. An error message indicating invalid contact index is shown.
Listing contacts that have been added to favourites
Prerequisites: Add a few contacts to favourites using the addfav
command.
Test case: listfav
Expected: All contacts that have been added to favourites are displayed. A success response is shown in the result display.
Test case: listfav x
(where x is any non-space character(s))
Expected: An error message indicating invalid command format due to trailing text after listfav
is shown in the result display. No filtering occurs on the displayed list.
Removing a contact from favourites after listfav
Prerequisites: Call listfav
successfully.
Test case: removefav i/1
Expected: The first contact currently displayed in list of favourites is removed as favourite. Result display shows the name of the contact removed from favourites. Updated full list of contacts is shown.
Adding contact(s) as favourite
Prerequisites: List all contacts using the list
command. Ensure there are at least three contacts in the list.
Test case: addfav i/ 1,3
Expected: First and third contacts are added as favourites. Details of the affected contacts are shown in the result display.
Test case: addfav i/ 1
Expected: First contact is added as favourite. Details of the affected contact are shown in the result display. A warning regarding contacts that were already in favourites is also shown in the result display.
Test case: addfav i/ 0
Expected: No contact is added as favourite. An error message indicating invalid command format is shown in the result display.
Test case: addfav x i/ 1
(where x is any non-space character)
Expected: Similar to previous.
Removing contact(s) from favourites
Prerequisites: List all contacts using the list
command. Three contacts in the list of which the first and third contacts are marked as favourite. You may use addfav
to add these contacts as favourites.
Test case: removefav i/ 1,3
Expected: First and third contacts are removed from favourites. Details of the affected contacts are shown in the result display.
Test case: removefav i/ 1
Expected: First contact is removed from favourites. Details of the affected contact are shown in the result display. A warning regarding contacts that were not previously in favourites is also shown in the result display.
Test case: removefav i/ 0
Expected: No contact is removed from favourites. An error message indicating invalid command format is shown in the result display.
Test case: removefav x i/ 1
(where x is any non-space character)
Expected: Similar to previous.
Team size: 4
UI improvements: The current UI shows the orders of a contact inResultDisplay
when listorder
command is called. We plan to add an OrderListPanel
beside the existing PersonListPanel
to show the orders
of a contact instead. This will allow users to view the orders of a contact in a more user-friendly manner,
without having the need to call listorder
repeatedly for the same contact whenever a new command updates ResultDisplay
.
Furthermore, when a very long field is added, the UI text may be truncated. We plan to add a tooltip to show
the full text when the mouse hovers over the truncated text.
Make addorder
message more specific: The current addorder
command does not show a preview of the
order added, making it inconvenient for users as they have to scroll all the way to end of ResultDisplay
to view their newly added order. We plan to show a preview of the order added. For example:
Added Order: [100 oranges (by: 2024-04-15)] from Alex Yeoh
.
Raise error when an outdated order date is added: The current date validation does not check if the
order date is outdated when addorder
command is called. We plan to raise an error when an outdated order date
is added. For example: Order date cannot be in the past
.
Support more flexible phone number formats: The current phone number validation only accepts numerical inputs.
We plan to support more flexible formats, including country codes and special characters. For example:
+65 1234 5678
, +129-123-334-5678
.
Improve Search Functionality: The current implementation of the find command allows users to search for contacts based on their names, tags, or company names. However, it does not support searching by address, email, or phone number. We acknowledge that the ability to search by these fields can significantly enhance user experience by providing more flexibility and efficiency in locating contact information. The initial decision to exclude address, email, and phone number from the search criteria was based on a focus on the most commonly used identifiers for quick search and to maintain simplicity in the search interface. We also considered the privacy implications and the less frequent necessity of searching by personal information such as phone numbers or addresses. However, in order to enhance the utility of our contact management system, we are planning to introduce expanded search capabilities. This will include the ability to search for contacts by their phone numbers, email addresses, and physical addresses. This enhancement aims to provide a comprehensive search functionality that meets the needs of all users, making the tool more versatile and efficient for locating specific entries.
Warning when using clear
command: The current implementation of the clear
command deletes all contacts
and orders without any warning or confirmation from the user. This can lead to accidental data loss if the user
mistakenly enters the command. To prevent such incidents, we plan to introduce a warning prompt when the clear
command is executed. The warning message will inform the user about the irreversible nature of the action and
prompt them to confirm their decision before proceeding with the deletion.
Advanced data validation for inputs: The current implementation does not check the length of text-based inputs.
We plan to add a reasonable length limit for relevant fields such as NAME
, EMAIL
, ADDRESS
, TAG
, COMPANY
and REMARK
to prevent database overflow, ensure data integrity, and enhance user experience.
Adding a new contact: The current implementation of the add
command does not allow users to add a new
contact with the same name but different address, email, and number. We plan to enhance the add
command to support the
addition of multiple contacts with the same name but different contact details.