By: Team AY1920S1-CS2103T-W12-3      Since: Sep 2019      Licence: MIT

1. Introduction

1.1. Purpose

This document describes the architecture and system design of PalPay. It is a living document that evolves throughout the design and implementation for each release. Each release will have an edition of the document, and the current edition of the document is for the first public release of the application.

This document is aimed at covering the high-level system architecture and design. It is segmented into two major parts: software design, including system architecture, and design implementation. The software design documents the main software components that operate and support the main system architecture. Essential details such as the user stories and use cases, as well as the Non Functional Requirements are included at the back of the document.

1.2. Audience

This document is written for software engineers want to gain an insight of the system architecture and design of the application. In particular, the intended audience of this document is the students taking the roles of the developers, designers, and software testers of PalPay from CS2103T - Software Engineering.

1.3. Description

PalPay is a CLI application targeted for users who have poor financial management skills. It allows the users to keep track of daily financial transactions, as well as set a budget for a time duration to achieve long-term financial success. Not only that, users can keep a ledger of lending and borrowing of money with others so that the users can keep track of the flow of their money.

2. Setting up

Refer to the guide here.

3. Design

3.1. Architecture

ArchitectureDiagram
Figure 1. Architecture Diagram

The Architecture Diagram given above explains the high-level design of the App. Given below is a quick overview of each component.

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 method where necessary.

Commons represents a collection of classes used by multiple other components. The following class plays an important role at the architecture level:

  • LogsCenter : Used by many classes to write log messages to the App’s log file.

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 components

  • Defines its API in an interface with the same name as the Component.

  • Exposes its functionality using a {Component Name}Manager class.

For example, the Logic component (see the class diagram given below) defines it’s API in the Logic.java interface and exposes its functionality using the LogicManager.java class.

LogicClassDiagram
Figure 2. Class Diagram of the Logic Component

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.

ArchitectureSequenceDiagram
Figure 3. Component interactions for delete 1 command

The sections below give more details of each component.

3.2. UI Component

UiClassDiagram
Figure 4. Structure of the UI Component

API : Ui.java

The UI consists of a MainWindow that is made up of parts e.g.CommandBox, ResultDisplay, PersonListPanel, StatusBarFooter etc. All these, including the MainWindow, inherit from the abstract UiPart class.

The UI component uses 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.

3.3. Logic Component

LogicClassDiagram
Figure 5. Structure of the Logic Component

API : Logic.java

  1. Logic uses the BankAccountParser class to parse the user command.

  2. This results in a Command object which is executed by the LogicManager.

  3. The command execution can affect the Model (e.g. adding a transaction).

  4. The result of the command execution is encapsulated as a CommandResult object which is passed back to the Ui.

  5. In addition, the CommandResult object can also instruct the Ui to perform certain actions, such as displaying help to the user.

Given below is the Sequence Diagram for interactions within the Logic component for the execute("delete t1") API call.

DeleteSequenceDiagram
Figure 6. Interactions Inside the Logic Component for the delete t1 Command
The lifeline for DeleteCommandParser should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram.

3.4. Model Component

ModelClassDiagram
Figure 7. Structure of the Model Component

API : Model.java

The Model,

  • stores a UserPref object that represents the user’s preferences.

  • stores the Bank Account data.

  • exposes an unmodifiable ObservableList<BankOperation> and ObservableList<Budget> 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 due to user command.

  • does not depend on any of the other three components.

3.5. Storage Component

StorageClassDiagram
Figure 8. Structure of the Storage Component

API : Storage.java

The Storage component,

  • can save UserPref objects in json format and read it back.

  • can save the Bank Account data in json format and read it back.

3.6. Common Classes

Classes used by multiple components are in the seedu.addressbook.commons package.

4. Implementation

This section describes some noteworthy details on how certain features are implemented.

4.1. Transaction: in / out / split / receive

The Transaction abstract class allows user to input income, expense or split commands into the PalPay.

4.1.1. Current Implementation

Transaction is an abstract class which contains the default constructor and commonly used functions. InTransaction and OutTransaction extends the Transaction class. Transaction stores an amount, date, description, and a set of categories. This describes the variables a Transaction with the BankAccount will typically hold. InTransaction and OutTransaction implements BankAccountOperation.

