← back to Omega Watches 2
src/app/api/dashboard/route.ts
92 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 }
);
}
// Recent collector runs (last 10)
const recentRuns = await query(`
SELECT cr.run_id, ds.display_name as source_name, cr.job_type, cr.status,
cr.records_fetched, cr.records_inserted, cr.records_quarantined,
cr.duration_ms, cr.started_at, cr.error_message
FROM collector_run cr
JOIN data_source ds ON cr.source_id = ds.id
ORDER BY cr.started_at DESC
LIMIT 10
`);
// Collection-level price summary
const collectionSummary = await query(`
SELECT wr.collection,
COUNT(DISTINCT wr.id) as ref_count,
COUNT(me.event_id) as event_count,
AVG(me.price_usd)::NUMERIC(14,2) as avg_market_price,
MIN(me.price_usd)::NUMERIC(14,2) as min_price,
MAX(me.price_usd)::NUMERIC(14,2) as max_price
FROM watch_reference wr
LEFT JOIN market_event me ON me.reference_id = wr.id AND NOT me.is_quarantined AND me.price_usd > 0
GROUP BY wr.collection
ORDER BY event_count DESC
`);
// Recent quarantine alerts (unresolved, last 5)
const recentAlerts = await query(`
SELECT qr.id, qr.severity, qr.reason as field_name, qr.details,
me.reference_number_raw, me.source_name, qr.created_at
FROM quarantine_record qr
JOIN market_event me ON qr.event_id = me.event_id
WHERE qr.resolved = false
ORDER BY qr.created_at DESC
LIMIT 5
`);
// 24-hour collection stats
const stats24h = await query(`
SELECT
COUNT(*) as runs_24h,
COUNT(*) FILTER (WHERE status = 'completed') as success_24h,
COUNT(*) FILTER (WHERE status = 'failed') as failed_24h,
COALESCE(SUM(records_inserted), 0) as inserted_24h,
COALESCE(SUM(records_quarantined), 0) as quarantined_24h
FROM collector_run
WHERE started_at > NOW() - INTERVAL '24 hours'
`);
// Top movers — references with highest price variance in last 30 days
const topMovers = await query(`
SELECT wr.reference_number, wr.collection, wr.model_name,
COUNT(*) as events_30d,
AVG(me.price_usd)::NUMERIC(14,2) as avg_price,
STDDEV(me.price_usd)::NUMERIC(14,2) as price_stddev
FROM market_event me
JOIN watch_reference wr ON me.reference_id = wr.id
WHERE me.sale_date > CURRENT_DATE - 30
AND NOT me.is_quarantined
AND me.price_usd > 0
GROUP BY wr.id, wr.reference_number, wr.collection, wr.model_name
HAVING COUNT(*) >= 2
ORDER BY STDDEV(me.price_usd) DESC NULLS LAST
LIMIT 5
`);
return NextResponse.json({
success: true,
data: {
recent_runs: recentRuns,
collection_summary: collectionSummary,
recent_alerts: recentAlerts,
stats_24h: stats24h[0],
top_movers: topMovers,
},
});
}