wulf-pulse/app/api/addigy/org-mappings/route.ts

172 lines
5.3 KiB
TypeScript
Raw Normal View History

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 }
);
}
}