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
interface
with the same name as the Component. - implements its functionality using a concrete
{Component Name}Manager
class (which follows the corresponding APIinterface
mentioned in the previous point)
For example, the Logic
component defines its API in the Logic.java
interface and implements its functionality using the LogicManager.java
class which follows the Logic
interface.
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
Logic
component. - listens for changes to
Model
data so that the UI can be updated with the modified data. - keeps a reference to the
Logic
component, because theUI
relies on theLogic
to execute commands. - depends on some classes in the
Model
component, as it displaysClient
object 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
Logic
is called upon to execute a command, it uses theAddressBookParser
class to parse the user command. - This results in a
Command
object (more precisely, an object of one of its subclasses e.g.,AddCommand
) which is executed by theLogicManager
. - The command can communicate with the
Model
when it is executed (e.g. to add a client). - The result of the command execution is encapsulated as a
CommandResult
object 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
AddressBookParser
class creates anXYZCommandParser
(XYZ
is a placeholder for the specific command name e.g.,AddCommandParser
) which uses the other classes shown above to parse the user command and create aXYZCommand
object (e.g.,AddCommand
) which theAddressBookParser
returns back as aCommand
object. - All
XYZCommandParser
classes (e.g.,AddCommandParser
,DeleteCommandParser
, …) inherit from theParser
interface so that they can be treated similarly where possible e.g, during testing.
3.4 Model component
API : Model.java
The Model
component,
- stores the address book data i.e., all
Client
objects (which are contained in aUniqueClientList
object). - has a
UniqueNextMeetingList
inAddressBook
, which contains allNextMeeting
objects belonging to allClient
objects in theUniqueClientList
object. - has a
UniqueTagList
inAddressBook
, which containsTag
(s) that aClient
can reference. This allowsAddressBook
to only require oneTag
object per unique tag. - stores the currently ‘selected’
Client
objects (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 theClient
object to display inClientListPanel
andClientViewPanel
- this
- stores all
NextMeeting
objects belonging to allClient
objects 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 theNextMeeting
object to display inNextMeetingCard
inMeetingsListPanel
- this
- stores a
UserPref
object that represents the user’s preferences. This is exposed to the outside as aReadOnlyUserPref
objects. - does not depend on any of the other three components (as the
Model
represents data entities of the domain, they should make sense on their own without depending on other components)
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
AddressBookStorage
andUserPrefStorage
, which means it can be treated as either one (if only the functionality of only one is needed). - depends on some classes in the
Model
component (because theStorage
component’s job is to save/retrieve objects that belong to theModel
)
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
LogicManager
starts to parse the given input text usingAddressBookParser
. - The
AddressBookParser
invokes the respectiveParser
based on the first word of the input text. - The remaining input text will be passed to the
ViewCommandParser
to parse. - The
ViewCommandParser
will parse theClientId
from the remaining input text. In our implementation, a validClientId
is any non-negative integer. - The
ViewCommandParser
will then create a newClientHasId
using theClientId
parsed. - The
ViewCommandParser
will then create aViewCommand
with theClientId
andClientHasId
. - The
LogicManger
will call theexecute
method ofViewCommand
. - The
ViewCommand
wil then call theupdateClientToView
method of the providedModel
with it’sClientHasId
. - The
ViewCommand
will finally create a newCommandResult
which will be returned toLogicManager
and the client’s information with the givenClientId
in 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
LogicManager
starts to parse the given input text usingAddressBookParser
. - The
AddressBookParser
invokes the respectiveParser
based on the first word of the input text. - The remaining input text will be passed to the
EditCommandParser
to parse. - The
EditCommandParser
will tokenize the remaining input text using theArgumentTokenizer
into anArgumentMultiMap
. - The
EditCommandParser
will then create a newclientId
which contains the list of client Ids. - The
EditCommandParser
will then create a newEditClientDescriptor
which contains the fields that the user is intending on editing. - The
EditCommandParser
will create aEditCommand
containing both the list of client Ids and theEditClientDescriptor
. - The
LogicManger
will call theexecute
method of the aforementionedEditCommand
. - The
EditCommand
will then call thesetAllClients
method of the providedModel
with theEditClientDescriptor
and the list of clients. - The
EditCommand
will then call theupdateFilteredClientList
method of the providedModel
with a predicate to show all clients in the client list. - The
EditCommand
will finally create a newCommandResult
which will be returned toLogicManager
and 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
LogicManager
starts to parse the given input text usingAddressBookParser
. - The
AddressBookParser
invokes the respectiveParser
based on the first word of the input text. - The remaining input text will be passed to the
SearchCommandParser
to parse. - The
SearchCommandParser
will tokenize the remaining input text using theArgumentTokenizer
into anArgumentMultiMap
. - The
SearchCommandParser
will then create a newClientContainsKeywordPredicate
using theArgumentMultiMap
. - The
SearchCommandParser
will then create aSearchCommand
with theClientContainsKeywordPredicate
. - The
LogicManger
will call theexecute
method ofSearchCommand
. - The
SearchCommand
wil then call theupdateFilteredClientList
method of the providedModel
with it’sClientContainsKeywordPredicate
. - The
SearchCommand
will finally create a newCommandResult
which 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
LogicManager
starts to parse the given input text usingAddressBookParser
- The
AddressBookParser
invokes the respectiveParser
based on the first word of the input text. - The remaining input text will be passed to the
FilterCommandParser
to parse. - The
FilterCommandParser
will tokenize the remaining input text using theArgumentTokenizer
into anArgumentMultiMap
. - The
FilterCommandParser
will then create a newClientContainsKeywordPredicate
using theArgumentMultiMap
. - The
FilterCommandParser
will then create aFilterCommand
with theClientContainsKeywordPredicate
- The
LogicManger
will call theexecute
method ofFilterCommand
. - The
FilterCommand
wil then call thefilterFilteredClientList
method of the providedModel
with it’sClientContainsKeywordPredicate
. - The
FilterCommand
will finally create a newCommandResult
which 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
LogicManager
starts to parse the given input text usingAddressBookParser
- The
AddressBookParser
invokes the respectiveParser
based on the first word of the input text. - The remaining input text will be passed to the
SortCommandParser
to parse. - The
SortCommandParser
will tokenize the remaining input text using theArgumentTokenizer
into anArgumentMultiMap
. - The
SortCommandParser
will then create a newSortByAttribute
based off the parsed field with the correspondingSortDirection
using theArgumentMultiMap
. - The
SortCommandParser
will then create aSortCommand
with theSortByAttribute
- The
LogicManger
will call the execute method ofSortCommand
. - The
SortCommand
wil then call thesortFilteredClientList
method of the providedModel
with it’sSortByAttribute
. - The
SortCommand
will finally create a newCommandResult
which 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
AbCreateCommandParser
parse the name of the address book that is to be created into aPath
to that new address book. - The
AbCreateCommandParser
will then create a newAbCreateCommand
with the parsedPath
. - The
LogicManger
then call the execute method ofAbCreateCommand
which set the address bookPath
and create a newCommandResult
with theSpecialCommandResult
type ofCREATE_ADDRESSBOOK
. - The
MainWindow
will then call its handleCreateAddressBook method after checking that theCommandResult
is of typeCREATE_ADDRESSBOOK
which will call the createAddressBook method ofLogicManager
. - The
LogicManger
will retrieve thePath
of the new address book and create a newAddressBookStorage
with it and along with a newAddressBook
. - The
LogicManger
then call setAddressBook method ofModelManager
with the newAddressBook
which will reset theAddressBook
to a newAddressBook
. - The
LogicManger
will also call switchAddressBook method ofStorageManager
with the newAddressBookStorage
.
The following sequence diagram shows how the ab create operation works:
4.6.2 Switch Address Book
- The
AbSwitchCommandParser
parse the name of the address book that is to be switched to into aPath
to that address book. - The
AbSwitchCommandParser
will then create a newAbSwitchCommand
with the parsedPath
. - The
LogicManger
then call the execute method ofAbSwitchCommand
which set the address bookPath
and create a newCommandResult
with theSpecialCommandResult
type ofSWITCH_ADDRESSBOOK
. - The
MainWindow
will then call its handleSwitchAddressBook method after checking that theCommandResult
is of typeSWITCH_ADDRESSBOOK
which will call the switchAddressBook method ofLogicManager
. - The
LogicManger
will retrieve thePath
of the address book to switched to and create a newAddressBookStorage
with it - The
LogicManger
will also call readAddressBook method ofJsonAddressBookStorage
with thePath
to get theAddressBook
that is to be switched to. - The
LogicManger
then call setAddressBook method ofModelManager
with theAddressBook
which will reset the currentAddressBook
to that. - The
LogicManger
will also call switchAddressBook method ofStorageManager
with the newAddressBookStorage
.
The following sequence diagram shows how the sort operation works:
4.6.3 Delete Address Book
- The
AbDeleteCommandParser
parse the name of the address book that is to be deleted to into aPath
to that address book. - The
AbDeleteCommandParser
will then create a newAbDeleteCommand
with the parsedPath
. - The
LogicManger
then call the execute method ofAbDeleteCommand
. - The
AbDeleteCommand
will then attempt to delete the address book specified by thePath
- The
AbDeleteCommand
will finally create a newCommandResult
which will be returned toLogicManger
.
The following sequence diagram shows how the sort operation works:
4.6.4 List Address Book
- The
AbListCommand
will call getAddressBookListString method ofModelManager
. - The
ModelManager
will then subsequently call toString method ofAddressBookList
- The
AddressBookList
will append the name of all the addressbook in its list together and return it back toAblistCommand
- The
AblistCommand
will finally then create aCommandResult
with 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
Client
fromUniqueClientList
. - Delete: removal of all lingering references that this
Client
has.
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-1
to#5C4033
instead (the color code for dark brown). - Save the file and boot up LeadsForce. You will see that the change in the background color of
BookTheme
is 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.css
to the static variableTHEMES
like 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
11
or 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
exit
command.
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
add
command, the user must input the client’s email and name. -
Test case:
add n/Dominic e/dominicLovesCS@gmail.com
Expected: A new client namedDominic
with the email addressdominicLovesCS@gmail.com
is 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 ID1
is 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
list
command. Multiple clients in the list. -
Test case:
delete 0
Expected: Client with Client ID0
is 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 ID1
has 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
,4
have 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 ID1
has 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
,4
have their next meeting changed to the23rd November 2021
from9am to 10am
atNUS 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 2021
are 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 wordDominic
in 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 appetite1
will be shown in the client list. Details of the command is shown in the status message. -
Test case:
filter Dominic r/1
Expected: Clients withDominic
in any of its attributes and risk appetite of1
will 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 wordDominic
in 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 appetite1
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 Dominic r/1
Expected: Clients withDominic
in any of its attributes and risk appetite of1
will 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 thenyes
when 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 thenno
when 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 Adult
address 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
data
folder 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.json
in the data folder). Remove theclientId
for 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