const ENGINE_URL = process.env.ENGINE_URL || 'http://127.0.0.1:3040'; const ENGINE_SECRET = process.env.ENGINE_SECRET || 'zeropost_internal_2026'; async function call(path, options = {}) { const res = await fetch(`${ENGINE_URL}${path}`, { ...options, headers: { 'Content-Type': 'application/json', 'x-internal-secret': ENGINE_SECRET, ...(options.headers || {}), }, cache: options.cache || 'no-store', next: options.next, }); if (!res.ok) { const txt = await res.text(); throw new Error(`Engine ${res.status}: ${txt}`); } return res.json(); } export async function listArticles({ limit = 20, offset = 0, tag } = {}) { const params = new URLSearchParams({ limit, offset }); if (tag) params.set('tag', tag); return call(`/api/articles?${params}`, { next: { revalidate: 60 } }); } export async function getArticle(slug) { try { return await call(`/api/articles/${slug}`, { next: { revalidate: 60 } }); } catch { return null; } } export async function listTags() { return call('/api/articles/tags', { next: { revalidate: 300 } }); } export async function getLive() { try { return await call('/api/stats/live', { cache: 'no-store' }); } catch { return null; } } export async function listSeries() { try { return await call('/api/series', { cache: 'no-store' }); } catch { return []; } } export async function getSeries(slug) { try { return await call(`/api/series/${slug}`, { cache: 'no-store' }); } catch { return null; } } export async function listNotes({ limit = 20 } = {}) { try { return await call(`/api/notes?limit=${limit}`, { cache: 'no-store' }); } catch { return []; } } export async function getStats() { try { return await call('/api/stats', { cache: 'no-store' }); } catch { return null; } } export async function generateArticle(data) { return call('/api/articles/generate', { method: 'POST', body: JSON.stringify(data), }); } // ── Admin API ───────────────────────────────────────────────────────────────── export async function adminListArticles({ limit = 100, offset = 0 } = {}) { return call(`/api/articles/admin?limit=${limit}&offset=${offset}`); } export async function adminGetArticle(id) { return call(`/api/articles/id/${id}`); } export async function adminUpdateArticle(id, data) { return call(`/api/articles/${id}`, { method: 'PATCH', body: JSON.stringify(data), }); } export async function adminDeleteArticle(id) { return call(`/api/articles/${id}`, { method: 'DELETE' }); } export async function adminBackfillCovers(limit = 5) { return call('/api/articles/backfill-covers', { method: 'POST', body: JSON.stringify({ limit }), }); } export async function adminGenerateArticle(topic, tags = []) { return call('/api/articles/generate', { method: 'POST', body: JSON.stringify({ topic, tags, autoPublish: false }), }); }