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