const express = require('express'); const router = express.Router(); const db = require('../db'); // GET /api/articles?feed_id=&folder_id=&status=unread|starred|all&search=&page=&limit= router.get('/', (req, res) => { const { feed_id, folder_id, status = 'all', search, page = 1, limit = 30 } = req.query; const clauses = []; const params = {}; if (feed_id) { clauses.push('a.feed_id = @feed_id'); params.feed_id = feed_id; } if (folder_id) { clauses.push('f.folder_id = @folder_id'); params.folder_id = folder_id; } if (status === 'unread') clauses.push('a.is_read = 0'); if (status === 'starred') clauses.push('a.is_starred = 1'); if (search) { clauses.push('(a.title LIKE @search OR a.summary LIKE @search)'); params.search = `%${search}%`; } const where = clauses.length ? `WHERE ${clauses.join(' AND ')}` : ''; const offset = (Number(page) - 1) * Number(limit); const articles = db.prepare(` SELECT a.id, a.feed_id, a.title, a.link, a.author, a.summary, a.image_url, a.published_at, a.is_read, a.is_starred, f.title AS feed_title, f.favicon AS feed_favicon FROM articles a JOIN feeds f ON f.id = a.feed_id ${where} ORDER BY a.published_at DESC LIMIT @limit OFFSET @offset `).all({ ...params, limit: Number(limit), offset }); const total = db.prepare(` SELECT COUNT(*) AS count FROM articles a JOIN feeds f ON f.id = a.feed_id ${where} `).get(params).count; res.json({ articles, total, page: Number(page), limit: Number(limit) }); }); router.get('/:id', (req, res) => { const article = db.prepare(` SELECT a.*, f.title AS feed_title, f.site_url AS feed_site_url, f.favicon AS feed_favicon FROM articles a JOIN feeds f ON f.id = a.feed_id WHERE a.id = ? `).get(req.params.id); if (!article) return res.status(404).json({ error: 'Article not found' }); res.json(article); }); router.patch('/:id', (req, res) => { const { is_read, is_starred } = req.body; const sets = []; const params = { id: req.params.id }; if (is_read !== undefined) { sets.push('is_read = @is_read'); params.is_read = is_read ? 1 : 0; } if (is_starred !== undefined) { sets.push('is_starred = @is_starred'); params.is_starred = is_starred ? 1 : 0; } if (!sets.length) return res.status(400).json({ error: 'Nothing to update' }); db.prepare(`UPDATE articles SET ${sets.join(', ')} WHERE id = @id`).run(params); res.json(db.prepare('SELECT * FROM articles WHERE id = ?').get(req.params.id)); }); // Bulk mark-as-read for a feed/folder/all router.post('/mark-read', (req, res) => { const { feed_id, folder_id, all } = req.body; if (all) { db.prepare('UPDATE articles SET is_read = 1 WHERE is_read = 0').run(); } else if (feed_id) { db.prepare('UPDATE articles SET is_read = 1 WHERE feed_id = ? AND is_read = 0').run(feed_id); } else if (folder_id) { db.prepare(`UPDATE articles SET is_read = 1 WHERE is_read = 0 AND feed_id IN (SELECT id FROM feeds WHERE folder_id = ?)`).run(folder_id); } else { return res.status(400).json({ error: 'Specify feed_id, folder_id, or all' }); } res.json({ ok: true }); }); module.exports = router;