← back to Omega Watches 2

src/app/api/snapshots/route.ts

66 lines

import { NextRequest, NextResponse } from "next/server";
import { query } from "@/lib/db";
import { getSession } from "@/lib/auth";

export const dynamic = "force-dynamic";

export async function GET(request: NextRequest) {
  const session = await getSession(request);
  if (!session) {
    return NextResponse.json({ success: false, error: { code: "UNAUTHORIZED", message: "Login required" } }, { status: 401 });
  }

  const { searchParams } = new URL(request.url);
  const source = searchParams.get("source");
  const limit = Math.min(parseInt(searchParams.get("limit") || "100"), 500);

  let whereClause = "WHERE 1=1";
  const params: any[] = [];

  if (source) {
    params.push(source);
    whereClause += ` AND source_name = $${params.length}`;
  }

  params.push(limit);

  const snapshots = await query(
    `SELECT id as snapshot_id, source_name, url, content_hash, content_type,
            content_size_bytes, parser_version, scraped_at
     FROM raw_snapshot
     ${whereClause}
     ORDER BY scraped_at DESC
     LIMIT $${params.length}`,
    params
  );

  // Summary stats
  const stats = await query(`
    SELECT
      COUNT(*) as total,
      COUNT(DISTINCT source_name) as sources,
      COALESCE(SUM(content_size_bytes), 0) as total_bytes,
      MAX(scraped_at) as last_snapshot
    FROM raw_snapshot
  `);

  // Per-source breakdown
  const bySource = await query(`
    SELECT source_name, COUNT(*) as count,
           SUM(content_size_bytes) as total_bytes,
           MAX(scraped_at) as latest
    FROM raw_snapshot
    GROUP BY source_name
    ORDER BY count DESC
  `);

  return NextResponse.json({
    success: true,
    data: {
      snapshots,
      stats: stats[0],
      by_source: bySource,
    },
  });
}