From 00673fd2c99a8f2d81b925386157441f09a6f7ba Mon Sep 17 00:00:00 2001 From: cottongin Date: Mon, 24 Aug 2026 01:36:41 -0400 Subject: [PATCH] feat: add backend proxy endpoints for sticker wall retrieval and rendering Co-authored-by: Cursor --- backend/routes/stickerwalls.js | 60 ++++++++++++++++++++++++++++++++++ backend/server.js | 2 ++ 2 files changed, 62 insertions(+) create mode 100644 backend/routes/stickerwalls.js diff --git a/backend/routes/stickerwalls.js b/backend/routes/stickerwalls.js new file mode 100644 index 0000000..40991d6 --- /dev/null +++ b/backend/routes/stickerwalls.js @@ -0,0 +1,60 @@ +const express = require('express'); +const { authenticateToken } = require('../middleware/auth'); + +const router = express.Router(); + +const VOTE_APP_URL = process.env.VOTE_APP_URL; +const VOTE_APP_API_KEY = process.env.VOTE_APP_API_KEY; + +router.get('/:sessionId', authenticateToken, async (req, res) => { + const { sessionId } = req.params; + if (!VOTE_APP_URL) { + return res.status(503).json({ error: 'Vote app not configured' }); + } + + try { + const upstream = await fetch(`${VOTE_APP_URL}/stickerwalls/${sessionId}.png`); + if (!upstream.ok) { + return res.status(upstream.status).end(); + } + res.set('Content-Type', 'image/png'); + const cacheControl = upstream.headers.get('cache-control'); + if (cacheControl) { + res.set('Cache-Control', cacheControl); + } + const buffer = Buffer.from(await upstream.arrayBuffer()); + res.send(buffer); + } catch (err) { + console.error('Sticker wall GET proxy error:', err.message); + res.status(502).json({ error: 'Failed to fetch sticker wall' }); + } +}); + +router.post('/:sessionId/render', authenticateToken, async (req, res) => { + const { sessionId } = req.params; + if (!VOTE_APP_URL || !VOTE_APP_API_KEY) { + return res.status(503).json({ error: 'Vote app not configured' }); + } + + try { + const upstream = await fetch(`${VOTE_APP_URL}/api/stickerwalls/${sessionId}/render`, { + method: 'POST', + headers: { 'X-API-Key': VOTE_APP_API_KEY }, + }); + if (!upstream.ok) { + return res.status(upstream.status).end(); + } + res.set('Content-Type', 'image/png'); + const rendered = upstream.headers.get('x-sticker-wall-rendered'); + if (rendered) { + res.set('X-Sticker-Wall-Rendered', rendered); + } + const buffer = Buffer.from(await upstream.arrayBuffer()); + res.send(buffer); + } catch (err) { + console.error('Sticker wall render proxy error:', err.message); + res.status(502).json({ error: 'Failed to render sticker wall' }); + } +}); + +module.exports = router; diff --git a/backend/server.js b/backend/server.js index 4613e8c..d46f420 100644 --- a/backend/server.js +++ b/backend/server.js @@ -27,6 +27,7 @@ const statsRoutes = require('./routes/stats'); const pickerRoutes = require('./routes/picker'); const votesRoutes = require('./routes/votes'); const webhooksRoutes = require('./routes/webhooks'); +const stickerwallsRoutes = require('./routes/stickerwalls'); app.use('/api/auth', authRoutes); app.use('/api/games', gamesRoutes); @@ -35,6 +36,7 @@ app.use('/api/stats', statsRoutes); app.use('/api', pickerRoutes); app.use('/api/votes', votesRoutes); app.use('/api/webhooks', webhooksRoutes); +app.use('/api/stickerwalls', stickerwallsRoutes); // Error handling middleware app.use((err, req, res, next) => {