3fe32d923e
Build & Auto-Repair / build (push) Has been cancelled
- 86 catch blocks in 49 API route files now return the actual error message via error.message
- 14 campaign/lead/config catch blocks that lacked console.error now log errors
- 17 client pages/components now show toast.error notifications on API failures
- Silent .catch(() => {}) and finally-only try blocks now surface errors to users
75 lines
2.3 KiB
TypeScript
75 lines
2.3 KiB
TypeScript
import { NextRequest, NextResponse } from "next/server"
|
|
import { getSessionUser } from "@/lib/auth"
|
|
import { query } from "@/lib/db"
|
|
|
|
function stageStatus(name: string): string {
|
|
switch (name) {
|
|
case "New": return "open"
|
|
case "Contacted": return "contacted"
|
|
case "Qualified":
|
|
case "Interested":
|
|
case "Demo Scheduled":
|
|
case "Negotiation": return "pending"
|
|
case "Closed Won": return "closed"
|
|
case "Closed Lost": return "ignored"
|
|
default: return "open"
|
|
}
|
|
}
|
|
|
|
export async function GET(request: NextRequest) {
|
|
try {
|
|
const user = await getSessionUser()
|
|
if (!user) return NextResponse.json({ error: "Unauthorized" }, { status: 401 })
|
|
|
|
const isAdmin = user.role === "admin" || user.role === "super_admin"
|
|
|
|
const result = await query(
|
|
`SELECT ls.id, ls.name, ls.sort_order, ls.probability,
|
|
COALESCE(
|
|
json_agg(
|
|
json_build_object(
|
|
'id', l.id,
|
|
'company_name', l.company_name,
|
|
'contact_name', l.contact_name,
|
|
'email', l.email,
|
|
'phone', l.phone,
|
|
'score', l.score,
|
|
'notes', l.notes,
|
|
'assigned_to', l.assigned_to,
|
|
'created_at', l.created_at
|
|
)
|
|
ORDER BY l.created_at DESC
|
|
) FILTER (WHERE l.id IS NOT NULL),
|
|
'[]'::json
|
|
) AS leads
|
|
FROM lead_stages ls
|
|
LEFT JOIN leads l ON l.stage_id = ls.id AND l.deleted_at IS NULL
|
|
WHERE ls.is_active = true
|
|
GROUP BY ls.id, ls.name, ls.sort_order, ls.probability
|
|
ORDER BY ls.sort_order`
|
|
)
|
|
|
|
const columns = result.rows.map((r: any) => {
|
|
const status = stageStatus(r.name)
|
|
let leads = r.leads || []
|
|
if (!isAdmin) {
|
|
leads = leads.filter((l: any) => l.assigned_to === user.id)
|
|
}
|
|
return {
|
|
id: r.id,
|
|
name: r.name,
|
|
status,
|
|
sortOrder: r.sort_order,
|
|
probability: r.probability,
|
|
leads,
|
|
}
|
|
})
|
|
|
|
return NextResponse.json(columns)
|
|
} catch (error) {
|
|
console.error("Kanban API error:", error)
|
|
const message = error instanceof Error ? error.message : "Failed to load kanban data"
|
|
return NextResponse.json({ error: message }, { status: 500 })
|
|
}
|
|
}
|