All files / src/app/api/admin/referrals/reports route.ts

0% Statements 0/133
100% Branches 0/0
0% Functions 0/1
0% Lines 0/133

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134                                                                                                                                                                                                                                                                           
export const dynamic = "force-dynamic";

import { NextResponse } from "next/server";
import { prisma } from "@/lib/prisma";
import {
  withAdmin,
  withErrorHandling,
  successResponse,
  ApiSuccessResponse,
  ApiErrorResponse } from "@/lib/api";

/**
 * GET /api/admin/referrals/reports
 * Get referral analytics and reports
 */
async function handleGet(): Promise<NextResponse<ApiSuccessResponse<unknown> | ApiErrorResponse>> {
  // Get total referrals
  const totalReferrals = await prisma.referral.count();

  // Get conversion stats
  const [signedUp, purchased, rewarded] = await Promise.all([
    prisma.referral.count({
      where: { status: { in: ["signed_up", "purchased", "rewarded"] } } }),
    prisma.referral.count({
      where: { status: { in: ["purchased", "rewarded"] } } }),
    prisma.referral.count({ where: { status: "rewarded" } }),
  ]);

  const conversionRate =
    totalReferrals > 0
      ? ((purchased / totalReferrals) * 100).toFixed(1)
      : "0.0";

  // Get rewards given stats
  const rewardsGiven = await prisma.referral.count({
    where: {
      OR: [{ referrerRewarded: true }, { refereeRewarded: true }] } });

  // Get top referrers
  const topReferrersData = await prisma.referral.groupBy({
    by: ["referrerId"],
    _count: {
      id: true },
    where: {
      status: { in: ["purchased", "rewarded"] } },
    orderBy: {
      _count: {
        id: "desc" } },
    take: 10 });

  // Get referrer details
  const referrerIds = topReferrersData.map((r) => r.referrerId);
  const referrers = await prisma.user.findMany({
    where: { id: { in: referrerIds } },
    select: { id: true, email: true, name: true } });
  const referrerMap = new Map(referrers.map((r) => [r.id, r]));

  const topReferrers = topReferrersData.map((data) => {
    const user = referrerMap.get(data.referrerId);
    return {
      userId: data.referrerId,
      name: user?.name || "Unknown",
      email: user?.email || "N/A",
      referrals: data._count.id };
  });

  // Get monthly trends (last 6 months)
  const sixMonthsAgo = new Date();
  sixMonthsAgo.setMonth(sixMonthsAgo.getMonth() - 6);

  const monthlyReferrals = await prisma.referral.findMany({
    where: {
      createdAt: { gte: sixMonthsAgo } },
    select: {
      status: true,
      createdAt: true } });

  // Group by month
  const monthlyTrends: Record<string, { created: number; converted: number }> =
    {};
  monthlyReferrals.forEach((ref) => {
    const monthKey = ref.createdAt.toISOString().slice(0, 7); // YYYY-MM
    if (!monthlyTrends[monthKey]) {
      monthlyTrends[monthKey] = { created: 0, converted: 0 };
    }
    monthlyTrends[monthKey].created++;
    if (["purchased", "rewarded"].includes(ref.status)) {
      monthlyTrends[monthKey].converted++;
    }
  });

  // Get campaign performance
  const campaigns = await prisma.referralProgram.findMany({
    select: {
      id: true,
      name: true,
      isActive: true } });

  const campaignPerformance = await Promise.all(
    campaigns.map(async (campaign) => {
      const [total, converted] = await Promise.all([
        prisma.referral.count({ where: { programId: campaign.id } }),
        prisma.referral.count({
          where: {
            programId: campaign.id,
            status: { in: ["purchased", "rewarded"] } } }),
      ]);
      return {
        id: campaign.id,
        name: campaign.name,
        isActive: campaign.isActive,
        totalReferrals: total,
        conversions: converted,
        conversionRate: total > 0 ? ((converted / total) * 100).toFixed(1) : "0.0" };
    })
  );

  return successResponse({
    overview: {
      totalReferrals,
      signedUp,
      purchased,
      rewarded,
      conversionRate: `${conversionRate}%`,
      rewardsGiven },
    topReferrers,
    monthlyTrends: Object.entries(monthlyTrends)
      .map(([month, data]) => ({ month, ...data }))
      .sort((a, b) => a.month.localeCompare(b.month)),
    campaignPerformance });
}

export const GET = withErrorHandling(withAdmin(handleGet));