test(analytics): verify SQL aggregates

This commit is contained in:
2026-08-19 09:12:43 +03:00
parent 019714a8cf
commit 1cbef453b0
3 changed files with 59 additions and 7 deletions

View File

@@ -8,6 +8,8 @@ import type {
Granularity,
} from '@family-budget/shared';
type Queryable = Pick<typeof pool, 'query'>;
interface BaseParams {
from: string;
to: string;
@@ -61,11 +63,14 @@ function buildBaseConditions(
return { conditions, values, nextIdx: idx };
}
export async function getSummary(params: BaseParams): Promise<AnalyticsSummaryResponse> {
export async function getSummary(
params: BaseParams,
db: Queryable = pool,
): Promise<AnalyticsSummaryResponse> {
const { conditions, values } = buildBaseConditions(params, 1);
const where = 'WHERE ' + conditions.join(' AND ');
const totalsResult = await pool.query(
const totalsResult = await db.query(
`${analyticsTransactions(where)},
category_net AS (
SELECT category_id, category_name, analytic_type, SUM(effective_amount)::bigint AS amount
@@ -90,7 +95,7 @@ export async function getSummary(params: BaseParams): Promise<AnalyticsSummaryRe
const transferInflow = Number(totalsResult.rows[0].transfer_inflow);
const transferOutflow = Number(totalsResult.rows[0].transfer_outflow);
const topResult = await pool.query(
const topResult = await db.query(
`${analyticsTransactions(where)}
SELECT category_id::bigint, category_name, GREATEST(-SUM(effective_amount), 0)::bigint AS amount
FROM analytics_transactions
@@ -122,11 +127,14 @@ export async function getSummary(params: BaseParams): Promise<AnalyticsSummaryRe
};
}
export async function getByCategory(params: BaseParams): Promise<ByCategoryItem[]> {
export async function getByCategory(
params: BaseParams,
db: Queryable = pool,
): Promise<ByCategoryItem[]> {
const { conditions, values } = buildBaseConditions(params, 1);
const where = 'WHERE ' + conditions.join(' AND ');
const { rows } = await pool.query(
const { rows } = await db.query(
`${analyticsTransactions(where)}
SELECT
category_id::bigint,
@@ -154,6 +162,7 @@ export async function getByCategory(params: BaseParams): Promise<ByCategoryItem[
export async function getTimeseries(
params: BaseParams & { categoryId?: number; granularity: Granularity },
db: Queryable = pool,
): Promise<TimeseriesItem[]> {
let truncExpr: string;
let intervalStr: string;
@@ -198,7 +207,7 @@ export async function getTimeseries(
const txWhere = txConditions.join(' AND ');
const { rows } = await pool.query(
const { rows } = await db.query(
`WITH periods AS (
SELECT
gs::date AS period_start,