← back to Omega Watches 2
src/app/api/alerts/route.ts
123 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 rules = await query(`
SELECT par.*, wr.reference_number, wr.collection, wr.model_name,
(SELECT AVG(me.price_usd)::NUMERIC(14,2)
FROM market_event me
WHERE me.reference_id = par.reference_id
AND NOT me.is_quarantined AND me.price_usd > 0
AND me.sale_date > CURRENT_DATE - 30
) as current_avg_price
FROM price_alert_rule par
JOIN watch_reference wr ON par.reference_id = wr.id
ORDER BY par.is_active DESC, par.created_at DESC
`);
// Check which rules are currently triggered
const enriched = rules.map((r: any) => {
const avg = parseFloat(r.current_avg_price) || 0;
let triggered = false;
if (r.alert_type === "price_below" && avg > 0 && avg < parseFloat(r.threshold)) triggered = true;
if (r.alert_type === "price_above" && avg > 0 && avg > parseFloat(r.threshold)) triggered = true;
return { ...r, is_triggered: triggered };
});
return NextResponse.json({
success: true,
data: {
rules: enriched,
summary: {
total: rules.length,
active: rules.filter((r: any) => r.is_active).length,
triggered: enriched.filter((r: any) => r.is_triggered).length,
},
},
});
}
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 { reference_number, alert_type, threshold, notes } = await request.json();
if (!reference_number || !alert_type || !threshold) {
return NextResponse.json(
{ success: false, error: { code: "MISSING_PARAMS", message: "reference_number, alert_type, and threshold required" } },
{ status: 400 }
);
}
const ref = await query(
"SELECT id FROM watch_reference WHERE reference_number = $1",
[reference_number]
);
if (ref.length === 0) {
return NextResponse.json(
{ success: false, error: { code: "NOT_FOUND", message: "Reference not found" } },
{ status: 404 }
);
}
const result = await query(
`INSERT INTO price_alert_rule (reference_id, alert_type, threshold, notes, created_by)
VALUES ($1, $2, $3, $4, $5)
RETURNING *`,
[ref[0].id, alert_type, threshold, notes || null, session.username]
);
return NextResponse.json({ success: true, data: result[0] });
}
export async function PUT(request: NextRequest) {
const session = await getSession(request);
if (!session) {
return NextResponse.json(
{ success: false, error: { code: "UNAUTHORIZED", message: "Login required" } },
{ status: 401 }
);
}
const { id, is_active } = await request.json();
if (!id || is_active === undefined) {
return NextResponse.json(
{ success: false, error: { code: "MISSING_PARAMS", message: "id and is_active required" } },
{ status: 400 }
);
}
await query(
"UPDATE price_alert_rule SET is_active = $1 WHERE id = $2",
[is_active, id]
);
return NextResponse.json({ success: true, data: { id, is_active } });
}