4.1.2. Design Considerations

Implementation of Transaction abstract class allows code reuse as different types of transactions depends on similar variables.
The balance in BankAccount is considered separate from the balance in Ledger, both being encompassed in UserState. Therefore user operations that deal with BankAccount implements the BankAccountOperation interface, while operations that deal with Ledger implements the LedgerOperation interface.
This allows us to achieve polymorphism by overloading methods in Model to handle the different operations correctly.

4.2. Update: update

This feature allows users to update either the Amount, Date or Category of either a Transaction or Budget.

4.2.1. Design Considerations

This update feature allows one or more fields of a Transaction or Budget to be updated. (e.g. update t1 $/2 and update t1 $/2 d/10102019 will both work as intended). This will minimize the need to input all non-required parameters if a user does not require all parameters of a Transaction or Budget to be changed.

Aspect: Update requires TYPE+INDEX as one of its parameter
  • Alternative 1 (current choice): takes in TYPE+INDEX to decide whether to delete an item from Transaction or Budget list. (e.g. delete b1 deletes item index 1 from budget).

    • Pros: Requires lesser user steps to be taken before executing a update command

    • Cons: Requires two lists to be created instead of 1. The UniqueTransactionList stores Transaction items and UniqueBudgetList to store Budget items. For example, when a new command is executed, we must remember to update both HistoryManager and VersionedAddressBook.

  • Alternative 2: Change to Transaction or Budget mode and keying in only index (e.g. update 1)

    • Pros: Requires only one unique list required to store both Transactions and Budgets.

    • Cons: Requires additional user step to switch between modes before executing a updating command.

4.3. Undo / Redo Command Feature: undo/redo

4.3.2. Design Considerations

Aspect: How undo & redo executes
  • Alternative 1 (current choice): Saves the entire address book.

    • Pros: Easy to implement.

    • Cons: May have performance issues in terms of memory usage.

  • Alternative 2: Individual command knows how to undo/redo by itself.

    • Pros: Will use less memory (e.g. for delete, just save the person being deleted).

    • Cons: We must ensure that the implementation of each individual command are correct.

Aspect: Data structure to support the undo/redo commands
  • Alternative 1 (current choice): Use a list to store the history of address book states.

    • Pros: Easy for new Computer Science student undergraduates to understand, who are likely to be the new incoming developers of our project.

    • Cons: Logic is duplicated twice. For example, when a new command is executed, we must remember to update both HistoryManager and VersionedAddressBook.

  • Alternative 2: Use HistoryManager for undo/redo

    • Pros: We do not need to maintain a separate list, and just reuse what is already in the codebase.

    • Cons: Requires dealing with commands that have already been undone: We must remember to skip these commands. Violates Single Responsibility Principle and Separation of Concerns as HistoryManager now needs to do two different things.

4.4. Delete Transaction Feature: delete

This feature allows the user to delete an existing transaction or budget from the list.
The following activity diagram summarizes what happens when a user executes Delete command:

DeleteActivityDiagram
Figure 9. Activity Diagram of Delete Command

4.4.1. Current Implementation

Transaction is an abstract class which implements UndoableAction. inTransaction and outTransaction extend the Transaction class. Transaction stores an amount, date and a set of categories which describe the variables a Transaction with the BankAccount will typically hold. Split transaction is the only dependency that relies on an additional peopleInvolved variable. inTransaction and outTransaction implement BankAccountOperation.

4.4.2. Design Consideration

Aspect: Delete requires TYPE+INDEX as one of its parameter

Implementation of Transaction abstract class allows code reuse as different types of transactions depends on similar variables. inTransaction and outTransaction can be referenced by making a call to BankAccountOperation, this BankAccountOperation is then passed as an argument to Logic components and multiple CRUD commands. This allows multiple transaction calls within the same method.

4.5. Sort Feature: sort

This feature allows the user to sort their bank account by the amount or date of their transactions by using the command sort amount or sort date respectively.

4.5.1. Current Implementation

