wulf-pulse/app/api/data/resources/route.ts

111 lines
3.2 KiB
TypeScript
Raw Normal View History

/**
* Resources Data API Endpoint
* GET /api/data/resources - Query resources (users) from PostgreSQL
*/
import { NextRequest, NextResponse } from 'next/server';
import postgresClient from '@/lib/services/postgres-client';
export async function GET(request: NextRequest) {
try {
const searchParams = request.nextUrl.searchParams;
const limit = parseInt(searchParams.get('limit') || '100');
const offset = parseInt(searchParams.get('offset') || '0');
const isActive = searchParams.get('isActive');
const sortBy = searchParams.get('sort');
const sortOrder = searchParams.get('order') || 'asc';
const ids = searchParams.get('ids'); // Comma-separated IDs for enrichment
// Build conditions and parameters
const conditions: string[] = [];
const params: any[] = [];
if (ids) {
// Fetch specific resources by IDs
const idArray = ids.split(',').map(id => parseInt(id.trim())).filter(id => !isNaN(id));
if (idArray.length > 0) {
conditions.push(`id = ANY($${params.length + 1})`);
params.push(idArray);
}
}
if (isActive !== null && !ids) {
conditions.push('is_active = $' + (params.length + 1));
params.push(isActive === 'true');
}
const whereClause = conditions.length > 0 ? 'WHERE ' + conditions.join(' AND ') : '';
// Build dynamic ORDER BY clause
let orderByClause = 'ORDER BY last_name ASC, first_name ASC';
if (sortBy) {
const validColumns = ['id', 'first_name', 'last_name', 'email', 'user_name', 'title', 'is_active', 'resource_type'];
if (validColumns.includes(sortBy)) {
const direction = sortOrder.toLowerCase() === 'desc' ? 'DESC' : 'ASC';
orderByClause = `ORDER BY ${sortBy} ${direction}, last_name ASC, first_name ASC`;
}
}
// Query resources
const query = `
SELECT
id,
first_name,
last_name,
email,
user_name,
title,
office_phone,
mobile_phone,
office_extension,
is_active,
location_id,
resource_type,
pay_roll_identifier,
hire_date,
travel_availability_pct,
survey_resource_rating,
created_at,
updated_at,
synced_at,
is_deleted,
deleted_at
FROM resources
${whereClause}
${orderByClause}
LIMIT $${params.length + 1} OFFSET $${params.length + 2}
`;
params.push(limit, offset);
const result = await postgresClient.query(query, params);
const resources = result.rows;
// Get total count
const countQuery = `
SELECT COUNT(*) as total
FROM resources
${whereClause}
`;
const countResult = await postgresClient.query(countQuery, params.slice(0, -2));
const totalCount = parseInt(countResult.rows[0].total);
return NextResponse.json({
resources,
pagination: {
limit,
offset,
total: totalCount,
hasMore: offset + resources.length < totalCount,
},
});
} catch (error) {
console.error('Failed to fetch resources:', error);
return NextResponse.json(
{ error: 'Failed to fetch resources' },
{ status: 500 }
);
}
}