SPB Git forge

spb/spb-cloud

Public
10commits 1branches 0releases
3.2 MBsize
maindefault branch
4 h agolast push
JavaScript 56.7% TypeScript 42.6%
3.1 KB · 116 lines typescript
Raw Blame History
1import { NextResponse } from "next/server";2import { prisma } from "@/lib/prisma";3import { getStorageUsage } from "@/lib/storage";4import { aggregateByCategory } from "@/components/dashboard/categories";56export const dynamic = "force-dynamic";78const UPLOAD_ACTIONS = new Set(["UPLOAD", "upload", "file_uploaded"]);910function dayKey(d: Date): string {11  const y = d.getFullYear();12  const m = String(d.getMonth() + 1).padStart(2, "0");13  const day = String(d.getDate()).padStart(2, "0");14  return `${y}-${m}-${day}`;15}1617export async function GET() {18  const since = new Date();19  since.setHours(0, 0, 0, 0);20  since.setDate(since.getDate() - 13); // 14 jours incluant aujourd'hui2122  const [23    fileCount,24    folderCount,25    shareCount,26    recentActivity,27    storageUsage,28    filesByType,29    favoriteCount,30    trashCount,31    versionCount,32    largestRaw,33    recentLogs,34  ] = await Promise.all([35    prisma.file.count(),36    prisma.folder.count(),37    prisma.sharedLink.count({ where: { active: true } }),38    prisma.activityLog.findMany({39      take: 20,40      orderBy: { createdAt: "desc" },41      include: { file: { select: { name: true } } },42    }),43    getStorageUsage(),44    prisma.file.groupBy({45      by: ["mimeType"],46      where: { deletedAt: null },47      _count: true,48      _sum: { size: true },49    }),50    prisma.fileMetadata.count({ where: { isFavorite: true, file: { deletedAt: null } } }),51    prisma.file.count({ where: { deletedAt: { not: null } } }),52    prisma.fileVersion.count(),53    prisma.file.findMany({54      where: { deletedAt: null },55      orderBy: { size: "desc" },56      take: 5,57      select: { id: true, name: true, size: true, mimeType: true, folderId: true },58    }),59    prisma.activityLog.findMany({60      where: { createdAt: { gte: since } },61      select: { createdAt: true, action: true },62    }),63  ]);6465  // File type breakdown (rétro-compatible)66  const typeBreakdown = filesByType.map((t) => ({67    type: t.mimeType,68    count: t._count,69    size: Number(t._sum.size || 0),70  }));7172  const byCategory = aggregateByCategory(typeBreakdown);7374  // Activité par jour (14 jours, jours vides inclus)75  const buckets = new Map<string, { date: string; count: number; uploads: number }>();76  for (let i = 0; i < 14; i++) {77    const d = new Date(since);78    d.setDate(since.getDate() + i);79    const k = dayKey(d);80    buckets.set(k, { date: k, count: 0, uploads: 0 });81  }82  for (const log of recentLogs) {83    const k = dayKey(new Date(log.createdAt));84    const b = buckets.get(k);85    if (!b) continue;86    b.count += 1;87    if (UPLOAD_ACTIONS.has(log.action)) b.uploads += 1;88  }89  const activityByDay = Array.from(buckets.values());9091  const largestFiles = largestRaw.map((f) => ({92    id: f.id,93    name: f.name,94    size: Number(f.size),95    mimeType: f.mimeType,96    folderId: f.folderId,97  }));9899  return NextResponse.json({100    fileCount,101    folderCount,102    shareCount,103    storageUsed: storageUsage.totalSize,104    diskFileCount: storageUsage.fileCount,105    recentActivity,106    typeBreakdown,107    // v3108    byCategory,109    activityByDay,110    favoriteCount,111    trashCount,112    versionCount,113    largestFiles,114  });115}116