Welcome to the Developer Guide of đȘNUScentsđȘ where we have written documentation with regards to the design and implementation of the App. In addition, we added other related information like the product scope, user stories, non-functional requirements, glossary and instructions for testing
Referred to addressbook-level3 when drafting this Developer Guide.
This project has been heavily modified from Spaceman Task Manager.
Thanks to Dr Akshay Narayan (module coordinator) and Irving (TA) for their guidance throughout the course of this project.
The Architecture Diagram given below explains the high-level design of the đȘNUScentsđȘ App. It depicts and provides a quick overview of how the core components interact with each other.
Nuscents
is in charge of the app launch and shut down.
The bulk of the appâs work is done by the following five components:
Below is a simplified class diagram of the system:
The ui
packages consists of the Ui
class and the Messages
class.
The UI
component prompts and reads commands from the user.
The UI
component is also responsible for printing output to the user.
TransactionList
, Storage
, Nuscents
, and Command
use Ui
to print output (including errors) to the user.
The Data component stores the transaction data i.e., all Transaction
objects in a TransactionList
object.
Each Transaction
object stores the information for an Allowance
or an Expense
.
The Command component holds the different types of commands available. All the commands inherit from the abstract
Command
class, which contains the execute
method.
The ListOfCommands
is used by Parser
to determine if the entered command is a valid one or not.
If it is not valid, an object of class InvalidCommand
will be constructed. The execute
method of the
InvalidCommand
class simply raises an exception that an invalid command has been entered, which will be shown
to the user.
The Parser
component creates various Command
and Transaction
objects based on the userâs input.
For example, if the user input is to add an expense, an Expense
and AddCommand
object will be created.
Parser
also uses ExpenseCategory
, AllowanceCategory
, and TransactionCategory
for creating expenses,
creating allowances, and filtering transactions respectively.
The Storage
component reads/writes from/to the ArrayList in TransactionList
depending on if the application is
starting or if a command has just been executed.
Storage
also uses Parser
to parse data from the storage file when the application starts up.
add
Transaction FeatureThe add transaction feature is facilitated by the Parser
class which parses user input and creates a Expense
or
Allowance
object which extends from the Transaction
class. The created Transaction
object will be stored in a
TransactionList
.
Given below is an example usage scenario and how the add transaction mechanism behaves at each step.
Step 1: The user launches the application for the first time. The TransactionList
will be initialized.
Step 2: The user executes expense /amt 20 /date 24-10-2023 /desc Lunch /note Pasta /cat Food
command to create a
transaction. The expense
command calls Parser#parseExpense()
to create an Expense
object. The
AddCommand#execute()
is then called to store the Expense
object in the TransactionList
.
The following sequence diagram shows how the add transaction operation works:
list
Transactions FeatureThis section lists the components involved in the list
transactions feature:
This section describes each componentâs role for the list
transaction feature:
showTransactionList()
method from Ui
.TransactionList.getTransactions()
, which gets the Transactions in the TransactionList
.getTransactions()
method returns all the Transactions in the TransactionList
.An alternative would be to list all the transactions directly in Parser
upon receiving a list command, however, to
promote separation of concerns and to keep code more readable, we decided not to take up this approach.
Step 1: User launches the application. TransactionList
is initialized.
Step 2: User inputs list
to list all transactions. The Parser identifies the command.
Step 3: A ListCommand
is created. This command is passed to Nuscents
.
Step 4: Nuscents
executes the ListCommand
, which invokes Ui.showTransactionList()
and Ui.showBudgetExpense()
.
Step 5: Ui.showTransactionList()
calls TransactionList.getTransactions()
, which gets the Transactions in the TransactionList.
Step 6: The transactions in TransactionList
are displayed to the user.
Step 7: Ui.showBudgetExpense()
calls TransactionList.getBudget()
, which gets the current budget set in the TransactionList.
Step 8: The budget details in TransactionList
are displayed to the user.
The following sequence diagram shows how the list transaction operation works:
Additionally, the list transaction feature further computes and displays the net balance amount based on the
following formula (net balance = total allowance amount - total expense amount). The showTransactionList()
method in
the Ui
class calls TransactionList.getNetBalance()
, which iterates through the list of transactions in the list to determine the net balance.
The net balance is then shown to the user.
view
Transaction FeatureThis section lists the components involved in the view
transaction feature:
This section describes each componentâs role for the view
transaction feature:
While the current design is deemed suitable for our application, we did consider alternative approaches, such as integrating the view transaction functionality directly within the Nuscents class without introducing a ViewCommand. However, we opted for the current design to promote a cleaner separation of concerns and to facilitate future expansions and modifications.
Step 1: User launches the application. The TransactionList initializes.
Step 2: User inputs view 2 to view the second transaction. The Parser identifies the command and extracts 2 as the taskIndex.
Step 3: A ViewCommand is created with taskIndex 2. This command is passed to the Nuscents class.
Step 4: Nuscents executes the ViewCommand, which invokes the viewTransaction method on TransactionList with taskIndex 2.
Step 5: TransactionList retrieves the second Transaction object and returns it to Nuscents.
Step 6: Nuscents passes the Transaction object to the UI, which displays the transaction details through the showTransactionViewMessage method.
The following sequence diagram shows how the view transaction operation works:
edit
Transaction FeatureThis section details the components involved in the edit
transaction feature:
EditCommand
object with the appropriate parameters.Command
class, encapsulating the âeditâ action along with the index and the new transaction details.execute()
method of EditCommand
.Expense
and Allowance
.Hereâs how each component plays a role in the edit
transaction feature:
Transaction
object.TransactionList
.execute()
method of EditCommand
and handles exceptions that may arise.editTransaction(index, transaction)
method to update transactions at a specific index.An alternative design considered was to have EditCommand
interact directly with Transaction
objects to modify their fields. However, this approach was discarded in favor of having a clear separation where TransactionList
manages all transactions, maintaining encapsulation and single responsibility principles.
Step 1: User starts the application, and TransactionList
is initialized with existing transactions.
Step 2: The user inputs edit 2 expense /amt 100 /date 01-01-2023 /desc Movie night
. The Parser
reads the input, separating the index from the rest of the transaction details.
Step 3: Parser
calls parseExpense
to create an Expense
object and then constructs an EditCommand
with the index and the new Expense
.
Step 4: Nuscents
receives and invokes the EditCommand
âs execute()
method.
Step 5: Inside execute()
, EditCommand
uses TransactionList
âs editTransaction(index, transaction)
to replace the existing transaction.
Step 6: TransactionList
updates the transaction at the given index. If the index is invalid, an exception is thrown.
Step 7: Upon successful update, UI
displays a confirmation message. If an error occurs, an error message is shown instead.
help
FeatureThe helpCommand
feature serves as an informative component to assist users unfamiliar with the application commands. It integrates the following components:
help
command.help
command, and provides command details when executed.execute()
method of the HelpCommand
.This section describes each componentâs role for the help
feature:
Parser
class recognizes the userâs intention to access the help menu through the help
keyword.Parser
identifies a help
command, it instantiates a HelpCommand
object. This object encapsulates the userâs request to view the command instructions.HelpCommand
object, the Nuscents
class triggers the execute()
method of the HelpCommand
.UI
class is then responsible for fetching the HELP_MENU
static string from the HelpCommand
class and displaying it to the user. This ensures the user receives a comprehensive list of commands available in the application.Initially, we pondered whether to embed the help details directly within the main application class, Nuscents
. This would eliminate the need for a separate HelpCommand
class. However, segregating the HelpCommand
ensures better modularity, making future expansions or modifications seamless.
help
Usage ScenarioStep 1: The user launches the application. The initial screen appears.
Step 2: Unsure of the commands, the user inputs the help
command.
Step 3: The application recognizes the command through the Parser
and creates a HelpCommand
object.
Step 4: The Nuscents
class invokes the execute()
method of the HelpCommand
.
Step 5: The UI
fetches the HELP_MENU
string and displays the comprehensive list of commands to the user.
filter
FeatureThis section lists the components involved in the filter
transaction feature:
This section describes each componentâs role for the filter
feature:
Step 1: User inputs filter entertainment to filter transactions by the âentertainmentâ category. The Parser identifies the command and uses parseFilterCategory to extract âentertainmentâ as the category.
Step 2: A FilterCommand object is created with the category set to âentertainmentâ. This command is then passed to the Nuscents class.
Step 3: In Nuscents, the execute() method of the FilterCommand is called. It invokes the filterTransaction method on the TransactionList with the category âentertainmentâ.
Step 4: TransactionList filters its transactions based on the âentertainmentâ category. If matching transactions are found, it returns them; otherwise, it indicates that no transactions are found.
Step 5: Depending on the outcome in Step 4, Nuscents instructs the UI to either display the list of filtered transactions and their net balance (using showFilterMessage) or to show a message indicating no transactions were found in the specified category (using showFilterNotFoundMessage).
The following sequence diagram shows how the view transaction operation works:
budget
FeatureThe budget
feature allows users to set a budget by specifying a float value.
This budget is then stored persistently in a budget.txt
file.
Hereâs how it works:
This section lists the components involved in the budget
transaction feature:
budget
command and extracts the float value.budget
command.execute()
method of the BudgetCommand
.budget.txt
file.This section describes each componentâs role for the budget
feature:
budget
command and extracts the float value.execute()
method of the BudgetCommand
. It then calls the setBudget()
method.budget.txt
file. It stores the budget persistently.Step 1: User inputs budget 50
. The Parser recognizes the command and extracts the budget value of 50.
Step 2: A BudgetCommand object is created with the budget value of 50. This command is then passed to the Nuscents class.
Step 3: Nuscents executes the BudgetCommand, which invokes the setBudget()
method and sets the budget value of 50.
Step 4: Storage writes the budget value to the budget.txt
file, making it persistent.
The list
feature now incorporates information about the budget
It prompts the user with a message whether they are approaching or exceeding their budget.
To ensure the persistence of the budget and proper initialization, the following steps are taken:
budget.txt
file. If found, it reads the budget value and initializes the budget
variable. If not found, there is no budget initialized (set to 0).budget.txt
file. It ensures that the budget is persistently stored and can be retrieved when needed.
These additions provide users with a warning feature, enhancing the financial tracking capabilities of đȘNUScentsđȘ. Users can now set a budget, and the application will inform them about their spending status concerning the budget within the list
feature.Version | As a ⊠| I want to ⊠| So that I can ⊠|
---|---|---|---|
v1.0 | new user | access a help command that lists all actions and examples | I can learn how to use the tracker effectively |
v1.0 | university student | add my allowance | I can track how much I get every month |
v1.0 | university student | add my expenses | I can keep track of my spending habits |
v1.0 | university student | delete allowance entries | I can remove wrong entries |
v1.0 | university student | delete expense entries | I can remove wrong entries |
v1.0 | university student | view a list of all entries | I can view my all my income and expenses at a glance |
v2.0 | university student | add details of income or expenses | I can know why I made that transaction |
v2.0 | university student | enquire my net balance | I can see my net balance |
v2.0 | university student | edit existing entries | I can correct wrong entries or make updates |
v2.0 | university student | create a budget for my living expenses | I can ensure I have enough funds throughout the semester |
v2.0 | university student | add details of income or expenses | I can see my expenses on different categories |
v2.0 | university student | filter expenses based on categories | I can view my expense on a specific category |
v2.0 | university student | filter income based on categories | I can view my income from a specific source |
v2.0 | university student | filter expenses based on categories | I can view my expense on a specific category |
v2.0 | university student | view details of income or expenses | I can have a better understanding of my financial habit |
Response Time: The system should respond to CLI commands within a maximum acceptable time of 1 second to ensure users receive quick feedback.
Throughput: The system should only be expected to handle one transaction at a time to ensure that there are no conflicts in transactions.
Availability: The system should have an availability of at least 99.9%, ensuring it is accessible to users for the majority of the time.
Error Handling: The system should demonstrate proper fault tolerance and error handling by recovering gracefully from any failure or unexpected errors, ensuring uninterrupted service.
Access Control: Access to financial data and CLI commands should be restricted based on individual users. đȘNUScentsđȘ is designed to be used by only one person per system. Hence, there is no sharing of financial data or transactions.
Data Scalability: The system should be able to scale horizontally to accommodate with the increase in the volume of financial data without a significant impact on performance.
CLI User Interface Design: The CLI should follow a user-friendly design, with clear and intuitive commands, prompts, and feedback messages to enhance the user experience. In addition, there is a âhelpâ option that guides the user on how to use the different possible commands.
User Documentation: We have created a user guide with examples to assist users in understanding and utilizing the features of đȘNUScentsđȘ.
Operating System Compatibility: The CLI should be compatible with major operating systems, including Windows, macOS, and Linux.
CLI Portability: Ensure that the CLI is portable across different environments and platforms, allowing users to use đȘNUScentsđȘ consistently regardless of their setup.
Data Migration: Establish procedures for migrating financial data when moving the system to a different environment, ensuring data integrity and a smooth transition.
Code Maintainability: Follow industry best practices for coding standards, and maintain clear and well-documented code to facilitate easy understanding and future maintenance.
Transaction Logs: Define a logging mechanism that captures relevant information for storage functions. Logs should be stored securely and be available for auditing purposes.
Please refer to User Guide for example user inputs. You may also vary the user input to an invalid one to see that the program handles it correctly.
Here are some example invalid inputs to test:
foo bar
allowance /amt -100 /desc negative /date 10-10-2010
expense /amt 100 /desc missing date
filter non-existent-category
delete 0
budget -100
view first index
edit first index