feat(insights): analytics drill-down, fee tracking, and category improvements
- Monthly spend chart with category breakdown drill-down - Merchant frequency and spend analytics with per-merchant history - Subscription detection and recurring charge tracking - Fee and interest analytics endpoint - Expanded category list with formatCategory display helper
This commit is contained in:
@@ -3,12 +3,11 @@ import { getCurrentUser } from "@/lib/auth";
|
||||
import { queryRaw } from "@/lib/db";
|
||||
|
||||
// Split-adjusted amount helper (positive for spend, negative for refunds)
|
||||
const MY_AMOUNT = `CASE WHEN ts.share_percent IS NOT NULL THEN COALESCE(t.amount_aud, t.amount) * ts.share_percent / 100 WHEN o.my_share_percent IS NOT NULL THEN COALESCE(t.amount_aud, t.amount) * o.my_share_percent / 100 ELSE COALESCE(t.amount_aud, t.amount) END`;
|
||||
const SPEND_EXPR = `
|
||||
CASE
|
||||
WHEN t.transaction_type IN ('refund', 'credit') THEN
|
||||
-(CASE WHEN ts.share_percent IS NOT NULL THEN COALESCE(t.amount_aud, t.amount) * ts.share_percent / 100 ELSE COALESCE(t.amount_aud, t.amount) END)
|
||||
ELSE
|
||||
(CASE WHEN ts.share_percent IS NOT NULL THEN COALESCE(t.amount_aud, t.amount) * ts.share_percent / 100 ELSE COALESCE(t.amount_aud, t.amount) END)
|
||||
WHEN t.transaction_type IN ('refund', 'credit') THEN -(${MY_AMOUNT})
|
||||
ELSE (${MY_AMOUNT})
|
||||
END
|
||||
`;
|
||||
|
||||
@@ -44,18 +43,18 @@ export async function GET(req: NextRequest) {
|
||||
COUNT(*) FILTER (WHERE t.transaction_type IN ('refund', 'credit'))::int as refund_count,
|
||||
COALESCE(SUM(
|
||||
CASE WHEN t.transaction_type IN ('debit', 'fee', 'interest') THEN
|
||||
CASE WHEN ts.share_percent IS NOT NULL THEN COALESCE(t.amount_aud, t.amount) * ts.share_percent / 100 ELSE COALESCE(t.amount_aud, t.amount) END
|
||||
${MY_AMOUNT}
|
||||
ELSE 0 END
|
||||
), 0)::numeric(12,2) as gross_spend,
|
||||
COALESCE(SUM(
|
||||
CASE WHEN t.transaction_type IN ('refund', 'credit') THEN
|
||||
CASE WHEN ts.share_percent IS NOT NULL THEN COALESCE(t.amount_aud, t.amount) * ts.share_percent / 100 ELSE COALESCE(t.amount_aud, t.amount) END
|
||||
${MY_AMOUNT}
|
||||
ELSE 0 END
|
||||
), 0)::numeric(12,2) as total_refunds,
|
||||
SUM(${SPEND_EXPR})::numeric(12,2) as net_spend,
|
||||
AVG(
|
||||
CASE WHEN t.transaction_type IN ('debit', 'fee', 'interest') THEN
|
||||
CASE WHEN ts.share_percent IS NOT NULL THEN COALESCE(t.amount_aud, t.amount) * ts.share_percent / 100 ELSE COALESCE(t.amount_aud, t.amount) END
|
||||
${MY_AMOUNT}
|
||||
END
|
||||
)::numeric(10,2) as avg_debit,
|
||||
MIN(t.transaction_date)::text as first_seen,
|
||||
|
||||
Reference in New Issue
Block a user