src/app/api/superadmin/logs/route.ts

route·app·2.0 KB · 57 lignes· Voir l'itinéraire
Annotation non disponible

Lance npm run annotate (nécessite ANTHROPIC_API_KEY dans .env.local) pour générer une annotation française par Claude Haiku 4.5.

2 exports

GETdynamic

Code source· typescript

import { NextRequest, NextResponse } from "next/server";
import { getSession } from "@/lib/auth/session";
import { prisma } from "@/lib/prisma/client";

export const dynamic = "force-dynamic";

// GET /api/superadmin/logs?action=&targetType=&period=&before=&limit=
// Liste paginée des audit logs avec filtres optionnels.
// Pagination cursor par createdAt (paramètre `before` ISO).
export async function GET(req: NextRequest) {
  const session = await getSession();
  if (!session || session.role !== "SUPER_ADMIN") {
    return NextResponse.json({ error: "Non autorisé" }, { status: 401 });
  }

  const url = req.nextUrl;
  const action = url.searchParams.get("action") ?? "";
  const targetType = url.searchParams.get("targetType") ?? "";
  const period = url.searchParams.get("period") ?? "all"; // 24h / 7d / 30d / all
  const before = url.searchParams.get("before"); // ISO date for cursor
  const limit = Math.min(parseInt(url.searchParams.get("limit") ?? "50", 10), 100);

  const where: Record<string, unknown> = {};
  if (action) where.action = action;
  if (targetType) where.targetType = targetType;

  if (period !== "all") {
    const now = new Date();
    let from: Date | null = null;
    if (period === "24h") from = new Date(now.getTime() - 24 * 3600 * 1000);
    else if (period === "7d") from = new Date(now.getTime() - 7 * 24 * 3600 * 1000);
    else if (period === "30d") from = new Date(now.getTime() - 30 * 24 * 3600 * 1000);
    if (from) {
      where.createdAt = { gte: from };
    }
  }

  if (before) {
    where.createdAt = {
      ...((where.createdAt as object) ?? {}),
      lt: new Date(before),
    };
  }

  const logs = await prisma.auditLog.findMany({
    where,
    orderBy: { createdAt: "desc" },
    take: limit + 1, // +1 pour savoir s'il y a plus
  });

  const hasMore = logs.length > limit;
  const items = hasMore ? logs.slice(0, limit) : logs;
  const nextCursor = hasMore ? items[items.length - 1].createdAt.toISOString() : null;

  return NextResponse.json({ items, hasMore, nextCursor });
}