ClientConnect is an AddressBook which is built upon AddressBook3
The app utilizes the following third-party libraries:
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
, ClientListPanel
, 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 Client
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 then executed by the LogicManager
.Model
to perform necessary operations (e.g. deleting a client). While this is shown as a single step in the diagram above for simplicity, it often involves multiple method calls between the Command
and Model
.CommandResult
object which is returned from Logic
.Internally, LogicManager
also handles logging and error tracking through the LogsCenter
utility. This enables detailed logs for actions such as the input command string and any exceptions thrown during parsing or execution, providing transparency and easing debugging.
The Logic
component is designed with extensibility in mind. To support a new command, developers simply need to:
Command
(e.g., SortCommand
)SortCommandParser
) that implements the Parser<T>
interfacecase
to the AddressBookParser#parseCommand
methodThis modular design makes it straightforward to extend the system while maintaining clarity and separation of concerns 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,
Client
objects (which are contained in a UniqueClientList
object).Client
objects (e.g., results of a search query) as a separate filtered list which is exposed to outsiders as an unmodifiable ObservableList<Client>
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 Client
references. This allows AddressBook
to only require one Tag
object per unique tag, instead of each Client
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 Rank
command component,
Comparator
that determines the sort order between any two clients using the compare
method.Comparator
has a COMPARATOR_WORD
String
that is used to parse user input to create the suitable Comparator
.Comparator
also depends on the Client
which helps to gain access to the required parameters to compare with.Given below is an example usage scenario and how the rank mechanism behaves at each step.
Alice
at the top of their client list.rank name
as the command input.Here's the sequence diagram that shows the flow of the execution for the command rank name
.
Target user profile:
Value proposition: provide fast access to clients’ addresses and preferences to help salespeople in making sales decisions and building rapports with clients, which can potentially increase their sales revenue
Priorities: High (must have) - * * *
, Medium (nice to have) - * *
, Low (unlikely to have) - *
Priority | As a … | I want to … | So that I can… |
---|---|---|---|
* * * | salesperson | add in my clients’ contact details | contact them for business purposes |
* * * | salesperson | edit my clients’ contact details | keep their information updated and relevant |
* * * | salesperson | delete a client | get rid of contact information that I don’t need anymore |
* * * | salesperson | find my clients’ info quickly in a large database | locate contact details of clients without having to go through the entire list |
* * * | salesperson who wants to know my customer preferences | rank my clients based on the most purchased product type | find out who my potential customers are for a given product |
* * * | salesperson | record clients' frequency of purchase | personalise advertisement and services |
* * * | salesperson | record clients' product preferences | promote new products to clients that are more likely to be interested in |
* * * | new user | view examples for the main features | get on board with the application more easily |
* * | user | be able to expand out the client information | view it with a bigger window |
* * | user | undo all my previously executed commands | revert changes without having to manually type in a long command |
* * | user | search for clients by name, phone number, or tag | quickly retrieve their information without scrolling through the entire list |
* * | salesperson | add profile pictures for my clients | quickly recognize them and personalize my interactions |
* * | salesperson | add social media links to client profiles | easily connect with them on different platforms |
* * | salesperson whose clients are of different statuses | categorize clients into different groups (e.g., VIP, Potential, Regular) | manage them more efficiently and tailor my communication |
* * | salesperson whose customers come from many industries | add tags for clients | split them into categories |
* * | salesperson | filter clients by tags | quickly see all the clients inside one category |
* * | user | be able to use the software in dark mode | view the contents comfortably |
* | user | have multiple accounts | save customer profiles for different businesses |
* | salesperson who needs to report to my company | export my client list to a CSV file | share it with my team or use it for data analysis and reporting |
* | salesperson | track the geographical location of my clients | plan visits efficiently |
* | paranoid user | access my address book via an authentication system | my customer profiles are kept confidential |
* | user | use the software in my desired language | understand how to use the software better |
{More to be added}
(For all use cases below, the System is the ClientConnect
and the Actor is the user
, unless specified otherwise)
Use case: Adding a client
MSS
User enters the command to add a client.
ClientConnect validates the input format and checks that all required fields are present.
ClientConnect adds the client to the address book.
ClientConnect displays a confirmation message showing the newly added contact details.
Use case ends.
Extensions
2a. Invalid Field Detected:
Use case: View List of Clients
MSS
User enters the command to view current list of added entities
ClientConnect validates the command input.
ClientConnect retrieves all stored entities from the address book.
ClientConnect displays the list with each entity’s name, contact number, and address in a clear, formatted view.
Use case ends.
Extensions
Use case: Delete a client
MSS
User enters the command to view the list of clients.
ClientConnect displays the full list of clients.
User enters the command to delete a client.
ClientConnect validates the command.
ClientConnect retrieves the details of the client at the specified index.
ClientConnect deletes the client's details from the address book.
ClientConnect displays a success message: “Deleted: <Info of the deleted client>”
Use case ends.
Extensions
Use case: find a client
MSS
User enters the command to find a list of clients that contains the keyword.
ClientConnect validates the command.
ClientConnect retrieves the information of clients that contains that specified keyword in their descriptions.
ClientConnect displays the list of clients.
Use case ends.
Extensions
Use case: Describe a client
MSS
Extensions
2a. Invalid index provided:
2b. No description provided:
Use case: Rank clients
MSS
Extensions
Use case: Expand client view
MSS
Extensions
Use case: Filter clients
MSS
Extensions
Use case: Get help
MSS
Use case: Exit application
MSS
17
or above installed.{More to be added}
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.
ClientConnect will autoload a sample address book with a few entries to play around with if there isn't one being created yet. So you may perform these test cases even without adding new entries.
Initial launch
Download the jar file and copy into an empty folder
Double-click the jar file Expected: Shows the GUI with a set of sample contacts. 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.
Deleting a client while all clients are being shown
Prerequisites: List all clients using the list
command. Multiple clients in the list.
Test case: delete 1
Expected: First contact is deleted from the list. Details of the deleted contact shown in the status message. Timestamp in the status bar is updated.
Test case: delete 0
Expected: No client is deleted. Error details shown in the status message. Status bar remains the same.
Other incorrect delete commands to try: delete
, delete x
, ...
(where x is larger than the list size)
Expected: Similar to previous.
Prerequisites: List all clients using the list
command. Multiple clients in the list.
Test case: filter pref/shampoo
Expected: All clients with shampoo
as part of their product preference are shown.
Test case: filter priority/2
Expected: All clients with the PREMIUM
priority are shown.
Test case: filter name/John
Expected: Error details shown in the status message.
Other incorrect filter command keywords to try: filter
, filter address/
, ...
(where keyword is invalid)
Expected: Similar to previous.
Prerequisites: List all clients using the list
command. Multiple clients in the list.
Test case: rank name
Expected: All clients are sorted based on their names in lexicographical order.
Test case: rank total
Expected: All clients are sorted based on their total purchase in descending order.
Other correct rank command keywords to try: rank toTal
, rank NAME
Expected: Similar to previous.
Test case: rank handsomeness
Expected: Current clients' order does not change. Error details shown in the status message.
Team size: 5
Support multiple product preferences for each client: The current client only has one product preference and its frequency. We plan to make every client has a list of product preferences with its corresponding frequency, to meet a more realistic scenario.
New commands to work with product preference: The current app only provides some basic ways to work with product preference, which can be inconvinient at times. We plan to add more commands such as AddProductPreference
to add product preferences cumulatively for one client, DeleteProductPreference
to delete a certain product preference, and EditProductPreference
to conveniently edit a product preference or its frequency for one client.
New commands to add tags cumulatively: For the same reason, now we can only edit tags through edit
command, and if we want to add a new tag to a client without touching existing tags, we will also have to type out all the existing tags in the command, which is very inconvenient and unpractical. We can add new command AddTag
to add new tags cumulatively to a client, and another new command DeleteTag
to delete a certain existing tag for a client.
Rank clients by product frequency of a certain product preference: We want our rank
command to be more useful, adding its ability to rank in many ways, including rank clients based on the frequency of a certain product.
Search by Contact Information: Our app currently has no way of finding a client by his contact details. We plan to improve our find feature to allow users to directly search for a client using their phone number or email address for quicker lookup.
Implement Robust Contact Information Verification: Our app currently only imposes basic rules on contact details like phones and emails. We plan to incorporate third-party APIs to send verification codes to phone numbers and email addresses upon entry, confirming their validity and reachability.
Flexible Client Creation: The app currently requires all fields for a client to be added, which can be inconvenient or irrelevant at times. We plan to modify the client addition process to enhance user convenience. Instead of requiring all fields (name, phone, email, address), we require only one of these primary contact details to create a new client entry.