Developer Guide
- 1. Introduction
- 2. Acknowledgements
- 3. Setting up, getting started
- 4. Design and Implementation
- 5. Documentation, logging, testing, configuration, dev-ops
- 6. Appendix: Requirements
- 7. Appendix: Instructions for manual testing
1. Introduction
1.1 Purpose
This guide covers the architecture, implementation and design choices in DonnaFin to give the reader a clear picture of the technical details, and the inner workings of DonnaFin.io (referred to as DonnaFin in this document for brevity).
1.2 Target Audience
- Developers: anyone who wishes to dive into this codebase to improve or extend on DonnaFin.
- Advanced Users: financial advisors who want to better understand DonnaFin’s features.
1.3 About DonnaFin
DonnaFin.io is a desktop application for financial advisors to keep track of their client information and related tasks. Despite the application having an intuitive Graphical User Interface (GUI), it is optimized for entering commands using a Command Line Interface (CLI).
1.4 Typical User Workflow
This activity diagram shows how one might typically navigate through the DonnaFin application.
Commands refer to the pre-defined functions available to the user. Invalid commands refer to commands that are not available in the current window or commands that are used with the wrong format.
1.5 Overview of Application
In order to better understand how DonnaFin helps financial advisors, it is useful to understand and model the key client details that a financial advisor has to keep track of.
Below is an Object-Oriented Domain Model (OODM) modelling the existing state of affairs between a financial advisor and their client/s.
DonnaFin gives financial advisors a platform to store their numerous clients and their details. In this guide it will be explained how all the different classes, and components of DonnaFin come together to create a software that is able to perform this functionality.
2. Acknowledgements
Code Reuse
- SE-EDU: Address Book 3 - served as the foundation of this project
- SE-EDU: Address Book 4 - adapted their automated GUI tests for use here.
Libraries / Framework
- JavaFX - front-end Java framework
- ShadowJAR - generating fat JARs
-
Jackson - file parsing framework for
.json
- JUnit - testing framework
- TestFX - automated GUI testing framework
3. Setting up, getting started
Refer to the guide Setting up and getting started.
4. Design and Implementation

.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.
4.1 Architecture
The Architecture Diagram given above explains the high-level design of the App.
Given below is a quick overview of main components and how they interact with each other.
Main components of the architecture
Main
has two classes called Main
and MainApp
. It is responsible for,
- At app launch: Initializes the components in the correct sequence, and connects them 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 (also shown in the diagram above).
- defines its API in an
interface
with the same name as the Component. - implements the aforementioned functionality using a concrete
{Component Name}Manager
class.
For example, the Logic
component defines its API in the Logic.java
interface and implements its functionality using
the LogicManager.java
. Other components interact with a given component through its interface as much as possible
rather than the concrete class or through any lower-level class, as illustrated in the (partial) class diagram below.
Experienced programmers may recognise this as the Facade design pattern. (See: Facade Design Pattern)
The sections below give more details of each component.

