import {NetWorthSnapshot, Prisma} from '@prisma/client'; import {DatabaseConnection} from '../config/database'; import {IUserScopedRepository} from './interfaces/IRepository'; const prisma = DatabaseConnection.getInstance(); /** * Repository for NetWorthSnapshot data access * Implements Single Responsibility Principle - handles only database operations */ export class NetWorthSnapshotRepository implements IUserScopedRepository { async findById(id: string): Promise { return prisma.netWorthSnapshot.findUnique({ where: {id}, }); } async findAllByUser(userId: string): Promise { return prisma.netWorthSnapshot.findMany({ where: {userId}, orderBy: {date: 'desc'}, }); } async create(data: Prisma.NetWorthSnapshotCreateInput): Promise { return prisma.netWorthSnapshot.create({ data, }); } async update(id: string, data: Prisma.NetWorthSnapshotUpdateInput): Promise { return prisma.netWorthSnapshot.update({ where: {id}, data, }); } async delete(id: string): Promise { await prisma.netWorthSnapshot.delete({ where: {id}, }); } /** * Get the latest snapshot for a user */ async getLatest(userId: string): Promise { return prisma.netWorthSnapshot.findFirst({ where: {userId}, orderBy: {date: 'desc'}, }); } /** * Get snapshots within a date range */ async getByDateRange(userId: string, startDate: Date, endDate: Date): Promise { return prisma.netWorthSnapshot.findMany({ where: { userId, date: { gte: startDate, lte: endDate, }, }, orderBy: {date: 'asc'}, }); } /** * Check if a snapshot exists for a specific date */ async existsForDate(userId: string, date: Date): Promise { const count = await prisma.netWorthSnapshot.count({ where: { userId, date, }, }); return count > 0; } /** * Get growth over time (percentage change between snapshots) */ async getGrowthStats(userId: string, limit: number = 12): Promise { const snapshots = await prisma.netWorthSnapshot.findMany({ where: {userId}, orderBy: {date: 'desc'}, take: limit, }); const stats = []; for (let i = 0; i < snapshots.length - 1; i++) { const current = snapshots[i]; const previous = snapshots[i + 1]; const growthAmount = current.netWorth - previous.netWorth; const growthPercent = previous.netWorth !== 0 ? (growthAmount / previous.netWorth) * 100 : 0; stats.push({ date: current.date, netWorth: current.netWorth, growthAmount, growthPercent: parseFloat(growthPercent.toFixed(2)), }); } return stats; } }