diff --git a/CHANGELOG.md b/CHANGELOG.md index 440a407..5d2fc69 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,11 +1,5 @@ # Changelog -## [Frontend 0.11.0 / Backend 0.10.0 / Shared 0.5.0] - 2026-08-21 - -### Added - -- Added category filtering to analytics summary and category breakdown, including savings-account interest handling in the filtered results. - ## [Backend 0.9.2] - 2026-08-20 ### Added diff --git a/backend/package.json b/backend/package.json index c0f9316..abac951 100644 --- a/backend/package.json +++ b/backend/package.json @@ -1,6 +1,6 @@ { "name": "@family-budget/backend", - "version": "0.10.0", + "version": "0.9.2", "private": true, "scripts": { "dev": "tsx watch src/app.ts", diff --git a/backend/src/routes/analytics.ts b/backend/src/routes/analytics.ts index 4e83bf6..c5608ed 100644 --- a/backend/src/routes/analytics.ts +++ b/backend/src/routes/analytics.ts @@ -8,7 +8,7 @@ const router = Router(); router.get( '/summary', asyncHandler(async (req, res) => { - const { from, to, accountId, categoryId, onlyConfirmed } = req.query; + const { from, to, accountId, onlyConfirmed } = req.query; if (!from || !to) { res.status(400).json({ error: 'BAD_REQUEST', message: 'from and to are required' }); return; @@ -18,7 +18,6 @@ router.get( from: from as string, to: to as string, accountId: accountId ? Number(accountId) : undefined, - categoryId: categoryId ? Number(categoryId) : undefined, onlyConfirmed: onlyConfirmed === 'true', }); res.json(result); @@ -28,7 +27,7 @@ router.get( router.get( '/by-category', asyncHandler(async (req, res) => { - const { from, to, accountId, categoryId, onlyConfirmed } = req.query; + const { from, to, accountId, onlyConfirmed } = req.query; if (!from || !to) { res.status(400).json({ error: 'BAD_REQUEST', message: 'from and to are required' }); return; @@ -38,7 +37,6 @@ router.get( from: from as string, to: to as string, accountId: accountId ? Number(accountId) : undefined, - categoryId: categoryId ? Number(categoryId) : undefined, onlyConfirmed: onlyConfirmed === 'true', }); res.json(result); diff --git a/backend/src/services/analytics.integration.test.ts b/backend/src/services/analytics.integration.test.ts index 3df48d3..cfbd548 100644 --- a/backend/src/services/analytics.integration.test.ts +++ b/backend/src/services/analytics.integration.test.ts @@ -32,8 +32,6 @@ async function testQueries(): Promise { const params = { from: '2026-07-01', to: '2026-07-31', accountId, onlyConfirmed: true }; const summary = await getSummary(params, client); assert.deepEqual({ expense: summary.totalExpense, income: summary.totalIncome, net: summary.net, transferOut: summary.transferOutflow, interest: summary.interestIncome }, { expense: 6_000, income: 15_000, net: 9_000, transferOut: 3_000, interest: 1_500 }); - const categorySummary = await getSummary({ ...params, categoryId: categoryId.expense }, client); - assert.deepEqual({ expense: categorySummary.totalExpense, income: categorySummary.totalIncome }, { expense: 6_000, income: 0 }); assert.equal((await getSummary({ ...params, from: '2026-08-01', to: '2026-08-31' }, client)).totalExpense, 7_000); assert.deepEqual((await getByCategory(params, client)).map((item) => item.amount), [6_000]); const timeseries = await getTimeseries({ ...params, granularity: 'month' }, client); diff --git a/backend/src/services/analytics.ts b/backend/src/services/analytics.ts index 1b92394..fdbf0e2 100644 --- a/backend/src/services/analytics.ts +++ b/backend/src/services/analytics.ts @@ -14,7 +14,6 @@ interface BaseParams { from: string; to: string; accountId?: number; - categoryId?: number; onlyConfirmed?: boolean; } @@ -62,11 +61,6 @@ function buildBaseConditions( values.push(params.accountId); idx++; } - if (params.categoryId != null) { - conditions.push(`t.category_id = $${idx}`); - values.push(params.categoryId); - idx++; - } if (params.onlyConfirmed) { conditions.push('t.is_category_confirmed = TRUE'); } diff --git a/frontend/package.json b/frontend/package.json index 93ec54e..261e832 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,6 +1,6 @@ { "name": "@family-budget/frontend", - "version": "0.11.0", + "version": "0.10.2", "private": true, "type": "module", "scripts": { diff --git a/frontend/src/pages/AnalyticsPage.tsx b/frontend/src/pages/AnalyticsPage.tsx index b9fe2ae..5783aac 100644 --- a/frontend/src/pages/AnalyticsPage.tsx +++ b/frontend/src/pages/AnalyticsPage.tsx @@ -1,14 +1,12 @@ import { useState, useEffect, useCallback } from 'react'; import type { Account, - Category, AnalyticsSummaryResponse, ByCategoryItem, TimeseriesItem, Granularity, } from '@family-budget/shared'; import { getAccounts } from '../api/accounts'; -import { getCategories } from '../api/categories'; import { getSummary, getByCategory, getTimeseries } from '../api/analytics'; import { PeriodSelector, @@ -31,10 +29,8 @@ function getDefaultPeriod(): PeriodState { export function AnalyticsPage() { const [period, setPeriod] = useState(getDefaultPeriod); const [accountId, setAccountId] = useState(''); - const [categoryId, setCategoryId] = useState(''); const [onlyConfirmed, setOnlyConfirmed] = useState(false); const [accounts, setAccounts] = useState([]); - const [categories, setCategories] = useState([]); const [summary, setSummary] = useState( null, ); @@ -44,7 +40,6 @@ export function AnalyticsPage() { useEffect(() => { getAccounts().then(setAccounts).catch(() => {}); - getCategories({ isActive: true }).then(setCategories).catch(() => {}); }, []); const fetchAll = useCallback(async () => { @@ -68,7 +63,6 @@ export function AnalyticsPage() { from: period.from, to: period.to, ...(accountId ? { accountId: Number(accountId) } : {}), - ...(categoryId ? { categoryId: Number(categoryId) } : {}), ...(onlyConfirmed ? { onlyConfirmed: true } : {}), }; @@ -86,7 +80,7 @@ export function AnalyticsPage() { } finally { setLoading(false); } - }, [period, accountId, categoryId, onlyConfirmed]); + }, [period, accountId, onlyConfirmed]); useEffect(() => { fetchAll(); @@ -118,13 +112,6 @@ export function AnalyticsPage() { ))} -
- - -