← back to Ventura Corridor
iter 134: /api/magazine/today unified payload — feature + caption + tags + share/audio for IG-autopost
f40d96ecbadb354486022c5c02b5d5bafe4099f3 · 2026-05-06 18:54:09 -0700 · SteveStudio2
Files touched
Diff
commit f40d96ecbadb354486022c5c02b5d5bafe4099f3
Author: SteveStudio2 <stevestudio2@SteveStacStudio.lan>
Date: Wed May 6 18:54:09 2026 -0700
iter 134: /api/magazine/today unified payload — feature + caption + tags + share/audio for IG-autopost
---
src/server/index.ts | 40 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 40 insertions(+)
diff --git a/src/server/index.ts b/src/server/index.ts
index a0130eb..af7232b 100644
--- a/src/server/index.ts
+++ b/src/server/index.ts
@@ -1823,6 +1823,46 @@ app.get('/api/magazine/feature-of-the-day', async (_req, res) => {
}
});
+// Unified daily payload — what an IG-autopost / morning-email / standup-audio job needs in one call.
+app.get('/api/magazine/today', async (_req, res) => {
+ try {
+ const r = await query(`
+ SELECT mf.id, mf.headline, mf.subhead, mf.editorial, mf.pull_quote, mf.category_tag,
+ mf.published_at, mf.views, mf.taps,
+ b.name AS biz_name, b.address AS biz_address, b.city, b.zip
+ FROM magazine_features mf
+ JOIN businesses b ON b.id = mf.business_id
+ WHERE mf.editorial IS NOT NULL AND length(mf.editorial) > 200
+ AND mf.status IN ('published','reviewed')
+ ORDER BY (mf.id * (EXTRACT(DOY FROM CURRENT_DATE)::int + 1)) % (SELECT GREATEST(count(*), 1) FROM magazine_features)
+ LIMIT 1
+ `);
+ if (r.rowCount === 0) return res.json({ feature: null });
+ const f = r.rows[0];
+ const tags = ['#TheCorridor', '#VenturaBoulevard', '#LosAngeles'];
+ if (f.category_tag) tags.push('#' + String(f.category_tag).replace(/[^a-z0-9]/gi, ''));
+ if (f.city) tags.push('#' + String(f.city).replace(/\s+/g, ''));
+ const caption =
+ `${f.headline}\n\n` +
+ (f.subhead ? `${f.subhead}\n\n` : '') +
+ `${(f.editorial as string).slice(0, 380).replace(/\s+\S*$/, '')}…\n\n` +
+ `Read the full feature → /magazine/${f.id}\n\n` +
+ tags.join(' ');
+ res.json({
+ date: new Date().toISOString().slice(0, 10),
+ feature: f,
+ permalink: `/magazine/${f.id}`,
+ share_card: `/share/${f.id}`,
+ audio: `/api/magazine/${f.id}/audio.m4a`,
+ tags,
+ caption,
+ caption_chars: caption.length,
+ });
+ } catch (e: any) {
+ res.status(500).json({ error: e.message });
+ }
+});
+
// Random published feature — for fleet-tv-style rotators or sidebar widgets
app.get('/api/magazine/random', async (req, res) => {
try {
← 97c9f08 iter 133: 404 page now suggests a random published feature
·
back to Ventura Corridor
·
iter 135: IG-autopost dry-run job — writes daily JSON+HTML d 85d3731 →