The sort command is facilitated by the Logic and Model components of the application.

The following sequence diagram shows how the sorting of transactions work when the user enters sort amount.

SortSequenceDiagram
Figure 10. Sequence Diagram for sort amount

4.5.2. Design Considerations

Aspect: Sorting of the Bank Account
  • Alternative 1 (Current Choice): Creating a comparator for each area to be sorted.

    • Pros: Easy to implement.

    • Cons: Users can only sort by comparators that have been implemented. Developers have to create a new comparator class to sort a new area.

  • Alternative 2: Users can define the area to be sorted.

    • Pros: Extremely flexible for the users as they are not limited to the number of areas to be sorted.

    • Cons: Difficult to implement.

4.6. Filter Feature: filter

This feature allows the user to filter their bank account by the category of their transactions by using the filter [CATEGORY]…​.

4.6.1. Overview

The FilterCommandParser implements Parser with the following operation:

  • FilterCommandParser#parse(): This operation will take in a String input from the user that represents different categories delimited by a whitespace. It will then create a TransactionContainsCategoriesPredicate and passed into a new FilterCommand. Finally, this operation will return the new FilterCommand.

4.6.2. Current Implementation

The filter command is facilitated by the FilterCommandParser and FilterCommand of the application. PalPay filters the list of transactions by checking if any of the specified categories exists in the transaction.

For instance, the command filter breakfast dinner would display a list of transactions with categories of breakfast or dinner or both.

The following class diagram depicts the relations of the FilterCommand, FilterCommandParser and its related classes.

FilterClassDiagram
Figure 11. Class Diagram for Filter

4.6.3. Design Considerations

Aspect: Filtering by multiple categories
  • Alternative 1 (Current Choice): Creating one predicate for all categories to be sorted.

    • Pros: Extremely flexible for the users as they are not limited to the number of categories to be filtered.

    • Cons: Difficult to implement.

  • Alternative 2: Creating a predicate for each category to be sorted.

    • Pros: Easy to implement.

    • Cons: Users can only filter by predicates that have been implemented. Developers have to create a new predicate class to filter a new category.

4.7. View Feature: view

This feature allows the user to switch between the different tabs of the application.

4.7.1. Current Implementation

The view command is facilitated by the MainWindow, MainTabPanel, ViewCommandParser and ViewCommand.

The following activity diagram shows the flow of the view command.

ViewActivityDiagram
Figure 12. Activity Diagram for View

4.8. Split Feature: split

This feature allows the user to pay for a certain item or make a transaction on behalf of his friends. Refer to the UserGuide for usage details.

4.8.1. Current Implementation

The split command is an abstraction of LendMoney class.
Given a list of shares and people, each person is assigned an amount based on the corresponding positional share and the total amount given to split command.
A LendMoney instance is created for each person and executed.

LedgerOperationDiagram
Figure 13. Class diagram for operations that deal with Ledger
SplitBehaviour
Figure 14. Activity diagram for creating a Split object

4.8.2. Design Considerations

Current implementation of Split class encourages code reuse by abstracting the delegating the task of rebalancing to another class.
However, this introduces coupling as the behavior of Split is now inexplicably tied to LendMoney.

Split
Figure 15. Sequence diagram for executing a SplitCommand

4.9. Settle Up Feature: receive

This feature allows another person to send money to the user.
The balance in the Ledger and the balance of the sender is updated accordingly.

4.9.1. Current Implementation

The receive command creates ReceiveMoney class that handles the transfer of fund from another person to the user.

In the handleBalance method of ReceiveMoney, it will find the correct person in the Ledger by name, or create a new Person with given name if it is not already in the Ledger.
Balance of the user and the sender is then updated accordingly.

Code snippet of handleBalance in ReceiveMoney
public class ReceiveMoney extends Payment {
    @Override
    public Amount handleBalance(Amount balance, UniquePersonList peopleInLedger) {
        Person target = super.handleTarget(peopleInLedger);
        target.spend(amount);
        return balance.addAmount(amount);
    }
}

