Skip to content

[CS2113-W12-4] FinTrack#5

Open
JordanTwz wants to merge 486 commits into
nus-cs2113-AY2526S1:masterfrom
AY2526S1-CS2113-W12-4:master
Open

[CS2113-W12-4] FinTrack#5
JordanTwz wants to merge 486 commits into
nus-cs2113-AY2526S1:masterfrom
AY2526S1-CS2113-W12-4:master

Conversation

@JordanTwz
Copy link
Copy Markdown

FinTrack helps NUS Computer Engineering students to track their finances. It is optimised for CLI users so that expenses can be recorded faster by typing in commands.

@duckyfuz duckyfuz force-pushed the master branch 2 times, most recently from 297a1f5 to b9612c8 Compare October 1, 2025 04:35
danielkwan2004 pushed a commit to danielkwan2004/tp that referenced this pull request Oct 1, 2025
…an2004-AboutUs

Modify aboutus.md to include Daniel Kwan
Copy link
Copy Markdown

@syCHEN1645 syCHEN1645 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall good job! Your code is mostly of good standard and quality. I see there are many assertion messages which look like errors or warnings for the user, so just a reminder that assertions cannot replace exceptions in error handling (please refer to the course website for why) in case some of you might have got it wrong.

/**
* Main entry-point for the FinTrack application.
*/
public static void main(String[] args) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The main method seems a bit long. Maybe more abstraction here?

return 0.0;
}

return getExpensesView().stream()
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks a bit complicated!

