/** * routes/zero.js — публичные роуты для сайта zeropost.ru/zero * Монтируется на /api/zero * * Без аутентификации — отдаём только published. */ const express = require('express'); const router = express.Router(); const zeroNotes = require('../services/zeroNotes'); const zPrompt = require('../services/zeroPrompt'); // GET /api/zero/notes?limit=20&offset=0&channel_id=1 router.get('/notes', async (req, res) => { try { const limit = Math.min(parseInt(req.query.limit) || 20, 50); const offset = parseInt(req.query.offset) || 0; const channelId = req.query.channel_id ? parseInt(req.query.channel_id) : null; const items = await zeroNotes.listPublished({ channelId, limit, offset }); res.json({ ok: true, items, limit, offset }); } catch (err) { console.error('[GET /api/zero/notes]', err.message); res.status(500).json({ error: err.message }); } }); // GET /api/zero/notes/:id — одна published заметка router.get('/notes/:id', async (req, res) => { try { const note = await zeroNotes.getById(parseInt(req.params.id)); if (!note || note.status !== 'published') { return res.status(404).json({ error: 'not found' }); } // Отдаём только публичные поля res.json({ ok: true, note: { id: note.id, channel_id: note.channel_id, content: note.content, theme: note.theme, theme_bucket: note.theme_bucket, pose: note.pose, image_url: note.image_url, published_at: note.published_at, channel_message_id: note.channel_message_id, }, }); } catch (err) { res.status(500).json({ error: err.message }); } }); // GET /api/zero/character — bio и описание для блока "Кто такой Зеро" router.get('/character', async (_req, res) => { res.json({ ok: true, character: zPrompt.CHARACTER, buckets: zPrompt.THEME_BUCKETS.map(b => ({ key: b.key, label: b.label })), }); }); module.exports = router;