[object Object]

← back to Ventura Corridor

iter 147: /api/magazine.json now accepts ?cat= and ?limit= for per-vertical JSON Feed consumers

af14cb7e79451e2625eb709c394a0648b944df06 · 2026-05-06 19:13:32 -0700 · SteveStudio2

Files touched

Diff

commit af14cb7e79451e2625eb709c394a0648b944df06
Author: SteveStudio2 <stevestudio2@SteveStacStudio.lan>
Date:   Wed May 6 19:13:32 2026 -0700

    iter 147: /api/magazine.json now accepts ?cat= and ?limit= for per-vertical JSON Feed consumers
---
 src/server/index.ts | 22 +++++++++++++++-------
 1 file changed, 15 insertions(+), 7 deletions(-)

diff --git a/src/server/index.ts b/src/server/index.ts
index be0cfa6..dcb7bf2 100644
--- a/src/server/index.ts
+++ b/src/server/index.ts
@@ -1994,24 +1994,32 @@ app.get('/api/magazine/:id/tap', async (req, res) => {
 });
 
 // JSON Feed 1.1 — full feed of published features (https://jsonfeed.org/)
-app.get('/api/magazine.json', async (_req, res) => {
+// Optional: ?cat=<category-tag> filters to a single vertical, ?limit=N (max 500).
+app.get('/api/magazine.json', async (req, res) => {
   try {
     const baseUrl = process.env.PUBLIC_BASE_URL || 'http://127.0.0.1:9780';
+    const cat = String(req.query.cat || '').trim() || null;
+    const limit = Math.min(500, Math.max(1, parseInt(String(req.query.limit || 200), 10) || 200));
+    const where: string[] = [`mf.status = 'published'`];
+    const params: any[] = [];
+    if (cat) { params.push(cat); where.push(`mf.category_tag = $${params.length}`); }
+    params.push(limit);
     const r = await query(
       `SELECT mf.id, mf.headline, mf.subhead, mf.editorial, mf.pull_quote, mf.category_tag,
               mf.generated_at, mf.published_at,
               b.name AS biz_name, b.address AS biz_address, b.city
        FROM magazine_features mf JOIN businesses b ON b.id = mf.business_id
-       WHERE mf.status = 'published'
+       WHERE ${where.join(' AND ')}
        ORDER BY mf.published_at DESC NULLS LAST, mf.generated_at DESC
-       LIMIT 200`
+       LIMIT $${params.length}`,
+      params
     );
     res.json({
       version: 'https://jsonfeed.org/version/1.1',
-      title: 'The Corridor',
-      home_page_url: `${baseUrl}/issue`,
-      feed_url: `${baseUrl}/api/magazine.json`,
-      description: "A magazine of who's here on Ventura Boulevard.",
+      title: cat ? `The Corridor · ${cat}` : 'The Corridor',
+      home_page_url: `${baseUrl}/issue${cat ? '/' + cat : ''}`,
+      feed_url: `${baseUrl}/api/magazine.json${cat ? '?cat=' + cat : ''}`,
+      description: cat ? `${cat} on Ventura Boulevard.` : "A magazine of who's here on Ventura Boulevard.",
       authors: [{ name: 'The Corridor desk' }],
       language: 'en',
       items: r.rows.map((f: any) => ({

← a4769a4 iter 146: auto-cover job — promotes top-tapped feature to co  ·  back to Ventura Corridor  ·  iter 148: /api/magazine/lottery?n=N&cat= — random N features a9953cd →