From 7ccd64a7bb7774d83577d96ffa5f994bac0c39c4 Mon Sep 17 00:00:00 2001 From: jerick Date: Tue, 21 Apr 2026 08:25:16 -0400 Subject: [PATCH] CC account value consistency --- src/app/(app)/budgets/page.tsx | 11 ++--------- src/app/(app)/dashboard/page.tsx | 11 ++--------- src/app/api/upload/route.ts | 8 +++++++- 3 files changed, 11 insertions(+), 19 deletions(-) diff --git a/src/app/(app)/budgets/page.tsx b/src/app/(app)/budgets/page.tsx index 129d20d..2de49f5 100644 --- a/src/app/(app)/budgets/page.tsx +++ b/src/app/(app)/budgets/page.tsx @@ -26,19 +26,12 @@ export default async function BudgetsPage({ searchParams }: { searchParams: Sear orderBy: { createdAt: 'asc' }, }), prisma.$queryRaw<{ budgetId: string; total: bigint }[]>` - SELECT t."budgetId", - COALESCE(SUM( - CASE - WHEN a.type = 'CREDIT_CARD' AND t.type = 'CREDIT' THEN t."amountCents" - WHEN a.type = 'CREDIT_CARD' AND t.type = 'DEBIT' THEN -t."amountCents" - WHEN a.type = 'BANK' AND t.type = 'DEBIT' THEN t."amountCents" - ELSE -t."amountCents" - END - ), 0)::bigint AS total + SELECT t."budgetId", COALESCE(SUM(t."amountCents"), 0)::bigint AS total FROM "Transaction" t JOIN "Account" a ON t."accountId" = a.id WHERE a."userId" = ${userId} AND t."budgetId" IS NOT NULL + AND t.type = 'DEBIT' AND t.date >= ${start} AND t.date <= ${end} GROUP BY t."budgetId" diff --git a/src/app/(app)/dashboard/page.tsx b/src/app/(app)/dashboard/page.tsx index 7c6681c..3c92947 100644 --- a/src/app/(app)/dashboard/page.tsx +++ b/src/app/(app)/dashboard/page.tsx @@ -41,19 +41,12 @@ export default async function DashboardPage({ searchParams }: { searchParams: Se orderBy: { name: 'asc' }, }), prisma.$queryRaw<{ budgetId: string; total: bigint }[]>` - SELECT t."budgetId", - COALESCE(SUM( - CASE - WHEN a.type = 'CREDIT_CARD' AND t.type = 'CREDIT' THEN t."amountCents" - WHEN a.type = 'CREDIT_CARD' AND t.type = 'DEBIT' THEN -t."amountCents" - WHEN a.type = 'BANK' AND t.type = 'DEBIT' THEN t."amountCents" - ELSE -t."amountCents" - END - ), 0)::bigint AS total + SELECT t."budgetId", COALESCE(SUM(t."amountCents"), 0)::bigint AS total FROM "Transaction" t JOIN "Account" a ON t."accountId" = a.id WHERE a."userId" = ${userId} AND t."budgetId" IS NOT NULL + AND t.type = 'DEBIT' AND t.date >= ${start} AND t.date <= ${end} GROUP BY t."budgetId" diff --git a/src/app/api/upload/route.ts b/src/app/api/upload/route.ts index 9e728ad..4908594 100644 --- a/src/app/api/upload/route.ts +++ b/src/app/api/upload/route.ts @@ -74,7 +74,13 @@ export async function POST(req: Request) { config = result.data } - const normalized = normalizeRows(allRows, accountId, config) + const rawNormalized = normalizeRows(allRows, accountId, config) + + // Credit card CSVs have inverted sign semantics: CREDIT = charge, DEBIT = refund. + // Flip types so the rest of the app can treat DEBIT = spending universally. + const normalized = account.type === 'CREDIT_CARD' + ? rawNormalized.map((r) => ({ ...r, type: r.type === 'CREDIT' ? 'DEBIT' as const : 'CREDIT' as const })) + : rawNormalized // Apply budget auto-assign rules (first match wins) const budgetRules = await prisma.budgetRule.findMany({