Facade
pattern. For example, for the Ui
component,
AttributePanel
, PersonCard
and ClientPanel
. Arguably the better implementation would be to restrict all the
interactions between components to the facades, but a design decision was made to prioritize a simple implementation of
critical features over adhering to the design pattern.
4.1.1 UI component
Ui.java
specifies the API of this component.
The UI consists of a MainWindow
that is made up of parts e.g.CommandBox
, ResultDisplay
, PersonListPanel
in
home view and CommandBox
, ResultDisplay
, and ClientPanel
in client view. 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 that is displayed has 6 main states to switch between.
PERSON_LIST_PANEL
CONTACT
POLICIES
ASSETS
LIABILITIES
NOTES
The first state, PERSON_LIST_PANEL
represents the home view of the client. It is where the user sees the information of multiple clients at the same time. The other 5 are tabs specific to
each client and will thus display different information for each client. The Ui
keeps track of the current tab it is
observing through the UiState
, which is set on each tab switch command. Further details for the tab switch command can be found
here.
The Ui
component uses the JavaFx UI framework. The layout of these UI parts are defined in matching .fxml
files that
are in the src/main/resources/view
folder. For example, the layout of the
MainWindow
is
specified in MainWindow.fxml
The Ui
component,
- executes user commands using the
Logic
component. - listens for changes to
Model
data so that the UI can be updated with the modified data. - keeps a reference to the
Logic
component, because theUi
relies on theLogic
to execute commands. - depends on some classes in the
Model
component, as it displaysPerson
object residing in theModel
.
4.1.2 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 chooses anABCParser
class e.gAddressBookParser
,ContactTabParser
etc., 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 person). - The result of the command execution is encapsulated as a
CommandResult
object which is returned byLogic
.
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:
-
ParserContext
holds a reference to aParserStrategy
that is set based on the current tab the user is on etc. - When
ParserContext
calls upon the currentParserStrategy
to parse a user command, theABCParser
(ABC
is a placeholder for the specific parser strategy e.g.,ContactTabParser
) creates anXYZCommandParser
(XYZ
is a placeholder for the specific command name e.g.,AddCommandParser
) which uses the other classes above to parse the user command and create aXYZCommand
object. Further details can be seen in the implementation of commands section here.
- All
XYZCommandParser
classes (e.g.,AddCommandParser
,DeleteCommandParser
, …) inherit from theParser
abstract class so that they can be treated similarly where possible e.g, during testing. -
ClientViewParser
andAddressBookParser
inherit fromParserStrategy
while the tab specific parsers inherit fromClientViewParser
inherit.
4.1.3 Model component
API : Model.java
The Model
component,
- stores the address book data i.e., all
Person
objects (which are contained in aUniquePersonList
object). - stores the currently ‘selected’
Person
objects (e.g., results of a search query) as a separate filtered list which is exposed to outsiders as an unmodifiableObservableList<Person>
that can be ‘observed’ e.g. theUi
can be bound to this list so that theUi
automatically updates when the data in the list change. - stores a
UserPref
object that represents the user’s preferences. This is exposed to the outside as aReadOnlyUserPref
objects. - stores
Storage
object and communicates with it to save address book to user files.
4.1.4 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
)
How is Person
stored?
-
JsonAdaptedPerson
is created with the Jackson framework. - Each
Person
in DonnaFin is stored as aJsonAdaptedPerson
as shown in our class diagram above. - The
Name
,Email
,Phone
,Address
andNotes
of eachPerson
is stored as aJsonProperty
of type String. -
Assets
,Liabilities
andPolicy
are stored as a List ofJsonAdaptedAsset
,JsonAdaptedLiability
andJsonAdaptedPolicy
respectively. EachJsonAdaptedAsset
,JsonAdaptedLiability
andJsonAdaptedPolicy
is created separately using Jackson and contains the necessary fields for their respective attributes, stored as aJsonProperty
of type String. - As a
Person
can have more than oneAsset
,Liability
orPolicy
, we have chosen to store them as nested objects rather converting them into a single String before storage and converting them back to the correct attributes on retrieval from the database. - As such,
Asset
,Liability
andPolicy
are stored in this special manner and any future attributes that share the same characteristics can be stored in the same way.
Here is an example of a Person
in JSON form:
{
"name" : "Alex Yeoh",
"phone" : "87438807",
"email" : "alexyeoh@example.com",
"address" : "Blk 30 Geylang Street 29, #06-40",
"notes" : "Likes bread",
"policies" : [ {
"name" : "Golden Age",
"insurer" : "AIA",
"totalValueInsured" : "$ 14000.00",
"yearlyPremiums" : "$ 28.00",
"commission" : "$ 4.00"
} ],
"liabilities" : [ {
"name" : "Bank debt",
"type" : "debt",
"value" : "$ 20000.00",
"remarks" : "10% interest"
} ],
"assets" : [ {
"name" : "HDB @Jurong",
"type" : "Property",
"value" : "$ 300000.00",
"remarks" : "BTO"
} ]
}
4.1.5 Common classes
Classes used by multiple components are in the donnafin.commons
package.
There are three main groups of Common classes, and here is a brief description of each and examples of how they are used in this codebase.
Type classes
There are two classes that can be found underdonnafin.commons.core.types
:
-
Index
: Abstracts away the difference between one-based index (display / user input) and zero-based index (native Java indexing of data structures). Serves to minimise programming errors, particularly those of the ‘off-by-one’ category that can happen when dealing with these incompatible numbering styles. -
Money
: Provides a numerically sound structure that can be used to represent monetary values with precision and support arithmetic operations without foregoing easy in built conversion to a human-readable format with the currency symbol (‘$’).
Utility classes
There are multiple classes in donnafin.commons.core.util
that serve a variety of purpose. In general, they can be seen
as a common library of pure functions that can be used throughout the application to fulfil certain purposes. It reduces
on code duplication and improves the cohesion of our code. For example, we often do defensive programming checks to
ensure that multiple objects are not null, and the CollectionUtil
package has useful static functions that can be
called on to do this.
Exception classes
There are custom-built exceptions donnafin.commons.exception
, that are used throughout the code base. Some custom
exceptions (like ParseException
) are only used in certain packages, and are therefore can be found in those packages.
In this package, we currently have DataConversionException
and IllegalValueException
, both of which handle a very
common issue throughout the application of handling and reporting bad formats (syntax) or bad inputs (semantics).
4.2 Implementation
How the architecture components interact with each other through commands
Command types fall into three main categories.
- Model-level commands
- Client-level commands
- UI-browsing commands
Despite falling under the three broad categories, the commands still have many similarities. Thus, we give an in depth explanation of how the first category works. Subsequent explanation of commands from the other two categories will follow the same framework but differ slightly.
4.2.1 Model-level commands

