TypeScript 50.6%
JavaScript 46.1%
SQL 2.1%
Shell 0.6%
CSS 0.5%
1import { NextRequest, NextResponse } from "next/server";2import { z } from "zod";3import { eq, desc } from "drizzle-orm";4import { db } from "@/db/client";5import { reports, moderationActions } from "@/db/schema";6import { assertSameOrigin, requireRole } from "@/lib/auth/session";7import { requireFreshMfa } from "@/lib/admin/mfa";8import { audit } from "@/lib/auth/audit";9import { handle, parseBody } from "@/lib/api";10export const dynamic = "force-dynamic";11export async function GET(req: NextRequest) { try { const u = await requireRole("MODERATOR"); requireFreshMfa(u); const status = req.nextUrl.searchParams.get("status") ?? "OPEN"; return NextResponse.json({ items: await db().select().from(reports).where(eq(reports.status, status)).orderBy(desc(reports.createdAt)).limit(300) }); } catch (e) { return handle(e); } }12const Body = z.object({ id: z.string().uuid(), status: z.enum(["RESOLVED", "DISMISSED"]), note: z.string().max(500).optional() });13export async function POST(req: NextRequest) { try { await assertSameOrigin(); const u = await requireRole("MODERATOR"); requireFreshMfa(u); const b = await parseBody(req, Body); await db().update(reports).set({ status: b.status }).where(eq(reports.id, b.id)); await db().insert(moderationActions).values({ actorId: u.id, targetType: "REPORT", targetId: b.id, action: b.status, note: b.note ?? null }); await audit(`admin.report.${b.status.toLowerCase()}`, { actorId: u.id, objectType: "report", objectId: b.id }); return NextResponse.json({ ok: true }); } catch (e) { return handle(e); } }14