import { NextRequest, NextResponse } from 'next/server'; import { getDb } from '@/lib/db'; import Parser from 'rss-parser'; export const dynamic = 'force-dynamic'; export async function GET() { const db = await getDb(); const feeds = await db.all(` SELECT f.*, (SELECT COUNT(*) FROM rss_items WHERE feed_id = f.id) as item_count FROM rss_feeds f ORDER BY f.created_at ASC `); return NextResponse.json(feeds); } export async function POST(req: NextRequest) { const { url, name } = await req.json(); if (!url || typeof url !== 'string') { return NextResponse.json({ error: 'URL is required' }, { status: 400 }); } // Validate URL format try { new URL(url); } catch { return NextResponse.json({ error: 'Invalid URL format' }, { status: 400 }); } // Validate it's actually an RSS feed const parser = new Parser({ timeout: 5000 }); let parsed; try { parsed = await parser.parseURL(url); } catch { return NextResponse.json({ error: 'Could not parse RSS feed at this URL' }, { status: 400 }); } const feedName = name?.trim() || parsed.title || new URL(url).hostname; const db = await getDb(); try { const result = await db.run( 'INSERT INTO rss_feeds (name, url) VALUES (?, ?)', feedName, url.trim() ); const feedId = result.lastID; // Immediately fetch and cache items for (const item of parsed.items || []) { if (!item.title || !item.link) continue; await db.run( `INSERT OR IGNORE INTO rss_items (feed_id, title, link, pub_date, creator, snippet) VALUES (?, ?, ?, ?, ?, ?)`, feedId, item.title, item.link, item.pubDate || item.isoDate || null, item.creator || item.author || null, (item.contentSnippet || item.content || '').substring(0, 500) || null ); } await db.run( 'UPDATE rss_feeds SET last_fetched = ? WHERE id = ?', new Date().toISOString(), feedId ); const feed = await db.get('SELECT * FROM rss_feeds WHERE id = ?', feedId); return NextResponse.json(feed, { status: 201 }); } catch (err: unknown) { if (err instanceof Error && err.message.includes('UNIQUE')) { return NextResponse.json({ error: 'Feed URL already exists' }, { status: 409 }); } throw err; } } export async function DELETE(req: NextRequest) { const { id } = await req.json(); if (!id) { return NextResponse.json({ error: 'Feed id is required' }, { status: 400 }); } const db = await getDb(); await db.run('DELETE FROM rss_items WHERE feed_id = ?', id); await db.run('DELETE FROM rss_feeds WHERE id = ?', id); return NextResponse.json({ ok: true }); }