import type {IncomeSource, Expense, Transaction, Prisma} from '@prisma/client'; import {DatabaseConnection} from '../config/database'; const prisma = DatabaseConnection.getInstance(); /** * Repository for IncomeSource data access */ export class IncomeSourceRepository { async findById(id: string): Promise { return prisma.incomeSource.findUnique({where: {id}}); } async findByIdAndUser(id: string, userId: string): Promise { return prisma.incomeSource.findFirst({where: {id, userId}}); } async findAllByUser(userId: string): Promise { return prisma.incomeSource.findMany({ where: {userId}, orderBy: {createdAt: 'desc'}, }); } async create(data: Prisma.IncomeSourceCreateInput): Promise { return prisma.incomeSource.create({data}); } async update(id: string, data: Prisma.IncomeSourceUpdateInput): Promise { return prisma.incomeSource.update({where: {id}, data}); } async delete(id: string): Promise { await prisma.incomeSource.delete({where: {id}}); } async getTotalMonthlyIncome(userId: string): Promise { const result = await prisma.incomeSource.aggregate({ where: {userId}, _sum: {amount: true}, }); return result._sum.amount || 0; } } /** * Repository for Expense data access */ export class ExpenseRepository { async findById(id: string): Promise { return prisma.expense.findUnique({where: {id}}); } async findByIdAndUser(id: string, userId: string): Promise { return prisma.expense.findFirst({where: {id, userId}}); } async findAllByUser(userId: string): Promise { return prisma.expense.findMany({ where: {userId}, orderBy: {createdAt: 'desc'}, }); } async create(data: Prisma.ExpenseCreateInput): Promise { return prisma.expense.create({data}); } async update(id: string, data: Prisma.ExpenseUpdateInput): Promise { return prisma.expense.update({where: {id}, data}); } async delete(id: string): Promise { await prisma.expense.delete({where: {id}}); } async getTotalMonthlyExpenses(userId: string): Promise { const result = await prisma.expense.aggregate({ where: {userId}, _sum: {amount: true}, }); return result._sum.amount || 0; } async getByCategory(userId: string): Promise> { const expenses = await this.findAllByUser(userId); return expenses.reduce((acc, expense) => { if (!acc[expense.category]) acc[expense.category] = []; acc[expense.category].push(expense); return acc; }, {} as Record); } } /** * Repository for Transaction data access */ export class TransactionRepository { async findById(id: string): Promise { return prisma.transaction.findUnique({where: {id}}); } async findByIdAndUser(id: string, userId: string): Promise { return prisma.transaction.findFirst({where: {id, userId}}); } async findAllByUser(userId: string): Promise { return prisma.transaction.findMany({ where: {userId}, orderBy: {date: 'desc'}, }); } async create(data: Prisma.TransactionCreateInput): Promise { return prisma.transaction.create({data}); } async update(id: string, data: Prisma.TransactionUpdateInput): Promise { return prisma.transaction.update({where: {id}, data}); } async delete(id: string): Promise { await prisma.transaction.delete({where: {id}}); } async getByDateRange(userId: string, startDate: Date, endDate: Date): Promise { return prisma.transaction.findMany({ where: { userId, date: {gte: startDate, lte: endDate}, }, orderBy: {date: 'desc'}, }); } async getByType(userId: string, type: string): Promise { return prisma.transaction.findMany({ where: {userId, type}, orderBy: {date: 'desc'}, }); } async getCashflowSummary(userId: string, startDate: Date, endDate: Date): Promise<{ totalIncome: number; totalExpenses: number; netCashflow: number; }> { const transactions = await this.getByDateRange(userId, startDate, endDate); const totalIncome = transactions .filter(t => t.type === 'income') .reduce((sum, t) => sum + t.amount, 0); const totalExpenses = transactions .filter(t => t.type === 'expense') .reduce((sum, t) => sum + t.amount, 0); return { totalIncome, totalExpenses, netCashflow: totalIncome - totalExpenses, }; } }