Skip to content

feat: lifestyle inflation detection insights (#118)#471

Open
qiridigital wants to merge 1 commit intorohitdash08:mainfrom
qiridigital:feat/lifestyle-inflation
Open

feat: lifestyle inflation detection insights (#118)#471
qiridigital wants to merge 1 commit intorohitdash08:mainfrom
qiridigital:feat/lifestyle-inflation

Conversation

@qiridigital
Copy link

Summary

Implements lifestyle inflation detection — comparing category spending between two equal time windows to surface where spending has grown materially over time.

What's included

Backend (packages/backend/)

  • app/services/lifestyle.py — Two-window comparison engine:
    • Splits history into "recent N months" vs "previous N months"
    • Computes average monthly spend per category in each window
    • Flags categories with growth ≥ threshold_pct (default 10%)
    • Returns pct_change, abs_change_monthly, annualised_extra, monthly trend list
    • Income transactions excluded from analysis
    • Results sorted by pct_change descending
  • app/routes/insights.py — New endpoint:
    • GET /insights/lifestyle-inflation?window_months=N&threshold_pct=P
    • window_months capped at 12, default 3
    • threshold_pct range 0–100, default 10
    • Returns inflated_categories, stable_categories, summary, params echo
  • tests/test_lifestyle.py — 13 pytest tests covering auth, empty state, growth detection, income exclusion, response structure, sort order, annualised calculation, trend format, and custom params

Frontend (app/src/)

  • api/lifestyle.ts — TypeScript API client with full typed interfaces
  • pages/LifestyleInflation.tsx — Dashboard page:
    • 4-tile summary banner (inflated count, stable count, extra monthly/annual spend)
    • Category cards colour-coded by severity (yellow <25% / orange 25–50% / red >50%)
    • Mini sparkline bar chart per category (grey = previous window, red = recent)
    • Compare window selector (1/2/3/6 months) + threshold dropdown
    • Collapsible stable categories section
  • App.tsx/lifestyle route added
  • Navbar.tsx — "Inflation" nav link added

Closes

Closes #118

Compares spending per category between two equal time windows (recent vs
previous) and surfaces categories where spending has grown materially,
indicating lifestyle inflation - the tendency to spend more as income grows.

- GET /insights/lifestyle-inflation?window_months=N&threshold_pct=P
  - Compares avg monthly spend: recent N months vs previous N months
  - Flags categories with growth >= threshold_pct (default 10%)
  - Returns pct_change, abs_change_monthly, annualised_extra per category
  - Monthly trend list (oldest->newest) for sparkline visualisation
  - Summary: inflated_count, stable_count, total_extra_monthly/annual
  - Sorted by pct_change descending (worst inflation first)
  - window cap: max 12 months; threshold range: 0-100%
- Service: services/lifestyle.py with two-window comparison algorithm
- Income transactions excluded from analysis
- React LifestyleInflation page:
  - 4-tile summary banner (counts + extra monthly + extra annual)
  - Category cards with colour-coded severity (yellow/orange/red)
  - Mini sparkline bar chart (grey=previous, red=recent window)
  - Window selector (1/2/3/6 months) + threshold dropdown
  - Collapsible stable categories section
- TypeScript API client (lifestyle.ts) with full typed interfaces
- Route /lifestyle added to App.tsx + Inflation nav link in Navbar
- 13 pytest tests: auth, empty, growth detection, income exclusion,
  response structure, sorting, annualised calc, trend format, custom params

/claim rohitdash08#118
Copilot AI review requested due to automatic review settings March 16, 2026 21:34
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds a new “Lifestyle Inflation” insight that compares category spending across two equal time windows (recent vs previous) to identify categories with material growth, exposing the results via a backend endpoint and a new frontend dashboard page.

Changes:

  • Backend service to compute per-category windowed averages, pct/absolute deltas, and a per-month trend series.
  • New GET /insights/lifestyle-inflation endpoint with clamped window_months and threshold_pct query params.
  • Frontend API client + new /lifestyle page and navbar link to visualize inflated/stable categories.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
packages/backend/app/services/lifestyle.py Implements the two-window comparison and payload structure (inflated/stable + summary + trend).
packages/backend/app/routes/insights.py Adds authenticated lifestyle inflation insights endpoint with parameter parsing/clamping.
packages/backend/tests/test_lifestyle.py Adds endpoint-level pytest coverage for auth, empty state, detection logic, sorting, and response structure.
app/src/api/lifestyle.ts Adds typed TS client/interfaces for the lifestyle inflation endpoint.
app/src/pages/LifestyleInflation.tsx Adds UI to select window/threshold, display summary tiles, and render category cards with trend bars.
app/src/App.tsx Registers the new /lifestyle route behind ProtectedRoute.
app/src/components/layout/Navbar.tsx Adds navigation entry for the new Lifestyle Inflation page.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +197 to +199


import pytest
Comment on lines +165 to +168
for d in [120, 150]:
_add_expense(client, auth_header, 100, cat_id, days_ago=d)
for d in [15, 45]:
_add_expense(client, auth_header, 400, cat_id, days_ago=d)
Comment on lines +182 to +185
for d in [120, 150]:
_add_expense(client, auth_header, 50, cat_id, days_ago=d)
for d in [15, 45]:
_add_expense(client, auth_header, 200, cat_id, days_ago=d)
Comment on lines +108 to +109
- summary: counts and total_extra_monthly_spend
- window_months: echo input param
Comment on lines +83 to +85
const currency = "₹";

useEffect(() => {
setError(null);
getLifestyleInflation(window, threshold)
.then(setData)
.catch((e) => setError(e.message))
"notes": "test",
},
headers=headers,
)
Comment on lines +54 to +60
# Previous window: months ~4 and ~5 ago → small spend
for days in [120, 150]:
_add_expense(client, auth_header, 100, cat_id, days_ago=days)

# Recent window: months ~1 and ~2 ago → big spend (inflated)
for days in [15, 45]:
_add_expense(client, auth_header, 300, cat_id, days_ago=days)
Comment on lines +142 to +152
# cat_a: 100 → 300 (+200%)
for d in [120, 150]:
_add_expense(client, auth_header, 100, cat_a, days_ago=d)
for d in [15, 45]:
_add_expense(client, auth_header, 300, cat_a, days_ago=d)

# cat_b: 100 → 150 (+50%)
for d in [120, 150]:
_add_expense(client, auth_header, 100, cat_b, days_ago=d)
for d in [15, 45]:
_add_expense(client, auth_header, 150, cat_b, days_ago=d)
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.

Lifestyle inflation detection insights

2 participants