public abstract class Payment extends Transaction implements LedgerOperations {
    protected Person handleTarget(UniquePersonList peopleInLedger) {
        Person personInvolved = person;
        if (peopleInLedger.contains(person)) {
            personInvolved = peopleInLedger.get(person).get();
        } else {
            peopleInLedger.add(person);
        }
        return personInvolved;
    }
}

4.10. Set Budget Feature: set

This feature allows the user to set a budget for a given time period for a category, if specified. The user is allowed to set multiple budgets, but duplicate budgets (budgets with the same identity in terms of amount, date and tag) are not allowed. Upon setting the budget and prior to the deadline, the user’s OutTransaction will deduct the amount from each budget in the list respectively.

4.10.1. Current Implementation

The set command is an extension of parent Command class, facilitated by the Logic and Model components of the application, PalPay
Given an amount and date, a new Budget is set for the user.
Upon setting a new budget, a BudgetCard is created and displayed in a list in the application window till the date set by the user.

4.10.2. Design Considerations

Currently, Budget does not extend from Transaction although the two behave in a similar way. There is an aggregation between Budget and Transaction as the two can exist independent of each other, although an effect on one may also cause an impact on the other. The current design was chosen over the former design of inheritance as there is a stark difference in the two in a way that Budget does not affect the balance of the user’s bank account directly while Transaction does. Hence, by Liskov Substitution Principle, inheritance is not a suitable design.

4.11. Project Balance Feature: project

This feature allows users to project their balance status based on past income and outflows as manifest in their TransactionHistory by using the command project [DATE].

4.11.1. Current Implementation

The project command is facilitated by the Logic and Model components of the application, PalPay

The sequence diagram below demonstrates how the project [DATE] command is handled by the application.

ProjectCommand Sequence Diagram
Figure 16. Sequence Diagram of Project Command

4.11.2. Future Enhancements

Graphical Representation

In future updates, the user’s balance projection will be displayed as a linear graph plotted against time, up until the date specified by the user in the command.

Projection by Category

In future updates, the user will be able to customise projections beyond specifying a single date. Some possible customizations include solely projection income / outflow amounts, and filtered projections based on categories. For instance, project d/22112019 c/Food -o will project the user’s spending (or outflow, as denoted by the -o flag) on Food (specified by the c/Food tag) up until the 22nd of November, 2019 (specified by the d/22112019 tag).

4.11.3. Design Considerations

The project command has multiple possible implementations as to how the projection may be computed. In the current implementation, the projected amount is calculated via the following equation:

Projected Balance = Current Balance - [(Past Income - Past Outflow) / Total Days Elapsed] * Days Until Date of Projection

While this algorithm allows for simple and fast computation, it does not hedge against one-time big purchases. For example, if the user were to buy a computer, his outflow projection is likely to be proportionally larger in the short run.

4.11.4. Alternative Implementations

Linear Regression

In light of the above-mentioned limitation, a possible algorithm to be used is the Gradient Descent algorithm in finding a best fit projection line for the user’s balance. However, this will increase the computational cost of the project function significantly, causing PalPay to run slower overall.

4.12. Logging

We are using java.util.logging package for logging. The LogsCenter class is used to manage the logging levels and logging destinations.

  • The logging level can be controlled using the logLevel setting in the configuration file (See Section 4.13, “Configuration”)

  • The Logger for a class can be obtained using LogsCenter.getLogger(Class) which will log messages according to the specified logging level

  • Currently log messages are output through: Console and to a .log file.

Logging Levels

  • SEVERE : Critical problem detected which may possibly cause the termination of the application

  • WARNING : Can continue, but with caution

  • INFO : Information showing the noteworthy actions by the App

  • FINE : Details that is not usually noteworthy but may be useful in debugging e.g. print the actual list instead of just its size

4.13. Configuration

Certain properties of the application can be controlled (e.g user prefs file location, logging level) through the configuration file (default: config.json).

5. Documentation

Refer to the guide here.

6. Testing

Refer to the guide here.

7. Dev Ops

Refer to the guide here.

Appendix A: Product Scope

Target user profile:

  • has a need to manage a significant number of contacts

  • prefer desktop apps over other types

  • can type fast

  • prefers typing over mouse input

  • is reasonably comfortable using CLI apps

