← back to Norma
app/api/drive/search/route.ts
54 lines
/**
* GET /api/drive/search?q=term1,term2&limit=10
* Search Google Drive (natalia@studentdebtcrisis.org OAuth).
*
* Responses:
* 200 { files: [...], connected: true }
* 200 { files: [], connected: false, reason: 'not_authorized' | 'scope_missing' }
*/
import { NextRequest, NextResponse } from 'next/server';
import { requireRole } from '@/lib/require-role';
import { searchDrive, hasDriveScope } from '@/lib/drive';
export async function GET(request: NextRequest) {
const auth = requireRole(request, 'admin', 'staff');
if (auth instanceof NextResponse) return auth;
try {
const { searchParams } = new URL(request.url);
const q = searchParams.get('q') || '';
const limit = Math.min(parseInt(searchParams.get('limit') || '10', 10) || 10, 20);
const keywords = q.split(/[,\s]+/).map((k) => k.trim()).filter((k) => k.length >= 3).slice(0, 5);
if (keywords.length === 0) {
return NextResponse.json({ files: [], connected: true });
}
const connected = await hasDriveScope();
if (!connected) {
return NextResponse.json({
files: [],
connected: false,
reason: 'scope_missing',
reauthUrl: '/api/gmail/oauth/start',
});
}
const files = await searchDrive(keywords, limit);
return NextResponse.json({ files, connected: true });
} catch (err) {
const msg = (err as Error).message || '';
if (msg === 'drive_scope_missing') {
return NextResponse.json({
files: [],
connected: false,
reason: 'scope_missing',
reauthUrl: '/api/gmail/oauth/start',
});
}
console.error('[drive/search] error:', msg);
return NextResponse.json({ error: 'Drive search failed' }, { status: 500 });
}
}