All files / src/app/api/admin/orders route.ts

97.11% Statements 101/104
80% Branches 8/10
100% Functions 1/1
97.11% Lines 101/104

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 1051x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 9x 9x 9x 9x 9x 9x 9x 9x 9x 9x 9x 9x 9x 9x 9x 2x 2x 9x 2x 2x 9x 9x   9x     9x 9x 9x 9x 9x 9x 9x 9x 9x 9x 9x 9x 9x 9x 9x 9x 9x 9x 9x 9x 9x 9x 9x 7x 7x 7x 7x 7x 7x 7x 7x 7x 1x 1x  
export const dynamic = "force-dynamic";
 
import { NextRequest, NextResponse } from 'next/server';
import {
  withAdmin,
  withErrorHandling,
  successResponse,
  ApiSuccessResponse,
  ApiErrorResponse } from "@/lib/api";
import { } from "@/lib/api/middleware";
import { prisma } from "@/lib/prisma";
import { } from "next-auth";
import { Prisma } from "@prisma/client";
 
interface OrderListData {
  id: number;
  userId: number;
  status: string;
  total: number;
  isDemo: boolean;
  createdAt: Date;
  updatedAt: Date;
  user: { name: string | null; email: string };
  items: Array<{
    quantity: number;
    price: number;
    product: { title: string };
  }>;
}
 
interface OrderListResponse {
  orders: OrderListData[];
  pagination: {
    page: number;
    limit: number;
    total: number;
    pages: number;
  };
}
 
/**
 * GET /api/admin/orders
 * Get all orders with filters for admin management
 */
async function handleGet(
  request: NextRequest
): Promise<NextResponse<ApiSuccessResponse<OrderListResponse> | ApiErrorResponse>> {
  const searchParams = request.nextUrl.searchParams;
  const page = searchParams.get("page") ? parseInt(searchParams.get("page")!) : 1;
  const limit = searchParams.get("limit") ? parseInt(searchParams.get("limit")!) : 20;
  const status = searchParams.get("status");
  const userId = searchParams.get("userId");
  const showDemo = searchParams.get("showDemo"); // "true" to show demo orders, "false" to hide
  const demoOnly = searchParams.get("demoOnly"); // "true" to show only demo orders
 
  const skip = (page - 1) * limit;
 
  const where: Prisma.OrderWhereInput = {};
  if (status) {
    where.status = status as "PROCESSING" | "SHIPPED" | "DELIVERED" | "CANCELLED";
  }
  if (userId) {
    where.userId = parseInt(userId);
  }
  // Demo filter: hide demo orders by default unless explicitly shown
  if (showDemo === "false") {
    where.isDemo = false;
  } else if (demoOnly === "true") {
    where.isDemo = true;
  }
 
  const [orders, total] = await Promise.all([
    prisma.order.findMany({
      where,
      select: {
        id: true,
        userId: true,
        status: true,
        total: true,
        isDemo: true,
        createdAt: true,
        updatedAt: true,
        user: { select: { name: true, email: true } },
        items: {
          select: {
            quantity: true,
            price: true,
            product: { select: { title: true } } } } },
      skip,
      take: limit,
      orderBy: { createdAt: "desc" } }),
    prisma.order.count({ where }),
  ]);
 
  return successResponse({
    orders,
    pagination: {
      page,
      limit,
      total,
      pages: Math.ceil(total / limit) } });
}
 
export const GET = withErrorHandling(withAdmin(handleGet));