Value proposition: manage contacts faster than a typical mouse/GUI driven app

Appendix B: User Stories

Priorities: High (must have) - * * *, Medium (nice to have) - * *, Low (unlikely to have) - *

Priority As a …​ I want to …​ So that I can…​

* * *

data-oriented person

see an overview of my transactions in an intuitive graph

gain insights at a glance

* * *

new user

see usage instructions

refer to instructions when I forget how to use the App

* * *

student

input my spending into different categories

manage my expenses better

* * *

visual person

see how much budget I have left in each category

cut down on spending as necessary

* * *

student with many friends

split the bill with my friends

know how much I should payment for a meal

* * *

student who forgets to payment his debt on time

be reminded to payment my debt before the deadline

stop incurring interests

* *

patriotic Singaporean who travels to JB often

easily calculate how much Ringgit to bring

enjoy my holiday with insufficient money

* *

thrifty person

see how my savings or spending will project into the future

plan my budget

*

user who forgets to save money

be incentivized me to save money

be motivated to not overspend/save money

{More to be added}

Appendix C: Use Cases

(For all use cases below, the System is the PalPay and the Actor is the user, unless specified otherwise)

Use case: Add an income

MSS

  1. User requests to add an income amount.

  2. PalPay adds the income amount.

    Use case ends.

Extensions

  • 1a. Amount entered by the user is invalid.

    • 1a1. PalPay shows an error message.

      Use case resumes at step 1.

Use case: Delete expense

MSS

  1. User requests to view spending.

  2. PalPay shows the list of expenses since beginning of time.

  3. User requests to delete an expense.

  4. PalPay deletes the specified expense.

    Use case ends.

Extensions

  • 1a. User speicified days passed since.

    • 1a1. PalPay shows the list of expenses since the time period specified.

      Use case resumes at step 3.

{More to be added}

Appendix D: Non Functional Requirements

  1. Should work on any mainstream OS with JDK 11 or above installed.

  2. A user with above average typing speed for regular English text should be able to accomplish most of the tasks faster using commands than using the mouse.

  3. Upon user input, PalPay should execute tasks (and display results) within 1 second.

  4. Users should have (and be able to specify) default options such that they can issue minimal commands for common tasks.

  5. Should be quick and efficient, with each user session lasting no longer than 3 minutes to effectively manage his current financial state.

  6. Should not make users feel defeated, but rather empowered in managing their finances.

Appendix E: Glossary

Mainstream OS

Windows, Linux, Unix, OS-X

Private contact detail

A contact detail that is not meant to be shared with others

Appendix F: Product Survey

Product Name

Author: …​

Pros:

  • …​

  • …​

Cons:

  • …​

  • …​

Appendix G: Instructions for Manual Testing

Given below are instructions to test the app manually.

These instructions only provide a starting point for testers to work on; testers are expected to do more exploratory testing.

G.1. Launch and Shutdown

  1. Initial launch

    1. Download the jar file and copy into an empty folder

    2. Double-click the jar file
      Expected: Shows the GUI with a set of sample contacts. The window size may not be optimum.

  2. Saving window preferences

    1. Resize the window to an optimum size. Move the window to a different location. Close the window.

    2. Re-launch the app by double-clicking the jar file.
      Expected: The most recent window size and location is retained.

{ more test cases …​ }

G.2. Deleting a Person

  1. Deleting a person while all persons are listed

    1. Prerequisites: List all persons using the list command. Multiple persons in the list.

    2. Test case: delete 1
      Expected: First contact is deleted from the list. Details of the deleted contact shown in the status message. Timestamp in the status bar is updated.

    3. Test case: delete 0
      Expected: No person is deleted. Error details shown in the status message. Status bar remains the same.

    4. Other incorrect delete commands to try: delete, delete x (where x is larger than the list size) {give more}
      Expected: Similar to previous.

{ more test cases …​ }

G.3. Saving Data

  1. Dealing with missing/corrupted data files

    1. {explain how to simulate a missing/corrupted file and the expected behavior}

{ more test cases …​ }