/** * GET /api/admin/company-scope * Returns all active companies with their current in_scope status. * Companies without a company_scope row are implicitly in scope (true). * * Query params: * search — filter by company name (ILIKE) * type — filter by company_type integer */ import { NextRequest, NextResponse } from 'next/server'; import { requireAdmin } from '@/lib/auth-utils'; import postgresClient from '@/lib/services/postgres-client'; interface CompanyRow { id: string; company_name: string; company_type: number | null; in_scope: boolean; } const COMPANY_TYPE_LABELS: Record = { 1: 'Customer', 2: 'Canceled', 3: 'Cold', 4: 'Dead', 5: 'Warm', 6: 'Vendor', 7: 'Partner', 8: 'Prospect', }; export async function GET(request: NextRequest) { const { error } = await requireAdmin(); if (error) return error; const url = request.nextUrl; const search = url.searchParams.get('search')?.trim() || null; const typeParam = url.searchParams.get('type'); const typeFilter = typeParam ? parseInt(typeParam, 10) : null; const params: unknown[] = []; const conditions = ['c.is_active = true', 'c.is_deleted = false']; if (search) { params.push(`%${search}%`); conditions.push(`c.company_name ILIKE $${params.length}`); } if (typeFilter !== null && !isNaN(typeFilter)) { params.push(typeFilter); conditions.push(`c.company_type = $${params.length}`); } const result = await postgresClient.query( `SELECT c.id::text, c.company_name, c.company_type, COALESCE(cs.in_scope, true) AS in_scope FROM companies c LEFT JOIN company_scope cs ON cs.company_id = c.id WHERE ${conditions.join(' AND ')} ORDER BY c.company_name`, params ); const companies = result.rows.map((r) => ({ id: r.id, companyName: r.company_name, companyType: r.company_type, companyTypeLabel: r.company_type != null ? (COMPANY_TYPE_LABELS[r.company_type] ?? `Type ${r.company_type}`) : null, inScope: r.in_scope, })); const excluded = companies.filter((c) => !c.inScope).length; return NextResponse.json({ companies, total: companies.length, excluded }); }