Developer Guide
-
LeadsForce - Developer Guide
- 1. Introduction
- 2. Setting up and getting started
- 3. Design
- 4. Implementation
- AddressBook feature
- 5. Documentation, logging, testing, configuration, dev-ops
-
6. Appendix: Requirements
- 6.1 Product scope
- 6.2 User stories
-
6.3 Use cases
- 6.3.1 UC01 Add a client to the client list
- 6.3.2 UC02 View a client’s information
- 6.3.3 UC03 Edit client information
- 6.3.4 UC04 Delete a client
- 6.3.5 UC05 Showcases list of clients
- 6.3.6 UC06 Search for a client
- 6.3.7 UC07 Setting a meeting with clients
- 6.3.8 UC08 Showing schedule for the day
- 6.3.9 UC09 Clearing a client list
- 6.3.10 UC10 Create a new address book
- 6.3.11 UC11 Clear an address book of clients
- 6.4 Non-Functional Requirements
- 6.5 Glossary
- 7. Appendix: Instructions for manual testing
LeadsForce - Developer Guide
By: AY2122S1-CS2103T-T17-3
1. Introduction
LeadsForce is a desktop app that is optimized for use via a Command Line Interface (CLI) while still having the benefits of a Graphical User Interface (GUI). Catered towards student financial advisors, LeadsForce makes the process of managing client information seamless! LeadsForce does this by helping the financial advisors store and retrieve client information effortlessly and seamlessly.
LeadsForce’s developer Guide is written for developers who wish to contribute to or extend our project. It is technical, and explains the inner workings of LeadsForce and how the different components of our application work together.
Reading this Developer Guide
| icon | remark |
|---|---|
| 💡 | This icon denotes useful tips to note of during development. |
| ❗️ | This icon denotes important details to take note of during development. |
This user guide is also colour coded according to the component.

