← back to Omega Watches 2

src/app/api/admin/refresh-views/route.ts

50 lines

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

export const dynamic = "force-dynamic";

const MATERIALIZED_VIEWS = ["source_health", "ref_price_summary"];

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

  if (session.role !== "admin" && session.role !== "operator") {
    return NextResponse.json(
      { success: false, error: { code: "FORBIDDEN", message: "Admin or operator role required" } },
      { status: 403 }
    );
  }

  const results: { view: string; refreshed: boolean; duration_ms: number; error?: string }[] = [];

  for (const view of MATERIALIZED_VIEWS) {
    const start = Date.now();
    try {
      await query(`REFRESH MATERIALIZED VIEW CONCURRENTLY ${view}`);
      results.push({ view, refreshed: true, duration_ms: Date.now() - start });
    } catch (e: any) {
      // If CONCURRENTLY fails (no unique index), try without
      try {
        await query(`REFRESH MATERIALIZED VIEW ${view}`);
        results.push({ view, refreshed: true, duration_ms: Date.now() - start });
      } catch (e2: any) {
        results.push({ view, refreshed: false, duration_ms: Date.now() - start, error: e2.message });
      }
    }
  }

  const allSuccess = results.every((r) => r.refreshed);

  return NextResponse.json({
    success: allSuccess,
    data: { results, refreshed_at: new Date().toISOString() },
  });
}