karbe/src/app/api/metrics/route.ts
Claude Integration 14fd9a5940
Some checks failed
CI / test (pull_request) Failing after 2m13s
feat(p2): vitest + 27 tests + /api/health enrichi + /api/metrics + workflow CI
2026-06-01 02:27:14 +00:00

78 lines
2.1 KiB
TypeScript

import { NextResponse } from "next/server";
import { BookingStatus, CarbetStatus, UserRole } from "@/generated/prisma/enums";
import { prisma } from "@/lib/prisma";
export const runtime = "nodejs";
export const dynamic = "force-dynamic";
/**
* Metrics publiques, agrégées (jamais de PII).
* Format JSON simple — consommable par un script cron ou un dashboard léger.
*/
export async function GET() {
const now = new Date();
const last24h = new Date(now.getTime() - 86_400_000);
const last7d = new Date(now.getTime() - 7 * 86_400_000);
const last30d = new Date(now.getTime() - 30 * 86_400_000);
const [
carbetsPublished,
carbetsTotal,
bookings24h,
bookings7d,
bookings30d,
bookingsByStatus,
usersTotal,
usersByRole,
mediaTotal,
auditLast24h,
] = await Promise.all([
prisma.carbet.count({ where: { status: CarbetStatus.PUBLISHED } }),
prisma.carbet.count(),
prisma.booking.count({ where: { createdAt: { gte: last24h } } }),
prisma.booking.count({ where: { createdAt: { gte: last7d } } }),
prisma.booking.count({ where: { createdAt: { gte: last30d } } }),
prisma.booking.groupBy({
by: ["status"],
_count: { _all: true },
}),
prisma.user.count(),
prisma.user.groupBy({
by: ["role"],
_count: { _all: true },
}),
prisma.media.count(),
prisma.auditLog.count({ where: { createdAt: { gte: last24h } } }),
]);
return NextResponse.json({
generatedAt: now.toISOString(),
carbets: {
total: carbetsTotal,
published: carbetsPublished,
},
bookings: {
last24h: bookings24h,
last7d: bookings7d,
last30d: bookings30d,
byStatus: Object.fromEntries(
Object.values(BookingStatus).map((s) => [
s,
bookingsByStatus.find((b) => b.status === s)?._count._all ?? 0,
]),
),
},
users: {
total: usersTotal,
byRole: Object.fromEntries(
Object.values(UserRole).map((r) => [
r,
usersByRole.find((u) => u.role === r)?._count._all ?? 0,
]),
),
},
media: { total: mediaTotal },
audit: { last24h: auditLast24h },
});
}