2. Setting up and getting started
Refer to the guide Setting up and getting started.
3. Design
3.1 Architecture
LeadsForce is a brown field project adapted and developed upon from AddressBook3. Our team decided on reusing the overall architecture by maintaining the system with 6 components (as listed in the diagram above) while building upon each component to cater to the needs of LeadsForce. The Architecture Diagram given above explains the high-level design of the App, which was adapted from AddressBook3. In the subsequent chapters, we will be providing an overview of the component, explain how each component works internally, and how you could scale the system, which can server as a guideline for the developers to expand LeadsForce.
Tip: The .puml files used to create diagrams in this document can be found in the diagrams folder. Refer to the PlantUML Tutorial at se-edu/guides to learn how to create and edit diagrams.
Main has two classes called Main and MainApp. It is responsible for,
- At app launch: Initializes the components in the correct sequence, and connects them up with each other.
- At shut down: Shuts down the components and invokes cleanup methods where necessary.
Commons represents a collection of classes used by multiple other components.
The rest of the App consists of four components.
-
UI: The UI of the App. -
Logic: The command executor. -
Model: Holds the data of the App in memory. -
Storage: Reads data from, and writes data to, the hard disk.
Each of the four main components,
- defines its API in an
interfacewith the same name as the Component. - implements its functionality using a concrete
{Component Name}Managerclass (which follows the corresponding APIinterfacementioned 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.
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.
The sections below give more details of each component.
3.2 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, 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,
- executes user commands using the
Logiccomponent. - listens for changes to
Modeldata so that the UI can be updated with the modified data. - keeps a reference to the
Logiccomponent, because theUIrelies on theLogicto execute commands. - depends on some classes in the
Modelcomponent, as it displaysClientobject residing in theModel.
LeadsForce’s GUI is primarily adapted from AddressBook3, with the addition of a SideBar that conveniently displays information for the user.
Our SideBar has a ClientViewPanel, which like the ClientCard, has a dependency on the Model class to fully display the information of the Client of interest to the user.
In addition, the SideBar also has a MeetingListPanel, which holds a list of NextMeetingCard. NextMeetingCard has a dependency on the Model class to fully display all scheduled meetings of the user.
3.3 Logic component
API : Logic.java
Here’s a (partial) class diagram of the Logic component:
How the Logic component works:
- When
Logicis called upon to execute a command, it uses theAddressBookParserclass to parse the user command. - This results in a
Commandobject (more precisely, an object of one of its subclasses e.g.,AddCommand) which is executed by theLogicManager. - The command can communicate with the
Modelwhen it is executed (e.g. to add a client). - The result of the command execution is encapsulated as a
CommandResultobject which is returned fromLogic.
The Sequence Diagram below illustrates the interactions within the Logic component for the execute("delete 1") API call.

DeleteCommandParser should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram.
Here are the other classes in Logic (omitted from the class diagram above) that are used for parsing a user command:
How the parsing works:
- When called upon to parse a user command, the
AddressBookParserclass creates anXYZCommandParser(XYZis a placeholder for the specific command name e.g.,AddCommandParser) which uses the other classes shown above to parse the user command and create aXYZCommandobject (e.g.,AddCommand) which theAddressBookParserreturns back as aCommandobject. - All
XYZCommandParserclasses (e.g.,AddCommandParser,DeleteCommandParser, …) inherit from theParserinterface so that they can be treated similarly where possible e.g, during testing.
3.4 Model component
API : Model.java
The Model component,
- stores the address book data i.e., all
Clientobjects (which are contained in aUniqueClientListobject). - has a
UniqueNextMeetingListinAddressBook, which contains allNextMeetingobjects belonging to allClientobjects in theUniqueClientListobject. - has a
UniqueTagListinAddressBook, which containsTag(s) that aClientcan reference. This allowsAddressBookto only require oneTagobject per unique tag. - stores the currently ‘selected’
Clientobjects (e.g., results of a search query) as a separate filtered list which is exposed to outsiders as an unmodifiableObservableList<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.- this
ObservableList<Client>is used for to get theClientobject to display inClientListPanelandClientViewPanel
- this
- stores all
NextMeetingobjects belonging to allClientobjects as a separate sorted list which is exposed to outsiders as an unmodifiableObservableList<NextMeeting>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.- this
ObservableList<NextMeeting>is used for to get theNextMeetingobject to display inNextMeetingCardinMeetingsListPanel
- this
- stores a
UserPrefobject that represents the user’s preferences. This is exposed to the outside as aReadOnlyUserPrefobjects. - does not depend on any of the other three components (as the
Modelrepresents data entities of the domain, they should make sense on their own without depending on other components)
3.5 Storage component
API : Storage.java
The Storage component,
- can save both address book data and user preference data in json format, and read them back into corresponding objects.
- inherits from both
AddressBookStorageandUserPrefStorage, which means it can be treated as either one (if only the functionality of only one is needed). - depends on some classes in the
Modelcomponent (because theStoragecomponent’s job is to save/retrieve objects that belong to theModel)
3.6 Common classes
Classes used by multiple components are in the seedu.address.commons package.
3.7 Client Fields
As client attributes often share a few similarities in their constraints, some with their own differences, we provide interfaces for developers to customise the constraints of client attributes.
3.7.1 Field options
We provide options for developers to easily customise the constraints on the user input such as whether the input is required or whether it is editable. These field options are encapsulated within the Field interface, which further branches into more concrete interfaces which can be implemented by Client attributes.
Field options largely dictate how the parsers respond to user’s inputs.
| Option | Description |
|---|---|
| IS_BLANK_VALUE_ALLOWED | If set to true, the field is allowed to be blank (for string fields such as phone, name, etc). Default to true. |
| IS_NULL_VALUE_ALLOWED | If set to true, the field is allowed to be null (for int/Date fields such as LastMet, etc). Default to true. |
| DEFAULT_VALUE | The default value for the field. Set when user does not pass in the prefix on Client creation. Default to "". |
| IS_EDITABLE | If set to true, the field is editable by the user through edit command. Default to true. |
3.7.2 Field interfaces
The following concrete interfaces inherit the Field interface. You can alternatively define your own interface or provide a concrete implementation of the field options within the attribute classes if they don’t suit your needs.
3.7.2.1 OptionalStringBasedField
| Option | Default |
|---|---|
| IS_BLANK_VALUE_ALLOWED | true |
| IS_NULL_VALUE_ALLOWED | false |
| DEFAULT_VALUE | "" |
| IS_EDITABLE | true |
3.7.2.2 OptionalNonStringBasedField
| Option | Default |
|---|---|
| IS_BLANK_VALUE_ALLOWED | true |
| IS_NULL_VALUE_ALLOWED | true |
| DEFAULT_VALUE | "" |
| IS_EDITABLE | true |
3.7.2.3 RequiredField
| Option | Default |
|---|---|
| IS_BLANK_VALUE_ALLOWED | false |
| IS_NULL_VALUE_ALLOWED | false |
| DEFAULT_VALUE |
""(But not used as value is required) |
| IS_EDITABLE | true |
3.7.3 FieldLength interfaces
There are FieldLength interfaces that contain a MAX_LENGTH field. This is used to help limit the number of characters that a user can input for a particular field.
| FieldLength type |
MAX_LENGTH value |
|---|---|
| StandardFieldLength | 30 |
| ShorterFieldLength | 15 |
| LongerFieldLength | 100 |
3.8 Comparable Client Attribute
All the clients attribute which the sort command support implements the IgnoreNullComparable interface to help determine an ordering for the attributes.
3.8.1 IgnoreNullComparable
The IgnoreNullComparable interface implements the Comparable interface and has the method compareWithDirection(T, SortDirection). The compareWithDirection is similar to the compareTo in Comparable but has the following additional properties: 1) null or the null-equivalent of the attribute will be ordered last. 2) the ordering will also be determined by the SortDirection pass into it.

