← back to Norma

app/api/ingest/news/route.ts

68 lines

import { NextRequest, NextResponse } from 'next/server';
import { requireRole } from '@/lib/require-role';
import { syncNews, DEFAULT_NEWS_FEEDS } from '@/lib/ingest-news';

/**
 * POST /api/ingest/news
 *
 * Trigger a news RSS sync. Fetches headlines from configured RSS feeds,
 * generates Gemini summaries, and persists to news_items.
 * Requires an authenticated session cookie.
 *
 * Optional body:
 *   { feeds?: string[] }   — override the default feed list with custom RSS URLs
 *
 * Response:
 *   200 { inserted, skipped, total, feeds, errors }  — sync completed
 *   400 { error: string }                            — invalid body
 *   500 { error: string }                            — sync failed
 */
export async function POST(request: NextRequest) {
  const auth = requireRole(request, 'admin', 'staff');
  if (auth instanceof NextResponse) return auth;

  let feedUrls: string[] = DEFAULT_NEWS_FEEDS;

  // Parse optional body — if malformed JSON just fall through to defaults
  const contentType = request.headers.get('content-type') ?? '';
  if (contentType.includes('application/json')) {
    try {
      const body = await request.json();

      if (body.feeds !== undefined) {
        if (
          !Array.isArray(body.feeds) ||
          body.feeds.some((f: unknown) => typeof f !== 'string')
        ) {
          return NextResponse.json(
            { error: '`feeds` must be an array of URL strings' },
            { status: 400 },
          );
        }

        if (body.feeds.length === 0) {
          return NextResponse.json(
            { error: '`feeds` array must not be empty' },
            { status: 400 },
          );
        }

        feedUrls = body.feeds as string[];
      }
    } catch {
      // Non-JSON or empty body — use defaults silently
    }
  }

  try {
    const result = await syncNews(feedUrls);
    return NextResponse.json(result, { status: 200 });
  } catch (err) {
    console.error('[api/ingest/news] POST error:', (err as Error).message);
    return NextResponse.json(
      { error: `News sync failed: ${(err as Error).message}` },
      { status: 500 },
    );
  }
}