import { NextRequest, NextResponse } from 'next/server'; import { Pool } from 'pg'; import { getAddigyClient } from '@/lib/services/addigy-factory'; import { AddigyOrgMapping } from '@/lib/types/addigy'; const pool = new Pool({ host: process.env.POSTGRES_HOST, port: parseInt(process.env.POSTGRES_PORT || '5432'), database: process.env.POSTGRES_DB, user: process.env.POSTGRES_USER, password: process.env.POSTGRES_PASSWORD, }); export async function GET(request: NextRequest) { try { const searchParams = request.nextUrl.searchParams; const includeUnmapped = searchParams.get('includeUnmapped') === 'true'; // Get all mappings from database const result = await pool.query<{ id: number; addigy_org_id: string; addigy_org_name: string; autotask_company_id: number; autotask_company_name: string; created_at: string; updated_at: string; }>('SELECT * FROM addigy_org_mappings ORDER BY addigy_org_name'); const mappings: AddigyOrgMapping[] = result.rows.map((row) => ({ id: row.id, addigyOrgId: row.addigy_org_id, addigyOrgName: row.addigy_org_name, autotaskCompanyId: row.autotask_company_id, autotaskCompanyName: row.autotask_company_name, createdAt: row.created_at, updatedAt: row.updated_at, })); // If includeUnmapped is true, fetch all Addigy policies (which act as organizations/sites) and merge if (includeUnmapped) { try { const addigyClient = getAddigyClient(); // In Addigy, policies are the grouping mechanism (like sites/organizations) const allPolicies = await addigyClient.getAllPolicies(); const mappedOrgIds = new Set(mappings.map((m) => m.addigyOrgId)); const unmappedOrgs = allPolicies .filter((policy) => !mappedOrgIds.has(policy.policyId)) .map((policy) => ({ id: 0, // Temporary ID for unmapped addigyOrgId: policy.policyId, addigyOrgName: policy.name, autotaskCompanyId: 0, autotaskCompanyName: '', createdAt: '', updatedAt: '', })); return NextResponse.json({ mappings: [...mappings, ...unmappedOrgs], totalMapped: mappings.length, totalUnmapped: unmappedOrgs.length, }); } catch (addigyError) { // If Addigy API fails, just return the mapped organizations console.warn('Failed to fetch unmapped Addigy policies:', addigyError); return NextResponse.json({ mappings: mappings, totalMapped: mappings.length, totalUnmapped: 0, warning: 'Could not fetch unmapped policies from Addigy API. Check API configuration.', }); } } return NextResponse.json({ mappings }); } catch (error) { console.error('Error fetching Addigy org mappings:', error); return NextResponse.json( { error: 'Failed to fetch Addigy org mappings' }, { status: 500 } ); } } export async function POST(request: NextRequest) { try { const body = await request.json(); const { addigyOrgId, addigyOrgName, autotaskCompanyId, autotaskCompanyName, } = body; if (!addigyOrgId || !autotaskCompanyId) { return NextResponse.json( { error: 'Missing required fields' }, { status: 400 } ); } // Insert or update mapping const result = await pool.query<{ id: number; addigy_org_id: string; addigy_org_name: string; autotask_company_id: number; autotask_company_name: string; created_at: string; updated_at: string; }>( `INSERT INTO addigy_org_mappings (addigy_org_id, addigy_org_name, autotask_company_id, autotask_company_name) VALUES ($1, $2, $3, $4) ON CONFLICT (addigy_org_id) DO UPDATE SET autotask_company_id = EXCLUDED.autotask_company_id, autotask_company_name = EXCLUDED.autotask_company_name, updated_at = CURRENT_TIMESTAMP RETURNING *`, [addigyOrgId, addigyOrgName, autotaskCompanyId, autotaskCompanyName] ); const mapping: AddigyOrgMapping = { id: result.rows[0].id, addigyOrgId: result.rows[0].addigy_org_id, addigyOrgName: result.rows[0].addigy_org_name, autotaskCompanyId: result.rows[0].autotask_company_id, autotaskCompanyName: result.rows[0].autotask_company_name, createdAt: result.rows[0].created_at, updatedAt: result.rows[0].updated_at, }; return NextResponse.json({ mapping }); } catch (error) { console.error('Error creating Addigy org mapping:', error); return NextResponse.json( { error: 'Failed to create Addigy org mapping' }, { status: 500 } ); } } export async function DELETE(request: NextRequest) { try { const searchParams = request.nextUrl.searchParams; const id = searchParams.get('id'); if (!id) { return NextResponse.json( { error: 'Missing mapping ID' }, { status: 400 } ); } await pool.query('DELETE FROM addigy_org_mappings WHERE id = $1', [ parseInt(id), ]); return NextResponse.json({ success: true }); } catch (error) { console.error('Error deleting Addigy org mapping:', error); return NextResponse.json( { error: 'Failed to delete Addigy org mapping' }, { status: 500 } ); } }