3.8.2 StringComparable
StringComparable is an abstract class which implements the IgnoreNullComparable interface which determine the ordering of an attributes based on the lexicographical ordering of the string representation of the attribute.
3.8.3 NumberComparable
NumberComparable is an abstract class which implements the IgnoreNullComparable interface which determine the ordering of an attributes based on the numerical ordering of the number representation of the string representation of the attribute.
3.8.4 Attribute’s Comparable Interface Summary
| Attribute | Comparable Interface |
|---|---|
| Client Id | NumberComparable |
| Name | StringComparable |
| StringComparable | |
| Phone | NumberComparable |
| Address | StringComparable |
| Risk Appetite | NumberComparable |
| Disposable Income | Number Comparable |
| Last Met | IgnoreNullComparable |
| Next Meeting | IgnoreNullComparable |
3.9 Prefix Mapper
The PrefixMapper is a utility class which provides a mapping of a prefix to the relevant methods for the attribute of that prefix. This class help to simplify segments of code which require operations that are dependent on the prefix and its corresponding attribute. The PrefixMapper contains a HashMap which map a prefix to their respective PrefixMapperElement. A PrefixMapperElement contains getter & setter method and values that are relevant to an attribute.
PrefixMapperElement contains the following:
- Name of the Attribute
- Default value of the Attribute
- Client Attribute getter Function
- EditClientDescriptor Attribute setter BiConsumer
- EditClientDescriptor Attribute getter Function
- Attribute Parser Function
4. Implementation
This section describes some noteworthy details on how certain features are implemented.
AddressBook feature
4.1 View Client Info
Description
LeadsForce allows users to view client info in the ClientViewPanel in the SideBar of the GUI using the View command.
Implementation
- The
LogicManagerstarts to parse the given input text usingAddressBookParser. - The
AddressBookParserinvokes the respectiveParserbased on the first word of the input text. - The remaining input text will be passed to the
ViewCommandParserto parse. - The
ViewCommandParserwill parse theClientIdfrom the remaining input text. In our implementation, a validClientIdis any non-negative integer. - The
ViewCommandParserwill then create a newClientHasIdusing theClientIdparsed. - The
ViewCommandParserwill then create aViewCommandwith theClientIdandClientHasId. - The
LogicMangerwill call theexecutemethod ofViewCommand. - The
ViewCommandwil then call theupdateClientToViewmethod of the providedModelwith it’sClientHasId. - The
ViewCommandwill finally create a newCommandResultwhich will be returned toLogicManagerand the client’s information with the givenClientIdin theClientViewPanel.
The following sequence diagram shows how the view operation works:
Implementation of ClientHasId
ClientHasId implements Predicate<Client> and allow filtering of a list of Client based on ClientId objects. ClientHasId contains a list which holds these ‘ClientId’. This allows the Model to use this list of ClientId objects to filter for Client(s) that contain the given ClientId(s).
4.2 Edit Client Info
Description
LeadsForce allows users to edit client info.
Implementation
- The
LogicManagerstarts to parse the given input text usingAddressBookParser. - The
AddressBookParserinvokes the respectiveParserbased on the first word of the input text. - The remaining input text will be passed to the
EditCommandParserto parse. - The
EditCommandParserwill tokenize the remaining input text using theArgumentTokenizerinto anArgumentMultiMap. - The
EditCommandParserwill then create a newclientIdwhich contains the list of client Ids. - The
EditCommandParserwill then create a newEditClientDescriptorwhich contains the fields that the user is intending on editing. - The
EditCommandParserwill create aEditCommandcontaining both the list of client Ids and theEditClientDescriptor. - The
LogicMangerwill call theexecutemethod of the aforementionedEditCommand. - The
EditCommandwill then call thesetAllClientsmethod of the providedModelwith theEditClientDescriptorand the list of clients. - The
EditCommandwill then call theupdateFilteredClientListmethod of the providedModelwith a predicate to show all clients in the client list. - The
EditCommandwill finally create a newCommandResultwhich will be returned toLogicManagerand the client’s information will be edited as according to the command input.
The following sequence diagram shows how the edit operation works:
Implementation of EditClientDescriptor
The EditClientDescriptor keeps tracks of all the attributes that the user intends on updating, and does so by using the set{ATTRIBUTE} command for all the attributes of Client(such as setName, setPhone, etc.).
4.3 Search Clients
Description
LeadsForce allows the user to search for clients using keywords. The keywords can be used to match generically
with any client’s attribute or specifically with the specified attributes
Implementation
- The
LogicManagerstarts to parse the given input text usingAddressBookParser. - The
AddressBookParserinvokes the respectiveParserbased on the first word of the input text. - The remaining input text will be passed to the
SearchCommandParserto parse. - The
SearchCommandParserwill tokenize the remaining input text using theArgumentTokenizerinto anArgumentMultiMap. - The
SearchCommandParserwill then create a newClientContainsKeywordPredicateusing theArgumentMultiMap. - The
SearchCommandParserwill then create aSearchCommandwith theClientContainsKeywordPredicate. - The
LogicMangerwill call theexecutemethod ofSearchCommand. - The
SearchCommandwil then call theupdateFilteredClientListmethod of the providedModelwith it’sClientContainsKeywordPredicate. - The
SearchCommandwill finally create a newCommandResultwhich will be returned toLogicManager.
The following sequence diagram shows how the search operation works:
Implementation of ClientContainsKeywordPredicate
ClientContainsKeywordPredicate implements Predicate<Client> and allow filtering of a list of Client based on
generic and attribute keywords.ClientContainsKeywordPredicate contains an ArgumentMultiMap which holds these
keywords. The preamble string of the ArgumentMultiMap corresponds to generic keywords. All the words in that string
will be used to match with all the attributes of the Client. The different values String that is mapped to the
different Prefix corresponds to attribute keywords. Each of these values string will then be matched with the
corresponding Client’s attribute that their Prefix refers to e.g. if the Prefix e/ was mapped to @gmail.com,
then @gmail.com will be used to matched with the Email attribute of the Client. For this predicate to return true,
the given Client must match with any of the generic keywords if there is any and all the attribute keywords if there
is any.
4.4 Filter Clients
Description
LeadsForce allows the user to filter for clients using keywords. This works similar to the search but it allows
for multiple filter to be stacked, which allows for user to look for clients incrementally.
Implementation
- The
LogicManagerstarts to parse the given input text usingAddressBookParser - The
AddressBookParserinvokes the respectiveParserbased on the first word of the input text. - The remaining input text will be passed to the
FilterCommandParserto parse. - The
FilterCommandParserwill tokenize the remaining input text using theArgumentTokenizerinto anArgumentMultiMap. - The
FilterCommandParserwill then create a newClientContainsKeywordPredicateusing theArgumentMultiMap. - The
FilterCommandParserwill then create aFilterCommandwith theClientContainsKeywordPredicate - The
LogicMangerwill call theexecutemethod ofFilterCommand. - The
FilterCommandwil then call thefilterFilteredClientListmethod of the providedModelwith it’sClientContainsKeywordPredicate. - The
FilterCommandwill finally create a newCommandResultwhich will be returned toLogicManager.
The following sequence diagram shows how the filter operation works:
Implementation of ClientContainsKeywordPredicate
See the above description in Search Clients.
4.5 Sort Clients
Description
LeadsForce allows the user to sort clients according to client fields. LeadsForce give clients the option to sort it in ascending or descending order.
Implementation
- The
LogicManagerstarts to parse the given input text usingAddressBookParser - The
AddressBookParserinvokes the respectiveParserbased on the first word of the input text. - The remaining input text will be passed to the
SortCommandParserto parse. - The
SortCommandParserwill tokenize the remaining input text using theArgumentTokenizerinto anArgumentMultiMap. - The
SortCommandParserwill then create a newSortByAttributebased off the parsed field with the correspondingSortDirectionusing theArgumentMultiMap. - The
SortCommandParserwill then create aSortCommandwith theSortByAttribute - The
LogicMangerwill call the execute method ofSortCommand. - The
SortCommandwil then call thesortFilteredClientListmethod of the providedModelwith it’sSortByAttribute. - The
SortCommandwill finally create a newCommandResultwhich will be returned toLogicManager.
The following sequence diagram shows how the sort operation works:
4.6 Multiple Address Book
LeadsForce allow the user to create and switch between multiple addressbook.
Description
LeadsForce allow the user to create and switch between multiple addressbook.
Implementation
Each individual addressbook is stored as its own JSON file in the data folder that the LeadsForce jar file is stored in. The following implementation will omit the details prior to the respective commands’ parser. Also, details with regard to AddressBookList has been omitted for simplicity if it is not critical to the function of the command.
4.6.1 Create new Address Book
- The
AbCreateCommandParserparse the name of the address book that is to be created into aPathto that new address book. - The
AbCreateCommandParserwill then create a newAbCreateCommandwith the parsedPath. - The
LogicMangerthen call the execute method ofAbCreateCommandwhich set the address bookPathand create a newCommandResultwith theSpecialCommandResulttype ofCREATE_ADDRESSBOOK. - The
MainWindowwill then call its handleCreateAddressBook method after checking that theCommandResultis of typeCREATE_ADDRESSBOOKwhich will call the createAddressBook method ofLogicManager. - The
LogicMangerwill retrieve thePathof the new address book and create a newAddressBookStoragewith it and along with a newAddressBook. - The
LogicMangerthen call setAddressBook method ofModelManagerwith the newAddressBookwhich will reset theAddressBookto a newAddressBook. - The
LogicMangerwill also call switchAddressBook method ofStorageManagerwith the newAddressBookStorage.
The following sequence diagram shows how the ab create operation works:
4.6.2 Switch Address Book
- The
AbSwitchCommandParserparse the name of the address book that is to be switched to into aPathto that address book. - The
AbSwitchCommandParserwill then create a newAbSwitchCommandwith the parsedPath. - The
LogicMangerthen call the execute method ofAbSwitchCommandwhich set the address bookPathand create a newCommandResultwith theSpecialCommandResulttype ofSWITCH_ADDRESSBOOK. - The
MainWindowwill then call its handleSwitchAddressBook method after checking that theCommandResultis of typeSWITCH_ADDRESSBOOKwhich will call the switchAddressBook method ofLogicManager. - The
LogicMangerwill retrieve thePathof the address book to switched to and create a newAddressBookStoragewith it - The
LogicMangerwill also call readAddressBook method ofJsonAddressBookStoragewith thePathto get theAddressBookthat is to be switched to. - The
LogicMangerthen call setAddressBook method ofModelManagerwith theAddressBookwhich will reset the currentAddressBookto that. - The
LogicMangerwill also call switchAddressBook method ofStorageManagerwith the newAddressBookStorage.
The following sequence diagram shows how the sort operation works:
4.6.3 Delete Address Book
- The
AbDeleteCommandParserparse the name of the address book that is to be deleted to into aPathto that address book. - The
AbDeleteCommandParserwill then create a newAbDeleteCommandwith the parsedPath. - The
LogicMangerthen call the execute method ofAbDeleteCommand. - The
AbDeleteCommandwill then attempt to delete the address book specified by thePath - The
AbDeleteCommandwill finally create a newCommandResultwhich will be returned toLogicManger.
The following sequence diagram shows how the sort operation works:
4.6.4 List Address Book
- The
AbListCommandwill call getAddressBookListString method ofModelManager. - The
ModelManagerwill then subsequently call toString method ofAddressBookList - The
AddressBookListwill append the name of all the addressbook in its list together and return it back toAblistCommand - The
AblistCommandwill finally then create aCommandResultwith that String and return it toLogicManager.
The following sequence diagram shows how the sort operation works:
4.7 GUI Feature
We will use this section to document implementation details regarding GUI-related features.
4.7.1 Filter tag panel
Filter tag panel involves the use of a listener to watch for any changes in the UniqueTagList. Once a change
is detected, it will update the UI accordingly. The tricky part is to get UniqueTagList to work with the TagPanel
listener. We also have to constantly monitor the “reference states” of Tag items in the UniqueTagList so that tags panel automatically removes
tags that are no longer referenced by any clients. For this, some form of garbage collection mechanism must exist.
Below, we will see how creating and modifying the client have an effect on the UniqueTagList. Client modification can be
seen as the entry point that triggers the chain of tag modification operations and thus the UI update of the TagPanel.
4.7.1.1 Add a new client
The following activity diagram summarizes what happens when a user executes an add command:
Doubly link client and tags
Doubly linking client and tags allows us to monitor the “reference states” of the tags without iterating through the UniqueClientList. “Reference state” here refers to the state of being referenced as well as how many clients are currently “referencing” the tags.
4.7.1.2 Edit a client
The following activity diagram summarizes what happens when a user executes an edit command:
How unreferenced tags are “garbage collected”?
The garbage collection of unreferenced tags takes place whenever the AddressBook listener detects an update event in the UniqueClientList.
The garbage collector will iterate through the UniqueTagList and remove all Tag objects that are not referenced by any clients. The design choice of doubly linking the tag and client further help facilitate this process since the “reference state” of the Tag has become easily available as a result.
4.7.1.3 Delete a client
The following activity diagram summarizes what happens when a user executes a delete command:
Remove vs “Delete”
You might notice that there is an interchanging of the words Remove and Delete which seem to suggest the same thing. However, they do have some slight difference in connotations.
- Remove: removal of
ClientfromUniqueClientList. - Delete: removal of all lingering references that this
Clienthas.
The “Delete” operation should be invoked everytime you remove a Client from the UniqueClientList to ensure the correctness of the “reference state” of Tag.
This is because removal of a Client from the UniqueClientList connotes that the Client is no longer present, hence it is important to ensure that any lingering references including association with any previously associated Tag objects are cut.
5. Documentation, logging, testing, configuration, dev-ops
5.1 Extensions and customisations
In LeadsForce, we put a strong emphasis on ensuring not only the quality but also the extensibility and customizability of our product. If you are wondering about how you can easily customise or add extensions to LeadsForce without worrying about the underlying implementations, you are at the right place. This section details the workflows and features that we have developed that can help you tweak certain features in LeadsForce without the need for you to delve too deeply into the codebase.
5.1.1 Change the look of an existing theme
Let’s say you dislike the look of our current BookTheme: you want the background to be dark brown instead of the current light brown.
Here’s what you should do:
- cd to
tp/src/main/resources/view. - Open
BookTheme.css. - On the top of the css file, you will see that all the css variables are nicely organised and defined for you.
- Let’s change the value of
-fx-base-1to#5C4033instead (the color code for dark brown). - Save the file and boot up LeadsForce. You will see that the change in the background color of
BookThemeis reflected immediately.
5.1.1.1 Summary of the functions of CSS variables:
| CSS Variable | Description | Default (in BookTheme) |
|---|---|---|
| -fx-base1 | Base color 1 • Preferably the darkest tone. • Used as the main background color of LeadsForce. |
#cb997e |
| -fx-base2 | Base color 2 | #eddcd2 |
| -fx-base3 | Base color 3 | #fff1e6 |
| -fx-base4 | Base color 4 | #f0efeb |
| -fx-base5 | Base color 5 • Preferably the lightest tone. |
#ddbea9 |
| -fx-font-color | The color of a generic font in LeadsForce | derive(-fx-base1, -30%) |
| -fx-font-color-bright | The color of a “bright” font in LeadsForce • “Bright” fonts overlay components of base color 1. |
#ffffff |
| -fx-menu-color | Color of the menu | #263238 |
| -fx-menu-color-highlighted | Color of the menu when highlighted | #455a64 |
| -fx-menu-font-color | Color of the menu font | #ffffff |
| -fx-menu-font-color-highlighted | Color of the menu font when highlighted | #ffffff |
5.1.2 Give LeadsForce a new theme
If you want to add more themes on top of our existing themes, here’s what you should do:
- cd to
tp/src/main/resources/view. - Create a copy of
BookTheme.css. - Rename the file to you preferred theme name and open it. e.g.
RainbowTheme.css. - Similar to 5.1.1, tweak the css variables to suit your needs.
- Save the file and cd to
tp/src/main/java/seedu/address/storage/ThemeList.java. - Add
RainbowTheme.cssto the static variableTHEMESlike so:
List.of(..., "RainbowTheme"); - Now boot up LeadsForce and you should see that your newly added theme is available in the menu bar. Hooray!
6. Appendix: Requirements
6.1 Product scope
Target user: Student Financial Advisor
Target user profile:
- Studying in university currently
- Prefers using desktop applications, over others
- Would much prefer to type, and can type fast
- Manages a significant number of contacts
- Short on time as they have to juggle both school and work at the same time
- Trying to sell financial products effectively by finding the right clients
Value propositions:
- Keep tracks of client information and meetings all in one place
- Much faster than a mouse driven GUI app
- Financial advisors can have a more targeted approach by categorising different clients
6.2 User stories
Priorities: High (must have) - * * *, Medium (nice to have) - * *, Low (unlikely to have) - *
| Priority | As a … | I can … | So that I can… |
|---|---|---|---|
* * * |
student financial advisor | add in my client’s information | refer to my client’s information later on |
* * * |
student financial advisor | remove a client from my catalogue of clients | remove clients who I no longer keep in touch with |
* * * |
student financial advisor | view my client’s information | view in-depth information on the client which can allow me to better strategies the appropriate plan |
* * * |
student financial advisor | categorise my clients | have a more targeted approach when approaching clients with new financial plans |
* * * |
student financial advisor | list out all my clients | have an overview of the clients I have |
* * * |
student financial advisor who is meeting with a client soon | lookup a client in the address book | strategies several plans that would be appropriate for my clients based on the client’s financial information |
* * * |
student financial advisor that forgot the client’s name | search for a client by their information | be able to greet the client when we meet |
* * * |
student financial advisor | save my address book locally | access the information again when I reopen the application |
* * * |
student financial advisor | see hints in error messages when I input a wrong command | know how to rectify my command |
* * * |
student financial advisor | be warned that I am about to add the same user again | avoid having duplicate clients in my catalogue of clients |
* * * |
student financial advisor | set meetings with my clients | keep track and not be late to my meetings with my clients |
* * * |
student financial advisor who’s client has changed client information | edit my client’s information | keep track of my client’s information |
* * * |
student financial advisor who is planning to attend an event | get an overview of my meeting schedule on the day | ensure that I can still attend my meetings with clients |
* * |
student financial advisor trying to sell a particular financial plan | search for clients with a certain amount of financial appetite | suggest the plans to the appropriate clients |
* * |
student financial advisor | sort clients in my catalogue of clients | quickly identify the clients based on the last time I’ve seen them or the number of financial plans they have |
* |
student financial advisor who has gotten a new laptop | transfer my clients’ information into another computer | transfer my clients’ information onto my new laptop |
6.3 Use cases
(For all use cases below, the System is the LeadsForce and the Actor is the user, unless specified otherwise)
6.3.1 UC01 Add a client to the client list
MSS
- User adds a client into the contact book
- LeadsForce adds the client to the contact book
Use case ends.
Extensions
-
1a. Missing parameters - name and email
- 1a1. LeadsForce shows an invalid command error message.
Use case ends.
- 1a1. LeadsForce shows an invalid command error message.
6.3.2 UC02 View a client’s information
MSS
- User requests to view the client’s information.
- LeadsForce shows the detailed view of the client’s information.
Use case ends.
Extensions
- 2a. User inputs an invalid Client ID
- 2a1. LeadsForce shows an invalid command error to user.
Use case ends.
- 2a1. LeadsForce shows an invalid command error to user.
6.3.3 UC03 Edit client information
MSS
- User request to edit multiple attributes of a client.
- LeadsForce updates the client’s information.
- User UC02 Views a client’s information to see that the information of the client have been changed.
Use case ends.
Extensions
- 1a. User inputs invalid attributes
- 1a1. LeadsForce shows an error to user, and informs the user of the valid attribute format.
Use case ends.
- 1a1. LeadsForce shows an error to user, and informs the user of the valid attribute format.
6.3.4 UC04 Delete a client
MSS
- User requests to list clients.
- LeadsForce shows a list of clients.
- User requests to delete a specific client by their Client ID.
- LeadsForce deletes the client.
Use case ends.
Extensions
-
2a. The list is empty.
Use case ends. -
3a. The given client id is invalid.
- 3a1. LeadsForce shows an error message, informing the user that there is no client with the given Client ID.
Use case resumes at step 2.
- 3a1. LeadsForce shows an error message, informing the user that there is no client with the given Client ID.
6.3.5 UC05 Showcases list of clients
MSS
- User request to view the full list of clients.
- LeadsForce showcases the client’s information.
Use case ends.
6.3.6 UC06 Search for a client
MSS
- User requests to list clients.
- LeadsForce shows a list of clients.
- User requests to search using specific keywords.
- LeadsForce shows the list of all people which match the keyword.
Use case ends.
Extensions
-
2a. LeadsForce returns an empty list since there is no clients in the list.
Use case ends. -
3a. LeadsForce returns an empty list since there is no client who fits the inputted keyword.
Use case ends.
6.3.7 UC07 Setting a meeting with clients
MSS
- User requests to set a meeting with the client
- LeadsForce updates the client’s next meeting portion to show the meeting that was inputted.
Use case ends.
Extensions
- 1a. User inputs invalid commands
- 1a1. LeadsForce shows an error to user, and informs the user of the valid command format.
Use case ends.
- 1a1. LeadsForce shows an error to user, and informs the user of the valid command format.
6.3.8 UC08 Showing schedule for the day
MSS
- User requests to see the schedule of meetings on a particular day.
- LeadsForce shows a schedule of meetings on the day.
Use case ends.
Extensions
- 1a. User inputs an invalid date
- 1a1. LeadsForce shows an invalid command error to user.
Use case ends.
- 1a1. LeadsForce shows an invalid command error to user.
- 2a. The meeting schedule is empty as the user has no meetings on the day.
Use case ends.
6.3.9 UC09 Clearing a client list
MSS
- User requests to clear the client list.
- LeadsForce asks for the user’s validation (asking if the user is very sure in deleting clients’ information).
- User validates the request.
- LeadsForce shows address book with no clients.
Use case ends.
Extensions
- 3a. User does not validate the request
- 3a1. LeadsForce does not clear the client list.
Use case ends.
- 3a1. LeadsForce does not clear the client list.
- 3b. User inputs invalid commands
- 3b1. LeadsForce shows an error to user, and informs the user of the valid commands.
Use case resumes at step 3.
- 3b1. LeadsForce shows an error to user, and informs the user of the valid commands.
6.3.10 UC10 Create a new address book
MSS
- User requests to create another address book with a specified name.
- LeadsForce shows view of the new address book.
Use case ends.
Extensions
- 1a. User inputs name that is the same as an existing address book
- 1a1. LeadsForce shows an error to user, and informs the user that an address book with the same name already exists.
Use case ends.
- 1a1. LeadsForce shows an error to user, and informs the user that an address book with the same name already exists.
6.3.11 UC11 Clear an address book of clients
MSS
- User requests to clear the address book.
- LeadsForce asks for the user’s validation (asking if the user is very sure in deleting clients’ information).
- User validates the request.
- LeadsForce shows address book with no clients.
Use case ends.
Extensions
- 3a. User does not validate the request
- 3a1. LeadsForce does not clear the address book.
Use case ends.
- 3a1. LeadsForce does not clear the address book.
- 3a. User inputs invalid commands
- 3b1. LeadsForce shows an error to user, and informs the user of the valid commands.
Use case resumes at step 3.
- 3b1. LeadsForce shows an error to user, and informs the user of the valid commands.
6.4 Non-Functional Requirements
- Should work on any mainstream OS as long as it has Java
11or above installed. - Should be able to hold up to 100 clients 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.
- The system should respond within two seconds after entering a command.
- Should work without requiring an installer.
- Should work on a 64-bit environment.
- Should be usable by a student who has little to no experience in using computers.
- The client information should be stored locally.
- Students who are inexperienced in using computers should be able to easily use LeadsForce.
6.5 Glossary
- Mainstream OS: Windows, Linux, Unix, OS-X
- Command Line Interface (CLI): Text-based user interface that is used to view and manage device files
- Graphical User Interface (GUI): A visual way of interacting with a device using a variety of items
- Leads: refers to contact with a potential customer, also known as a “prospect”
- Risk Appetite: level of risk that a lead is prepared to accept in pursuit of his/her objectives, before action is deemed necessary to reduce the risk
- Disposable Income: total clientele income minus clientele current taxes
- Client list: the list of clients that is displayed in the GUI
- Address Book: the list of clients where all clients inserted are kept
7. Appendix: Instructions for manual testing
Given below are instructions to test the app manually.
7.1 Launch and shutdown
-
Initial launch
-
Download the jar file and copy into an empty folder
-
Double-click the jar file Expected: Shows the GUI with a set of sample 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.
-
-
shut down the application by using the
exitcommand.
7.2 Commands for manual testing (Client Management Features)
In this section, you can test general commands in LeadsForce. Below is a summary of every client management feature in LeadsForce.
| Action | Format | Examples |
|---|---|---|
| Create | add n/CLIENT_NAME e/EMAIL [<attribute>/VALUE]... |
add n/benedict e/benedict@gmail.com p/90909898 r/3 |
| View | view CLIENT_ID |
view 123 |
| Edit | edit CLIENT_ID... [<attribute>/CHANGED_VALUE]... |
edit 12 n/Dominic p/12345678 |
| Delete | delete CLIENT_ID... |
delete 4 |
| List | list |
- |
| Sort | sort [<attribute>/SORT_DIRECTION]... |
sort r/asc |
| Schedule | schedule [DATE] |
schedule 25-12-2021 |
| Search | search KEYWORD... [<attribute>/ATTRIBUTE_KEYWORD]... |
search e/doe@gmail.com r/5 |
| Filter | filter KEYWORD[... <attribute>/ATTRIBUTE_KEYWORD]... |
filter e/doe@gmail.com p/9 |
| Clear | clear |
- |
7.2.1 Adding a client
-
Adding a client to the client list
-
Prerequisites: in using the
addcommand, the user must input the client’s email and name. -
Test case:
add n/Dominic e/dominicLovesCS@gmail.com
Expected: A new client namedDominicwith the email addressdominicLovesCS@gmail.comis added to the client list -
Test case:
add n/Dominic p/97263912
Expected: No client is added to the client list since email is not included. Invalid command error is shown to the user in the status message. -
Other incorrect delete commands to try:
add n/Dominic i/6(user is not allowed to give clients a Client ID) Expected: Similar to previous.
-
7.2.2 View a client
-
View the client’s information in the side panel’s client view panel.
-
Prerequisites: a client with the corresponding Client ID must exist in the client list
-
Test case:
view 1(supposing there is a client with client id 1)
Expected: Client with Client ID1is shown in the client view panel. Details of the command is shown in the status message. -
Test case:
view
Expected: No client is being selected to be viewed. Invalid command error is shown to the user in the status message. -
Other incorrect delete commands to try:
view 999(when the client id 999 does not exist)
Expected: Similar to previous.
-
7.2.3 Deleting a client
-
Deleting a client while all clients are being shown
-
Prerequisites: List all clients using the
listcommand. Multiple clients in the list. -
Test case:
delete 0
Expected: Client with Client ID0is deleted from the client list. Details of the deleted contact shown in the status message. -
Test case:
delete 999
Expected: No client is deleted since there is no client with client id999. Error details shown in the status message. Status bar remains the same. -
Other incorrect delete commands to try:
delete,delete x
Expected: Similar to previous.
-
7.2.4 Edit clients information
-
Editing a client’s information
-
Prerequisites: Users are not allowed to change the client id of the client.
-
Test case:
edit 1 n/Benedict
Expected: Client with Client ID1has the name changed toBenedict. Details of this change is shown in the status message. -
Test case:
edit 1 2 3 4 5 n/Benedict
Expected: Client with Client ID1,2,3,4have their name changed toBenedict. Details of this change is shown in the status message. -
Test case:
edit 1 n/Benedict e/rebeccalovescs@gmail.com
Expected: Client with Client ID1has the name changed toBenedict, and the email changed torebeccalovescs@gmail.com. Details of this change is shown in the status message. -
Test case:
edit 1 2 3 4 m/23-11-2021 (09:00~10:00), NUS SOC COM1
Expected: Client with Client ID1,2,3,4have their next meeting changed to the23rd November 2021from9am to 10amatNUS SOC COM1. Details of this change is shown in the status message. -
Test case:
edit 1 i/9
Expected: The client’s id will not be changed and error details are shown in the status message. Client list remains the same. -
Other incorrect delete commands to try:
delete,delete x,...(where x is larger than the list size)
Expected: Similar to previous.
-
7.2.5 Sort clients
-
Sorts the lists of clients
-
Prerequisites: the client list is not empty when the command is used
-
Test case:
sort r/asc
Expected: Sort the current based on their risk appetite in ascending order. Details of the sort is shown in the status message. -
Test case:
sort r/dsc d/asc
Expected: sorts clients by their risk appetite in descending order, then sorts the clients by their disposable income in ascending order for those who have the same risk appetite. Details of the sort is shown in the status message. -
Test case:
sort r/descending
Expected: The client list will not be sorted and error details are shown in the status message. Details of the command will be shown in the status message. -
Other incorrect delete commands to try:
sort,sort r8
Expected: Similar to previous.
-
7.2.6 Finding meeting schedule on day
-
Find meetings that are scheduled on a specified day
-
Prerequisites: User must have meetings on the day which is specified in the command.
-
Test case:
schedule 25-11-2021
Expected: Meetings that are schedule on the25th November 2021are shown in the meeting schedule panel. Details of the command is shown in the status message. -
Test case:
schedule
Expected: Returns the full list of meetings that are scheduled. Details of the command is shown in the status message. -
Test case:
schedule 2021-30-21
Expected: Meeting schedule remains unchanged. Error details shown in the status message and informs user that the format is incorrect. -
Other incorrect delete commands to try:
schedule 31-13-2021,schedule 32-12-2021
Expected: Similar to previous.
-
7.2.7 Filter Client List
-
Filter client list based on a given attribute
-
Prerequisites: there must be clients in the current client list.
-
Test case:
filter Dominic
Expected: Clients with the wordDominicin any of the client’s attributes will be shown in the client list. Details of the command is shown in the status message. -
Test case:
filter r/1
Expected: Clients with the risk appetite1will be shown in the client list. Details of the command is shown in the status message. -
Test case:
filter Dominic r/1
Expected: Clients withDominicin any of its attributes and risk appetite of1will be shown on the client list. Details of the command is shown in the status message. -
Test case:
filter
Expected: The client list remains unchanged. Error details shown in the status message and informs user of the correct format.
-
7.2.8 Searching for clients
-
Search for a client based on a given attribute
-
Prerequisites: there must be clients in your address book.
-
Test case:
search Dominic
Expected: Clients with the wordDominicin any of the client’s attributes will be shown in the client list, regardless if the user was on the client list initially. Details of the command is shown in the status message. -
Test case:
search r/1
Expected: Clients with the risk appetite1will be shown in the client list, regardless if the user was on the client list initially. Details of the command is shown in the status message. -
Test case:
search Dominic r/1
Expected: Clients withDominicin any of its attributes and risk appetite of1will be shown on the client list, regardless if the user was on the client list initially. Details of the command is shown in the status message. -
Test case:
search
Expected: The client list remains unchanged. Error details shown in the status message and informs user of the correct format.
-
7.2.9 Show all clients
- List all clients
- Test case:
list
Expected: Client list will contain all clients in the address book. Details of the command is shown in the status message.
- Test case:
7.2.10 Clear address book
- Clear all clients in address book
-
Test case:
clear, and thenyeswhen prompted by Are you sure that you wish to clear the Address Book Expected: Clients in the client list will be cleared and the client list and address book will be empty. Details of the command is shown in the status message. -
Test case:
clear, and thennowhen prompted by Are you sure that you wish to clear the Address Book Expected: Clients in the client list will not be cleared and the client list and address book will remain the same. Details of the command is shown in the status message.
-
7.2.11 General commands
| Action | Format |
|---|---|
| Help | help |
| Exit | exit |
Help command
- Getting help information
- Test case:
help
Expected: A window with a link to LeadsForce’s user guide
- Test case:
Exit command
- Exit the application
- Test case:
exit
Expected: the application closes
- Test case:
7.3 Commands for manual testing (Multiple address book feature)
In this section, you can test multiple address book features in LeadsForce. Below is a summary of all multiple address book features in LeadsForce.
| Action | Format | Examples |
|---|---|---|
| Create Address Book | ab create ADDRESSBOOK_NAME |
ab create vip |
| Delete Address Book | ab delete ADDRESSBOOK_NAME |
ab delete book |
| Switch Address Book | ab switch ADDRESSBOOK_NAME |
ab switch another |
| List Address Book | ab list |
- |
7.3.1 Create Address Book
-
Create Address Book
-
Prerequisites: -
-
Test case:
ab create Young Adult
Expected: Creates a new address book with the nameyoung adult. Details of the command is shown in the status message. -
Test case:
ab create Addressbook
Expected: Does not create a new address book and error details are shown in the status message, informing the user that the address book name already exists. -
Test case:
ab create
Expected: Does not create a new address book and error details are shown in the status message, informing the user of a valid command format.
-
7.3.2 Delete Address Book
-
Delete Address Book
-
Prerequisites: the user has to be using a different address book to delete another address book
-
Test case:
ab delete Young Adult
Expected: Deletes an address book with the nameyoung adult. Details of the command is shown in the status message. -
Test case:
ab delete
Expected: Does not delete a new address book and error details are shown in the status message, informing the user of a valid command format.
-
7.3.3 Switch Address Book
-
Switch between Address Book
-
Prerequisites: have at least 2 address books
-
Test case:
ab switch Young Adult
Expected: Switch to theYoung Adultaddress book. Details of the command is shown in the status message.
-
7.3.4 List Address Books
-
List the names of all address books
-
Prerequisites: -
-
Test case:
ab list
Expected: Lists the name of all address books. Details of the command is shown in the status message.
-
7.4 Saving data
-
Dealing with missing/corrupted data files
- The data files can be found in the
datafolder of the repository, and are named accordingly to the name of the address books in your application (For instance, if you have an address book that’s calledYoung Adults, there will be a JSON file calledYoung Adults.jsonin the data folder). Remove theclientIdfor one of the clients in the corrupted data file, and restart the application
Expected: LeadsForce should display an empty client list for the address book with the same name as the corrupted data file.
- The data files can be found in the