← back to Govarbitrage

src/lib/dashboard.ts

42 lines

import { prisma } from "@/lib/db";

export interface DashboardStats {
  activeAuctions: number;
  closingToday: number;
  highestProfit: number;
  highestRoi: number;
  cashRequired: number; // sum of recommended max bids across active opportunities
  expectedProfit: number; // sum of expected net profit
  highestScore: number;
  pendingResearch: number;
}

/** Aggregate the summary-card metrics in a single pass. */
export async function getDashboardStats(): Promise<DashboardStats> {
  const now = new Date();
  const endOfDay = new Date(now);
  endOfDay.setHours(23, 59, 59, 999);

  const [activeAuctions, closingToday, pendingResearch, costAgg, topScore] = await Promise.all([
    prisma.listing.count({ where: { listingStatus: "ACTIVE", closingAt: { gte: now } } }),
    prisma.listing.count({ where: { listingStatus: "ACTIVE", closingAt: { gte: now, lte: endOfDay } } }),
    prisma.listing.count({ where: { researchStatus: { in: ["PENDING", "QUEUED", "IN_PROGRESS"] } } }),
    prisma.costBreakdown.aggregate({
      _sum: { expectedNetProfit: true, recommendedMaxBid: true },
      _max: { expectedNetProfit: true, roi: true },
    }),
    prisma.score.aggregate({ where: { profile: "OVERALL_OPPORTUNITY" }, _max: { value: true } }),
  ]);

  return {
    activeAuctions,
    closingToday,
    highestProfit: Number(costAgg._max.expectedNetProfit ?? 0),
    highestRoi: Number(costAgg._max.roi ?? 0),
    cashRequired: Number(costAgg._sum.recommendedMaxBid ?? 0),
    expectedProfit: Number(costAgg._sum.expectedNetProfit ?? 0),
    highestScore: Number(topScore._max.value ?? 0),
    pendingResearch,
  };
}