public double getTotalExpense() {
double sum = 0;
for (Expense expense : expenses) {
assert expense != null : "Expense should not be null.";
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hope you are not using assertion to handle errors, as it is only meant to help developers verify the code.

amount = Double.parseDouble(amountStr);
} catch (NumberFormatException e) {
LOGGER.log(Level.WARNING, "Invalid amount format: {0}.", amountStr);
throw new IllegalArgumentException("Amount must be a valid number.");
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good error handling! Maybe can organise the error messages into string constants, especially if they are reused somewhere else?

*/
public class ExpenseList extends ArrayList<Expense> {

/** Comparator that orders expenses in reverse chronological order (newest first). */
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please follow the same format (leave out 1st and last lines) as other comments.

return changed;
}

/* ========== Validation & Invariants ========== */
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't seem to be in standard format? Remeber to remove it if it is no longer needed.

Copy link
Copy Markdown

@jyx0615 jyx0615 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall, the DG looks great and includes many useful diagrams.
Just a quick reminder — don’t forget to add the : before the entities.

Comment thread docs/DeveloperGuide.md Outdated
#### Reading User Input
`waitForInput()` owns the blocking read from `System.in` via a shared `Scanner`. The method prints a consistent `> ` prompt, trims whitespace, and returns an empty string when the user simply presses enter. If the input stream is closed or the scanner encounters an illegal state, the method logs the failure (`SEVERE`) and returns `EXIT_COMMAND`; this sentinel gives the caller a deterministic way to trigger a graceful shutdown without duplicating exception handling logic. Unexpected runtime exceptions are rethrown after being logged so they can be surfaced during development.

![img_1.png](images/img_1.png)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems like that the entities in a sequence diagram are objects not the method calls

Screenshot 2025-10-29 at 10 18 45 AM

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe there's no need to include system method calls in the sequence diagram.

Comment thread docs/DeveloperGuide.md

The internal logic for `parseAddExpense` is shown below in this sequence diagram:

![parser.png](images/parser.png)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The activation bar seems to be too long.
Screenshot 2025-10-29 at 10 30 39 AM

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe use the same tool for all diagrams to keep the style consistent.

Comment thread docs/DeveloperGuide.md Outdated

`printListOfIncomes(...)` and `printListOfExpenses(...)` render collections supplied by the model. Both methods iterate defensively: each entry is validated inside the loop, and malformed records are skipped with a `WARNING` log instead of aborting the entire render. Both incomes and expenses are shown newest first to surface recent cash flows. Each row is wrapped with a 80-character horizontal divider to improve readability, and dates are standardised to `yyyy-MM-dd` via a local `DateTimeFormatter`.

![img.png](images/img.png)
Copy link
Copy Markdown

@jyx0615 jyx0615 Oct 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same problem as previous. It seems like that the entities in a sequence diagram are objects not the method calls.

Screenshot 2025-10-29 at 10 51 13 AM

Comment thread docs/DeveloperGuide.md
5. When `list-budget` is called, `Ui` prints a list of the budgets by calling `printBudgets` which receives a printable version of all the budgets which we get from `getBudgetsView()`.

Below is the sequence diagram of an instance of `budget` and `add-expense`:
![budget.png](images/budget.png)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to clarify — does ok refer to a string or a variable here?

Screenshot 2025-10-29 at 10 42 52 AM

Comment thread docs/diagrams/budget.puml Outdated
Parser --> FinTrack: (category, amount)
FinTrack -> FM: setBudget(category, amount)
FM --> FinTrack: ok
FinTrack -> Ui: printBudgetSet(category, amount)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this format correct? Should there be a return arrow indicating a success/failure message right below this?

Comment thread docs/diagrams/budget.puml Outdated
FinTrack -> Parser: parseSetBudget(command)
Parser --> FinTrack: (category, amount)
FinTrack -> FM: setBudget(category, amount)
FM --> FinTrack: ok
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does "ok" mean? Please specify

Comment thread docs/diagrams/summary_expense.puml Outdated
else
Ui -> Ui: print "Here is a breakdown of your expense:"
loop for each (category, amount) in expenseByCategory
Ui -> Ui: percent = (amount / totalExpense) * 100.0
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Image

Ideally, your Ui component should not handle any calculations. Try to have FinanceManager perform this calculation, as it seems to be in charge of all calculations.

Comment thread docs/DeveloperGuide.md
5. `totalExpense` and `expenseByCategory` is then fed into a function in `Ui` called `printSummaryExpense` to print the summary.

Below is a sequence diagram to illustrate how summary-expense works:
![summary_expense.png](images/summary_expense.png)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Image

This check for "expenseByCategory is empty" could be redundant as totalExpense is <= 0 when expenseByCategory is empty and also when expenseByCategory contains zero-amount responses.
Thus, you could replace it with a single check e.g. "alt (no expenses recorded)"

Comment thread docs/DeveloperGuide.md
5. When `list-budget` is called, `Ui` prints a list of the budgets by calling `printBudgets` which receives a printable version of all the budgets which we get from `getBudgetsView()`.

Below is the sequence diagram of an instance of `budget` and `add-expense`:
![budget.png](images/budget.png)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Image

What does "ok" mean or refer to? Please be more specific.

Comment thread docs/DeveloperGuide.md
5. When `list-budget` is called, `Ui` prints a list of the budgets by calling `printBudgets` which receives a printable version of all the budgets which we get from `getBudgetsView()`.

Below is the sequence diagram of an instance of `budget` and `add-expense`:
![budget.png](images/budget.png)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Image

Is this format correct? Could there be return arrows labelled successMessage signifying whether the command executed by the user was successful or not?

Comment thread docs/DeveloperGuide.md
5. `totalExpense` and `expenseByCategory` is then fed into a function in `Ui` called `printSummaryExpense` to print the summary.

Below is a sequence diagram to illustrate how summary-expense works:
![summary_expense.png](images/summary_expense.png)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Image

Ideally, Ui should not perform this calculation as it should strictly receive data and display it. Perhaps consider having FinanceManager handle this as it is in charge of calculations.

Comment thread docs/DeveloperGuide.md Outdated

The following is an example class diagram that encapsulates the role of `FinTrack` and other modules `FinanceManager`, `Ui` and `Parser` when running `add-expense`:

![FinTrack.png](images/FinTrack.png)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove nonstandard << static >> and class icon from class diagram

Comment thread docs/DeveloperGuide.md Outdated
#### Reading User Input
`waitForInput()` owns the blocking read from `System.in` via a shared `Scanner`. The method prints a consistent `> ` prompt, trims whitespace, and returns an empty string when the user simply presses enter. If the input stream is closed or the scanner encounters an illegal state, the method logs the failure (`SEVERE`) and returns `EXIT_COMMAND`; this sentinel gives the caller a deterministic way to trigger a graceful shutdown without duplicating exception handling logic. Unexpected runtime exceptions are rethrown after being logged so they can be surfaced during development.

![img_1.png](images/img_1.png)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logger not necessary for sequence diagram

Comment thread docs/DeveloperGuide.md
{Describe the design and implementation of the product. Use UML diagrams and short code snippets where applicable.}
This section describes the overall architecture and explores the core classes of FinTrack.

### Architecture
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

well structured section that explains the separation between classes

Comment thread docs/DeveloperGuide.md
## Non-Functional Requirements

{Give non-functional requirements}
### Performance
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good review of the project from usability point of view

@limeiy1
Copy link
Copy Markdown

limeiy1 commented Oct 29, 2025

Is the class meant to be labelled as static in <<>>?

Screenshot 2025-10-29 at 1 47 13 PM

@limeiy1
Copy link
Copy Markdown

limeiy1 commented Oct 29, 2025

Screenshot 2025-10-29 at 2 06 51 PM Maybe can keep the use of activation bar consistent? The activation bar for Ui disappears in [not empty]

@limeiy1
Copy link
Copy Markdown

limeiy1 commented Oct 29, 2025

Screenshot 2025-10-29 at 2 12 14 PM Similar to previous comment, maybe can consider removing activation bars, if not add the activation bars for FinTrack and Ui?

@limeiy1
Copy link
Copy Markdown

limeiy1 commented Oct 29, 2025

Screenshot 2025-10-29 at 2 15 19 PM Is the activation bar for parser too long? It starts before the method call

duckyfuz and others added 30 commits November 3, 2025 23:11
Fix visual bug on forced termination
…bugging

Improve editability of persistence file, update UG, DG, PPP
Update PPP with ASCII guard, regex checks, and merged PRs
Update summary-expense sequence diagram
Update UG to clarify modifying budgets
Add exceeding or near budget checks when adding budget after existing…
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

10 participants