1. The command interacts with model through an addition or deletion
2. The command interacts with storage through an addition or deletion.
3. The command does not access the inner details of clients but rather treat them as atomic.
Commands that fall under this category are :
1. Add
2. Delete
3. Find
4. List
The delete
command is one of the commands that fall under this category.
We will be using the delete
command as the example to illustrate and explain all commands under this category.
Full sequence diagram |
![]() |
Logic specific sequence diagram |
![]() |
Here is an explanation of what takes place when the user enters the command delete 1
which falls under first category.
The full sequence diagram gives the overview of what happens when a command runs. Since the main legwork is done
in logic, the logic specific sequence diagram as shown above takes a deeper dive into the inner details the full
sequence diagram.
Explanation of diagram above:
- The
Ui
takes in the input command from the user and passes it to theLogic
component. - The
Logic
component parses the command and returns theDelete
command. - The
Logic
component executes theDelete
command. ThedeletePerson
method inModel
is called which then deletes thePerson
fromdonnafin.json
. - The
Logic
component then accepts theLogicConsumer
produced from theCommandResult
. This consumer will alter the logic component depending on theCommandResult
. In this case, for thedelete
command, the consumer makes no change to logic. - The
Logic
component then continues with theexecute
command and calls thesaveAddressBook
method to save the updatedaddressBook
with the deleted person. This does not involve a consumer in any way and is always part of execute command. - The
Model
component then callssaveAddressBook
method that engages theStorage
component to save the updated changes to storage locally. - The
Ui
component then accepts theConsumer<Ui>
produced from theCommandResult
. This consumer will alter the UI component depending on theCommandResult
. In this case, for thedelete
command, the consumer makes no change to logic.
4.2.2 Client-level commands

1. The command has to access and edit information regarding one specific client.
2. The command interacts and actively updates information in storage.
However, commands in the third category differ from the first in that this category deals with information within one specific client, while the first adds/deletes the client specified within the entire model.
Commands that fall into the second category are:
1. Edit
2. Append
3. Remove
Edit
command is a command that edits the information of a specific client. Other commands like append and remove,
also deal directly with a specific client’s information. Thus, they fall under the second category
Like other commands in the other two categories, edit command follows the same general
structure. We will be using the Edit
command as the example to illustrate and explain all commands under this category.
Explanation:
- The
Ui
takes in the input command from the user and passes it to theLogic
component. - The
Logic
component parses the input and theEdit
command is returned. A consumer forPersonAdapter
is created here. - The
Logic
component executes theEdit
command. - During the execution of the
Edit
command above, thePersonAdapter
accepts the consumer that edits the specified person. - A
EditCommandResult
is returned from the execution ofEdit
Command. ThisCommandResult
, like the two other categories contain both a consumer forUi
andLogic
. - The
Logic
component then accepts theLogicConsumer
produced from theCommandResult
. - The
Ui
component then accepts theConsumer<Ui>
produced from theCommandResult
. TheUi
is here to display the newly edits made.
In this category of commands, the class
PersonAdapter
is doing most of the legwork here.
PersonAdapter
serves as a wrapper for the Model class Person
.
The key differences are that Person
is immutable and does not support edits, while the PersonAdapter
effectively supports edits by wrapping a single Person
object and replacing it with an edited copy as and when necessary.
Such an implementation supports the user viewing and controlling a single client like with the ViewCommand
.
4.2.3 UI-browsing commands

