Skip to content
This repository was archived by the owner on Jun 19, 2026. It is now read-only.

Dynamic Budget Suggestions with confidence scoring and trend analysis (#73) - #79

Open
aliraza556 wants to merge 12 commits into
rohitdash08:mainfrom
aliraza556:feat/dynamic-budget-suggestions
Open

Dynamic Budget Suggestions with confidence scoring and trend analysis (#73)#79
aliraza556 wants to merge 12 commits into
rohitdash08:mainfrom
aliraza556:feat/dynamic-budget-suggestions

Conversation

@aliraza556

Copy link
Copy Markdown

Summary

Implements the Dynamic Budget Suggestions feature (Issue #73) that suggests budget limits
using past spending patterns to improve onboarding and financial guidance.

What changed

  • Backend: Budget suggestion engine (services/ai.py) — Rewrote the heuristic budget algorithm to analyze 3–6 months of historical spending data using weighted averages (recent months weighted higher). Computes a confidence score based on data availability, detects per-category spending trends (increasing/decreasing/stable), and generates actionable budget limits with a 50/30/20 breakdown.

  • Backend: API endpoint (routes/insights.py) — Enhanced /insights/budget-suggestion with month (YYYY-MM) and months (3-6) query parameters. Added Redis caching with 30-minute TTL and input validation.

  • Backend: Cache invalidation (routes/expenses.py, services/cache.py) — Added budget_suggestion_key and ensured budget suggestion cache is cleared when expenses are created, updated, or deleted.

  • Backend: OpenAPI spec (openapi.yaml) — Updated endpoint documentation with new query parameters and response schemas (BudgetSuggestion, ConfidenceScore, CategorySuggestion).

  • Frontend: API client (api/insights.ts) — New TypeScript API client with full type definitions for the budget suggestion response.

  • Frontend: Budgets page (pages/Budgets.tsx) — Replaced static content with a dynamic dashboard showing suggested budget, spending trend, 50/30/20 breakdown, per-category suggestions with trend indicators, and monthly spending history bars. Includes 3/6 month toggle and refresh button.

  • Tests (tests/test_budget_suggestions.py) — 18 comprehensive tests covering no-data defaults, single/multi-month analysis, confidence scoring, trend detection (increasing/decreasing/stable), lookback parameter clamping, income exclusion, 50/30/20 breakdown accuracy, and monthly history.

  • Dependency (requirements.txt) — Added python-dateutil for reliable month arithmetic via relativedelta.

Closed: #73

Acceptance Criteria

  • Uses 3–6 month historical spending data
  • Provides confidence score (0-100% with labels: no_data, low, medium, high, very_high)
  • Per-category budget suggestions with trend analysis
  • Falls back to OpenAI when API key is configured
  • Redis caching with automatic invalidation on expense changes
  • 18 backend tests all passing

ScreenShorts:

image image image

Test Plan

  • Run docker compose up --build — all services start successfully
  • Run docker compose run --rm backend python -m pytest -v tests/ — 28/28 tests pass
  • Register a new user, add expenses across 2+ months, verify budget suggestions
    update with real data on the Budgets page
  • Toggle between 3 Months and 6 Months — verify data range updates
  • Click Refresh — verify fresh data is fetched
  • Verify confidence score increases as more months of data are added
  • Verify spending trends correctly show increasing/decreasing/stable

## Files Changed (9 files, +1303 / -316 lines)

| File | Change |
|------|--------|
| `app/src/api/insights.ts` | New — TypeScript API client + types |
| `app/src/pages/Budgets.tsx` | Modified — Dynamic budget dashboard |
| `packages/backend/app/openapi.yaml` | Modified — API spec with new schemas |
| `packages/backend/app/routes/expenses.py` | Modified — Cache invalidation for budget suggestions |
| `packages/backend/app/routes/insights.py` | Modified — Enhanced endpoint with params + caching |
| `packages/backend/app/services/ai.py` | Modified — Multi-month heuristic engine |
| `packages/backend/app/services/cache.py` | Modified — Added budget_suggestion_key |
| `packages/backend/requirements.txt` | Modified — Added python-dateutil |
| `packages/backend/tests/test_budget_suggestions.py` | New — 18 tests for budget suggestions |

@aliraza556

Copy link
Copy Markdown
Author

@rohitdash08 The checks have passed. Please review the code and share your feedback.

@rohitdash08

Copy link
Copy Markdown
Owner

Hi @aliraza556, looks good to me but we have some modification related to your PR as per now this is not providing insights you should add persona instead of system prompt. also can you confirm did you check with your openai api key as it was failing to generate insight for the changes you made.

Could you please share your Discord?

- Replace single user prompt with system persona + user data pattern
- Add response_format for reliable JSON output
- Include insights field in AI response
- Log OpenAI failures instead of silently swallowing errors
@aliraza556

Copy link
Copy Markdown
Author

Hi @rohitdash08, thanks for the feedback! I've fixed the OpenAI integration — added a proper FinMind persona as the system message instead of the old single-prompt approach, enabled JSON response format so it won't fail to parse, and added an insights field to the output. Also added error logging so failures are visible now instead of silently falling back. My Discord is aliraza_804, feel free to reach out there.

@rohitdash08

Copy link
Copy Markdown
Owner

@aliraza556, our tests are still failing. Can you please share your test script here?

@aliraza556

Copy link
Copy Markdown
Author

Hi @rohitdash08, here's the full test script — tests/test_budget_suggestions.py. It covers all the key scenarios:

Test Categories:

  • Endpoint returns suggestion with no data (default budget)
  • Single month and multi-month data handling
  • Data range reflects actual months with data
  • Monthly totals included in response
  • Lookback param (3 months / 6 months / clamped values)
  • Custom month param accepted
  • Invalid month format rejected
  • Income excluded from suggestions
  • Confidence scoring (0 months = 0%, more months = higher confidence)
  • Trend detection (increasing / decreasing / stable)
  • Monthly history per category
  • Breakdown sums to suggested total
  • Default 50/30/20 breakdown ratios

How to run:

docker compose run --rm -e PYTHONPATH=/app backend pytest tests/test_budget_suggestions.py -v

All 18 tests pass locally. Can you share the error output so I can check what's failing on your end?

@rohitdash08

rohitdash08 commented Feb 16, 2026

Copy link
Copy Markdown
Owner

@aliraza556, it's only related to the budget of the consumer and all I can see here the tests are related to the changes you made.

Please resolve the comments and I still can't see openai/gemini integration here, feel free to use gemini free api here

@rohitdash08

Copy link
Copy Markdown
Owner

@aliraza556, I'm having trouble to add you on discord. Can you please add me @geekster007
so that I can help you here?

@aliraza556

Copy link
Copy Markdown
Author

@aliraza556, I'm having trouble to add you on discord. Can you please add me @geekster007 so that I can help you here?

@rohitdash08 Sure

@aliraza556

Copy link
Copy Markdown
Author

@aliraza556, it's only related to the budget of the consumer and all I can see here the tests are related to the changes you made.

Please resolve the comments and I still can't see openai/gemini integration here, feel free to use gemini free api here

Hi @rohitdash08, I've added Gemini integration for the budget suggestions — it now uses the free Gemini API as the primary AI provider since we don't have an OpenAI key set. The priority chain is: Gemini -> OpenAI -> Heuristic fallback. Also added the FinMind persona, an insights field in the response, and proper error logging. All 18 budget tests + other tests still pass.

@rohitdash08

Copy link
Copy Markdown
Owner

@aliraza556, again I'm saying it's not specific to the budget contraint. The priority chain is like user can provide their free gemini api key and get the insights if they don't have openai key. Persona still need to be improved we are still getting test failure for your PR

@aliraza556

aliraza556 commented Feb 16, 2026

Copy link
Copy Markdown
Author

@aliraza556, again I'm saying it's not specific to the budget contraint. The priority chain is like user can provide their free gemini api key and get the insights if they don't have openai key. Persona still need to be improved we are still getting test failure for your PR

Hi @rohitdash08, I understand — the Gemini integration is already set up as a general fallback: if user has Gemini key → use Gemini, if OpenAI key → use OpenAI, otherwise → heuristic. I've also updated the default model to gemini-2.0-flash since gemini-1.5-flash was returning 404.

@rohitdash08

rohitdash08 commented Feb 16, 2026

Copy link
Copy Markdown
Owner

@aliraza556, I think you're aligned with the requirement which I told you on discord feel free to ask please change it back to gemini-1.5-flash in your next commit

- Add 25 mocked tests for Gemini/OpenAI integration covering API calls,
  persona verification, fallback chain, JSON parsing, and error handling
- Improve FinMind persona with structured sections (Expertise, Personality,
  Rules) for richer AI-generated insights
- Revert default model to gemini-1.5-flash (confirmed working)
- All 50 tests pass with black and flake8 clean
@aliraza556

Copy link
Copy Markdown
Author

@aliraza556, I think you're aligned with the requirement which I told you on discord feel free to ask please change it back to gemini-1.5-flash in your next commit

@rohitdash08 Done

@rohitdash08

rohitdash08 commented Feb 16, 2026

Copy link
Copy Markdown
Owner

@aliraza556, still failing the tests resolve the comments.
are you having some trouble can you created the demo for this as well?

you can use the mock data for insights testings

@aliraza556

Copy link
Copy Markdown
Author

Hi @rohitdash08, I've fixed the formatting issue and added comprehensive AI integration tests. Here's the local test run:
53/53 tests pass — includes:

  • 18 heuristic budget tests (no data, single/multi month, trends, confidence, 50/30/20)
  • 6 Gemini integration tests (mocked API, persona in prompt, markdown fence parsing, fallback)
  • 3 OpenAI integration tests (mocked client, system persona, fallback)
  • 4 fallback chain tests (Gemini → OpenAI → heuristic priority)
  • 6 JSON parsing tests
  • 3 persona validation tests
  • 13 existing tests (auth, bills, categories, dashboard, expenses)

Also: black --check . and flake8 . both clean.

Model reverted to gemini-1.5-flash as requested. Could you approve the CI workflow run for the latest commit? It shows "Action required" since it's a fork PR.

image

@rohitdash08 rohitdash08 left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

@aliraza556 , also please resolve the merge conflicts

Comment thread packages/backend/app/services/ai.py Outdated
)


def _openai_budget(uid: int, ym: str, lookback: int = MAX_MONTHS):

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

change the method name

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

any update on this?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

@rohitdash08 I am on it.

Comment thread packages/backend/app/services/ai.py Outdated
return _heuristic_budget(uid, ym, lookback)


FINMIND_PERSONA = (

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

improve the persona, this should analyze the manual input as well

Comment thread packages/backend/app/services/ai.py Outdated
"rising you say so clearly. You always use the 50/30/20 rule "
"(needs/wants/savings) as a starting framework and adjust based on "
"the user's actual patterns. You respond ONLY with valid JSON."
"You are FinMind, a certified personal finance advisor and data analyst "

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Don't put finmind, it should be financial analyst

Comment thread packages/backend/app/services/ai.py Outdated
"2. Highlight the single biggest saving opportunity first.\n"
"3. Provide at least 2 actionable tips tied to specific categories.\n"
"4. Include short motivational insight (one sentence).\n"
"5. Respond ONLY with valid JSON — no markdown, no commentary."

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

persona is still lacking @aliraza556

aliraza556 added 3 commits March 18, 2026 00:31
'- Financial analyst persona validation' in the module docstring
to match the renamed class and the reviewer's branding request.
@aliraza556

Copy link
Copy Markdown
Author

Hi @rohitdash08, I've addressed all your review comments. Here's a summary of everything done:

1. Method names renamed (change the method name)

  • _gemini_budget_gemini_budget_suggestion
  • _openai_budget_openai_budget_suggestion

2. "FinMind" removed from persona (Don't put finmind, it should be financial analyst)

  • Renamed FINMIND_PERSONAFINANCIAL_ANALYST_PERSONA
  • Replaced all "FinMind" branding with "certified financial analyst"

3. Persona improved with manual input handling (improve the persona, this should analyze the manual input as well)

  • Added a dedicated ## Manual Input Handling section so the AI incorporates user-provided context (upcoming expenses, salary changes, financial goals, life events)

4. Persona depth improved (persona is still lacking)

  • Expanded to 3 structured sections: Core Expertise, Personality, Rules
  • 8 rules covering: data-driven advice, manual context blending, biggest saving opportunity first, actionable tips per category, quantifying spending increases, motivational insight, emergency-fund targeting, JSON-only output
  • Added expertise areas: debt-to-income ratio awareness, income vs. expense gap analysis, anomaly detection, non-judgmental coaching tone

5. Merge conflicts resolved

  • All 9 conflicts across 4 files resolved — HEAD's multi-month analytics merged with origin's BYOK Gemini and persona features

All 63 backend tests pass. black formatting is clean.

Please let me know if you'd like any further changes!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Dynamic Budget Suggestions

2 participants