1. The commands do not interact with model.
2. The commands have to handle the changing of
ParserStrategy
, from the current oneto
ABCParser
of the new tab.
3. The commands need to update the UiState
of Ui
to keep track of which tab the user is currently on.
Commands that fall into this category are:
1. SwitchTab
2. View
3. Home
Switch tab command is a command that explicitly involves the changing of tabs, which fall under the third category
We will be using the SwitchTab
command as the example to illustrate and explain all commands under this category.
Explanation of diagram above:
- The
Ui
takes in the input command from the user and passes it to theLogic
component that is responsible for parsing the input. - The
Logic
component parses the command and returns theSwitchTab
command. - The
Logic
component executes theSwitchTab
command and returns theSwitchTabCommandResult
- The
Logic
component then accepts theLogicConsumer
produced from theSwitchTabCommandResult
. In this case, for theSwitchTab
command, a newParserStrategy
is set here. - The
Ui
component then accepts theConsumer<Ui>
produced from theCommandResult
.UiState
is set here.
1. When a
XYZCommand
class (e.g. HomeCommand
, ViewCommand
,…) is executed, it returns a CommandResult
object containing a logic action if the XYZCommand
requires a change in tab or view. 2.
LogicManager
accepts this CommandResult
object and executes the logic action here.LogicManager
is a facade that is able to set and change the current ParserStrategy
.3.
ParserContext
in LogicManager
is updated to contain the ABCParser
of the new view or tab.4.
Ui
is updated to change its state, which is kept track of by UiState
by accepting the consumer also in the CommandResult
.4.3 Contact Tab
The following screenshot shows the user in the Client View. You may notice that the primary controller for this view is
not the MainWindow
, but a different class, ClientPanel
. This JavaFX controller encapsulate all the logic for Client
View specific actions.
The dark blue rectangle indicates a VBox
(vertical box) containing 4 AttributePanel
instances (1 for each attribute: Name
, Email
, Phone
, Address
.
On every call to changing tab or refreshing, the ClientPanel
takes the following steps:
- The
VBox
container inClientPanel
will clear all its children -
ClientPanel
will create a list ofAttributePanel
s (a handy class for constructing a display for any single valued attribute) - The
VBox
container will add the list ofAttributePanel
s as its child.
4.4 Policies, Assets and Liabilities Tab
These tabs all behave and are implemented identically, so they will be discussed together, with the Policies tab used as an example.
The dark blue rectangle indicates an AnchorPane
that contains the entire AttributeTable
.
The red rectangle is the table heading.
The green rectangle is an ‘aggregator’ label, that shows some aggregated measurement of the data.
The purple rectangle is the standard JavaFX TableView
component.
AttributeTable
is a generic class that aims to provide a standardised rich table view of any multi-valued attribute.
In aid of this, it was written as a generic class with the ‘open-closed principle’ in mind.
(See SE-EDU: Open Closed Principle)
You can look at a very minimal example of how to create TableConfig
and set up an attribute for AttributeTable
in AttributeTableTest
. In short, you have the TableConfig
holds the following:
- Table heading
- Aggregator function that takes a list of the attribute (
Policy
in this case) and turn it into an aggregate label (e.g. Total value of commissions) - A list of
ColumnConfig
that specifies the property name, the column heading to show, the preferred and max widths for each column, as well.
The steps taken in constructing these tabs are very similar to those for the Contact tab.
- The
VBox
container inClientPanel
will clear all its children. - The attribute intended to be used (policy in this case) will provide the
TableConfig
required as a public static member. -
ClientPanel
will create anAttributeTable
using this configuration and the data (list of values from thePersonAdapter
) - The
VBox
container will add theAttributeTable
as its child.
AttributeTable
4.5 Notes tab
The NotesTabParser
is different from other tabSpecificParsers
in that it has no tab specific command. However, the
TextArea
of the notes tab allows the user to type in any quick notes that the
user would want, updating it in realtime. This is opposed to the commands however, since for commands
changes to any other component only happen when the command is executed. Hence, the notes tab takes advantage of a
different process.
This is a planned deviation in user workflow, and done so as notes are more infrequently used, and there is an expectation that users would write at length in a multi-line field. As such, we deemed the gains from force fitting editing notes into a command line style edit and accommodating a switch from the single line Command Bar was deemed unnecessarily complicated and unintuitive.
The dark blue rectangle indicates an TextArea
.
- The
VBox
container inClientPanel
will clear all its children. -
ClientPanel
will get the current value in thePersonAdapter
’s notes field and create aTextArea
with it. - The
TextArea
will be configured to support saving edits (explained later in this section). - The
VBox
container will add theAttributeTable
s as its children.
Key details of the TextArea
:
- A listener is attached to the
TextArea
of the notes tab. This allows for realtime updates when typing in theTextArea
. If there are any changes, the functionedit
inPersonAdapter
is called. - The
edit
function inPersonAdapter
saves the information straight away, hence making the updates realtime.
5. Documentation, logging, testing, configuration, dev-ops
6. Appendix: Requirements
6.1 Product scope
Target user profile:
- Financial Advisor
- Has a need to manage a significant number of clients
- Keep track of their financial and personal information
- Prefer desktop apps over other types
- Tech-savvy, comfortable with keyboard shortcuts (CLI apps)
- Can type fast
- Prefers typing to mouse interactions
Value proposition: manage customers faster than a typical mouse/GUI driven app
The product provides financial advisors with a clean, easy to use interface to prepare them for meetings and maintain good relationships with their clients. On a per-client basis, DonnaFin keeps track and displays client’s financial details, their contact details, and any notes about the client. In the main page, it collates all clients for easy access. In the client information page, financial details of the specific client selected is neatly segmented into tabs for convenient and quick access.
The product will not help them with work relations with other financial advisors as the product’s scope only covers the personal use of the product. It does not link with any financial calculators, financial databases or cover market information.
6.2 User stories
Priorities: (must have) - HIGH
, Medium (nice to have) - MEDIUM
, Low (unlikely to have) - LOW
Priority | As a … | I want to … | So that I can… |
---|---|---|---|
HIGH |
new user | see usage instructions | refer to instructions when I forget how to use the App |
HIGH |
user | add a new client | add new clients to my list |
HIGH |
user | delete a client | remove clients that I no longer have |
HIGH |
efficient user | find a client by name | locate details of clients without having to go through the entire list |
HIGH |
user | view a client’s personal info | find out the personal information about the client |
HIGH |
user | return to home window from client’s information | move on to view my other clients instead of the current client that I am viewing |
HIGH |
new user | clear all clients | delete all clients and reset all my contacts for the application |
HIGH |
user | edit a client’s contact information | keep up to date with the clients information for further usage |
HIGH |
user | add a policy to the client’s list of policies | update the current policies the client has should a new policy be purchased |
HIGH |
user | delete a policy to the client’s list of policies | update the current policies the client has |
HIGH |
user | add an asset to the client’s list of assets | update the current assets the client has |
HIGH |
user | delete an asset from the client’s list of assets | update the current assets the client has |
HIGH |
efficient user | view the total value of all assets | make decisions regarding the assets and inform the client about his aggregated asset value easily |
HIGH |
user | add a liability to the client’s list of liabilities | update the current liabilities that the client has |
HIGH |
user | delete a liability from the client’s list of liabilities | update the current liabilities that the client has |
MEDIUM |
efficient user | view the total value of liabilities | make decisions regarding liabilities with more useful information |
MEDIUM |
user | jot down quick notes regarding the client | keep track of general information regarding the client |
MEDIUM |
organised user | switch between different tabs of client information, e.g financial information or personal information | have access to all the information of the client easily |
MEDIUM |
new user | follow a tutorial when adding my first client | learn how to add a new client |
MEDIUM |
new user | follow a tutorial when deleting a client | learn how to remove a client that I do not want to keep track of |
MEDIUM |
new user | follow a tutorial to view a client’s personal information | learn how to view a specific client’s contact information |
LOW |
new user | follow a tutorial to switch between a client’s information information tabs | learn how to view all information regarding a specific client |
LOW |
new user | follow a tutorial when adding policies to a client’s list of policies | learn how to add policies to the list of policies of a specific client |
LOW |
new user | follow a tutorial when deleting policies from a client’s list of policies | learn how to delete policies from the list of policies of a specific client |
LOW |
new user | follow a tutorial when adding assets to a client’s list of assets | learn how to add assets to the list of assets of a specific client |
LOW |
new user | follow a tutorial when adding delete from a client’s list of assets | learn how to delete assets from the list of assets of a specific client |
LOW |
new user | follow a tutorial when adding liabilities to a client’s list of liabilities | learn how to add liabilities to the list of liabilities of a specific client |
LOW |
new user | follow a tutorial when deleting liabilities from a client’s list of liabilities | learn how to delete liabilities from the list of liabilities of a specific client |
LOW |
new user | follow a tutorial when jotting down notes for a client | learn how to jot down quick notes regarding general information of the client |
6.3 Use cases
(For all use cases below, the System is the DonnaFin
application and the Actor is the user
, unless specified otherwise)
UC01: Adding a client to DonnaFin
State: Home Window
MSS
- User requests to add client along with the relevant details.
-
DonnaFin announces that the client has been successfully added.
Use case ends.
Extensions
- 1a. User’s input does not conform with the specified format.
- 1a1. DonnaFin shows an error message and displays the correct format for the user to use and a correct example.
Use case resumes from step 1.
- 1a1. DonnaFin shows an error message and displays the correct format for the user to use and a correct example.
UC02: Deleting a client from DonnaFin
State: Home Window
MSS
- User requests to delete a client from DonnaFin using the right syntax.
-
DonnaFin announces that the client has been successfully deleted.\
Use case ends.
Extensions
- 1a. The given index is invalid.
- 1a1. DonnaFin shows an error message. Use case resumes from step 1.
UC03: Finding a client by name
State: Home Window
MSS
- User chooses to find a client within DonnaFin.
-
DonnaFin displays the clients that match the input keyword.
Use case ends.
Extensions
- 1a. User’s input does not conform with the specified format.
- 1a1. DonnaFin shows an error message.
Use case resumes from step 1.
- 1a1. DonnaFin shows an error message.
- 1b. The keyword does not match any client.
- 1b1. DonnaFin does not display any client.
Use case ends.
- 1b1. DonnaFin does not display any client.
UC04: Viewing the details of a client
State: Home Window
MSS
- User requests to view a client.
-
DonnaFin displays details on the client.
Use case ends.
Extensions
- 1a. User’s input does not conform with the specified format.
- 1a1. DonnaFin shows an error message.
Use case resumes from step 1.
- 1a1. DonnaFin shows an error message.
- 1b. The given index is invalid.
- 1b1. DonnaFin shows an error message.
Use case resumes from step 1.
- 1b1. DonnaFin shows an error message.
UC05: Getting help
State: Works on both Home and Client Window
MSS
- User requests for help to get assistance on commands.
-
DonnaFin displays a window with the user guide for the DonnaFin application.
Use case ends.
UC06: Listing all clients
State: Home Window
MSS
- User requests for the list of all the registered clients.
-
DonnaFin displays all the clients that has been registered within DonnaFin.
Use case ends.
UC07: Switching to other tabs
State: Client Window
MSS
- User requests to view another tab within the client Window.
-
DonnaFin switches the current tab to the requested tab.
Use case ends.
Extensions
- 1a. The user’s input cannot be mapped to any tab.
- 1a1. DonnaFin shows an error message and tells the user that the tab they request does not match any existing tab.
Use case resumes from step 1.
- 1a1. DonnaFin shows an error message and tells the user that the tab they request does not match any existing tab.
UC08: Returning to Home Window
State: Client Window
MSS
- User requests to return to home window.
-
DonnaFin switches the view back to home window.
Use case ends.
UC09: Editing a client’s contact information
State: Client Window (Contact Tab)
MSS
- User requests to edit client’s contact information.
-
Field is edited and client window with the updated field is shown.
Use case ends.
Extensions
- 1a. User’s input does not conform with the specified format.
- 1a1. Contact is not updated and DonnaFin shows an error message.
Use case resumes from step 1.
- 1a1. Contact is not updated and DonnaFin shows an error message.
UC10: Adding an asset to a client
State: Client Window (Assets Tab)
MSS
- User requests to add an asset to the client.
-
DonnaFin adds the asset.
Use case ends.
Extensions
- 1a. User’s input does not conform with the specified format.
- 1a1. DonnaFin shows an error message.
Use case resumes from step 1.
- 1a1. DonnaFin shows an error message.
UC11: Removing an asset from a client
State: Client Window (Assets Tab)
MSS
- User requests to remove an asset from the client.
-
DonnaFin removes the asset.
Use case ends.
Extensions
- 1a. User’s input does not conform with the specified format.
- 1a1. DonnaFin shows an error message and displays the correct format for the user to use with a correct example.
Use case resumes from step 1.
- 1a1. DonnaFin shows an error message and displays the correct format for the user to use with a correct example.
- 1b. User’s given index is invalid.
- 1b1. DonnaFin shows an error message.
Use case resumes from step 1.
- 1b1. DonnaFin shows an error message.
UC12: Adding a liability to a client
State: Client Window (Liabilities Tab)
MSS
- User requests to add a liability to the client.
-
DonnaFin adds the liability.
Use case ends.
Extensions
- 1a. User’s input does not conform with the specified format.
- 1a1. DonnaFin shows an error message.
Use case resumes from step 1.
- 1a1. DonnaFin shows an error message.
UC13: Removing a liability from a client
State: Client Window (Liabilities Tab)
MSS
- User requests to remove a specific liability from the client.
-
DonnaFin deletes the liability.
Use case ends.
Extensions
- 1a. User’s input does not conform with the specified format.
- 1a1. DonnaFin shows an error message and displays the correct format for the user to use with a correct example.
Use case resumes from step 1.
- 1a1. DonnaFin shows an error message and displays the correct format for the user to use with a correct example.
- 1b. User’s given index is invalid.
- 1b1. DonnaFin shows an error message.
Use case resumes from step 1.
- 1b1. DonnaFin shows an error message.
UC14: Adding a policy to a client
State: Client Window (Policies Tab)
MSS
- User requests to add a policy to the client.
-
DonnaFin adds the policy.
Use case ends.
Extensions
- 1a. User’s input does not conform with the specified format.
- 1a1. DonnaFin shows an error message.
Use case resumes from step 1.
- 1a1. DonnaFin shows an error message.
UC15: Removing a policy from a client
State: Client Window (Policies Tab)
MSS
- User requests to remove a policy from the client.
-
DonnaFin removes the policy.
Use case ends.
Extensions
- 1a. User’s input does not conform with the specified format.
- 1a1. DonnaFin shows an error message and displays the correct format for the user to use with a correct example.
Use case resumes from step 1.
- 1a1. DonnaFin shows an error message and displays the correct format for the user to use with a correct example.
- 1b. User’s given index is invalid.
- 1b1. DonnaFin shows an error message.
Use case resumes from step 1.
- 1b1. DonnaFin shows an error message.
UC16: Exiting the application
State: Works on both Home and Client Window
MSS
- User requests to exit the application.
-
DonnaFin exits and closes.
Use case ends.
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 1000 persons without a noticeable sluggishness in performance for typical usage.
- A user with above average typing speed for regular English text (i.e. not code, not system admin commands) should be able to accomplish most of the tasks faster using commands than using the mouse.
- A novice with no coding background should be able to use the address book.
- The system should respond within 100 milliseconds.
- The size of the application should be no more than 100 MB.
- All data should be stored locally.
- The application should not need a remote server to function.
- The application should not require any installer to start functioning.
- The GUI should appear fine for screen resolutions 1920x1080 and higher.
6.5 Glossary
- Mainstream OS: Windows, Linux, Unix, OS-X
- Private client detail: A client detail that is not meant to be shared with others
- Asset: Things of present or future value owned by a client
- Liability: Things that the client owes to a debtor which would lead to an outflow of money in the future.
- Policy: A contract between an insurer and policyholder (the client in this case) where the policyholder receives financial protection or reimbursement against losses. ——————————————————————————————————————–
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 clients. The window size may not be optimised for your display.
-
-
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.
-
7.2 Adding a client
-
Adding a client in the home window.
-
Test case:
add n/Steve Rogers p/91820392 e/thefirstavenger@test.com a/33 Apple Road, 928103
Expected: New client with the details are added to the end of the list. Details of the added client are shown in the result display. -
Test case:
add e/thefirstavenger@test.com add n/Steve Rogers a/33 Apple Road, 928103 p/91820392
Expected: Similar to previous as the input order of the parameters does not matter as long as the command word (add
in this case) is the first word. -
Test case:
add n/@$%^&&* p/91820392 e/thefirstavenger@test.com a/33 Apple Road, 928103
Expected: Client is not added. Error details shown in the result display. -
Other incorrect add commands to try:
add n/@$%^&&* p/abcde e/thefirstavenger@test.com a/33 Apple Road, 928103
,add n/@$%^&&* p/92810283 e/thefirstavenger a/33 Apple Road, 928103
,...
. Expected: Similar to previous.
-
-
Adding a client in the client window.
- Test case:
add n/Steve Rogers p/91820392 e/thefirstavenger@test.com a/33 Apple Road, 928103
Expected: Client is not added as add is a home window command that cannot be executed in the client window. Error details shown in the result display.
- Test case:
7.3 Deleting a client
-
Deleting a client while all clients are being shown (home window)
-
Prerequisites: List all persons using the
list
command. Multiple persons in the list. -
Test case:
delete 1
Expected: First client is deleted from the list. Details of the deleted client shown in the result display. -
Test case:
delete 0
Expected: Client is not deleted. Error details shown in the result display. -
Other incorrect delete commands to try:
delete
,delete x
,...
(where x is larger than the list size)
Expected: Similar to previous.
-
-
Deleting a client while being in the client window.
- Test case:
delete 1
Expected: Client is not deleted as delete is a home window command that cannot be executed in the client window. Error details shown in the result display.
- Test case:
7.4 Viewing and editing a client’s contact details
-
Entering a client window
-
Prerequisites: Currently in the home window and a client exists in the list.
-
Test case:
view 1
Expected: Client window will be shown, and you can inspect the details of the client. -
Test case:
view -4
Expected: As it is not a valid index, you will remain in the home window with an error command output. -
Other incorrect view commands to try:
view
,view a
,view X
,...
(where x is larger than the list size)
Expected: Similar to previous.
-
-
Editing a client’s details.
-
Prerequisites: Currently in the client window and in the contact tab.
-
Test case:
edit n/John
Expected: The name of the client will be changed to John. Details of the newly edited client will be shown in the result display. -
Test case:
edit n/Jane p/82893109
Expected: Details of the client will change according to the input as multi-field editing is supported. Details of the newly edited client will be shown in the result display. -
Test case:
edit n/&$^@*@!
Expected: Details of the client will not change as an invalid format has been used. Error details shown in the result display. -
Other incorrect edit commands to try:
edit p/test
,...
Expected: Similar to previous.
-
7.5 Appending and removing a client’s asset/policy/liability list
-
Appending an asset/liability to a client.
-
Prerequisites: Currently in the client window and in the assets/liabilities tab (according to what financial information you want to append).
-
Test case:
append n/Good Class Bungalow ty/Property v/$10000000 r/newly bought with bank loan
Expected: An asset/liability with the input details will be added to the client’s financial information. The list of assets/liabilities will be sorted (including the newly added asset/liability). A message confirming that the asset/liability has been appended will appear in the result display. -
Test case:
append n/Good Class Bungalow v/$10000000 r/newly bought with bank loan
Expected: Asset/Liability will be not added as an invalid format has been used. An error message showing the correct format will be shown in the result display.
-
-
Appending a policy to a client.
-
Prerequisites: Currently in the client window and in the policies tab.
-
Test case:
append n/Diamond Policy i/AIA iv/$10000 pr/$200 c/$1000
Expected: A policy with the input details will be added to the client’s financial information. The list of policies will be sorted (including the newly added policy). A message confirming that the policy has been appended will appear in the result display. -
Test case:
append n/Diamond Policy iv/$10000 pr/$200 c/$1000
Expected: Policy will not be added as an invalid format has been used. An error message showing the correct format will be shown in the result display.
-
-
Removing an asset/liability/policy from a client.
-
Prerequisites: Currently in the client window and in the assets/liabilities/policies tab (according to which financial information to remove). Additionally, there are assets/liabilities/policies to be removed.
-
Test case:
remove 1
Expected: The first asset/liability/policy is removed from the list. A message to notify that the asset/liability/policy has been removed will be shown in the result display. -
Test case:
remove 0
Expected: Asset/Liability/Policy will not be removed from the list. An error message showing the correct format will be shown in the result display. -
Other incorrect remove commands to try:
remove
,remove a
,remove @
,remove X
,...
(where x is larger than the number of assets/liabilities/policies listed).
Expected: Similar to previous.
-
7.6 Clearing client list
- Clearing all clients in the home window.
- Prerequisites: User is currently in the home window and there is at least 1 client.
- Test case:
clear
Expected: All the clients listed in the client list panel will be removed, and the client list panel will be cleared. A message confirming that will appear in the result display. - Test case:
clear 2
Expected: Clients will not be cleared from the client list panel. An error message showing the correct format will be shown in the result display.
- Clearing all clients in the client window.
- Prerequisites: User is currently in the client window in any tab.
- Test case
clear
Expected: Clients will not be cleared from the client list panel. An error message letting the user know that the command is not supported in this view will be shown in the result display.
7.7 Switching tab in Client Window
- Switching to Contact Tab
- Prerequisites: User is currently in the client window.
- Test case:
tab c
,tab contact
,tab contacts
Expected: The tab will be changed to contact tab of the client in focus and the ‘Switched tab’ message will appear on the result display. - Test case:
tab contact us
Expected: The tab will not be changed and the client view will remain at the existing tab. An error message will be shown in the result display.
- Switching to Policies Tab
- Prerequisites: User is currently in the client window.
- Test case:
tab p
,tab policy
,tab policies
Expected: The tab will be changed to policies tab of the client in focus and the ‘Switched tab’ message will appear on the result display. - Test case:
tab polici
Expected: The tab will not be changed and the client view will remain at the existing tab. An error message will be shown in the result display.
- Switching to Assets Tab
- Prerequisites: User is currently in the client window.
- Test case:
tab a
,tab asset
,tab assets
Expected: The tab will be changed to assets tab of the client in focus and the ‘Switched tab’ message will appear on the result display. - Test case:
tab assetes
Expected: The tab will not be changed and the client view will remain at the existing tab. An error message will be shown in the result display.
- Switching to Liabilities Tab
- Prerequisites: User is currently in the client window.
- Test case:
tab l
,tab liability
,tab liabilities
Expected: The tab will be changed to liabilities tab of the client in focus and the ‘Switched tab’ message will appear on the result display. - Test case:
tab liabileeties
Expected: The tab will not be changed and the client view will remain at the existing tab. An error message will be shown in the result display.
- Switching to Notes Tab
- Prerequisites: User is currently in the client window.
- Test case:
tab n
,tab note
,tab notes
Expected: The tab will be changed to notes tab of the client in focus and the ‘Switched tab’ message will appear on the result display. - Test case:
tab noties
Expected: The tab will not be changed and the client view will remain at the existing tab. An error message will be shown in the result display.
7.6 Saving data
-
Dealing with missing/corrupted data files
- Prerequisites: DonnaFin is closed and there is access to the
[JAR file location]/data/donnafin.json
file.- Test case: Replace the name, phone, email or address attribute to
null
in the[JAR file location]/data/donnafin.json
file. - Expected: When DonnaFin is opened, the client list panel will be empty. Entering any valid command after this state will wipe the
[JAR file location]/data/donnafin.json
file completely, and your command will be executed.
- Test case: Replace the name, phone, email or address attribute to
- Prerequisites: DonnaFin is closed and there is access to the