const express = require('express'); const router = express.Router(); const { fetchJSON, uploadJSON, listImages, listTemplateFiles } = require('../services/pixelbin'); const { processCurl } = require('../services/openai2'); // GET /api/templates/images — must be BEFORE /:slug to avoid conflict router.get('/images', async (req, res) => { try { const images = await listImages(`brands/${process.env.MERCHANT_ID}/images`); res.json({ images }); } catch (err) { res.status(500).json({ error: err.message }); } }); // GET /api/templates router.get('/', async (req, res) => { try { const merchantId = process.env.MERCHANT_ID; const folder = `brands/${merchantId}/templates`; console.log(`[Templates] GET /api/templates start | merchant=${merchantId} | pid=${process.pid}`); const slugs = await listTemplateFiles(folder); console.log(`[Templates] GET /api/templates files | merchant=${merchantId} | slugs=[${slugs.join(', ')}]`); const templates = []; for (const slug of slugs) { const tmpl = await fetchJSON(folder, slug); if (tmpl) { console.log( `[Templates] GET /api/templates item | merchant=${merchantId} | slug=${slug} | eventSlug=${tmpl.eventSlug || 'n/a'} | approved=${!!tmpl.approvedVariant} | updatedAt=${tmpl.updatedAt || 'n/a'}` ); templates.push(tmpl); } else { console.log(`[Templates] GET /api/templates item-miss | merchant=${merchantId} | slug=${slug}`); } } console.log(`[Templates] GET /api/templates done | merchant=${merchantId} | count=${templates.length}`); res.json({ templates }); } catch (err) { res.status(500).json({ error: err.message }); } }); // GET /api/templates/:slug router.get('/:slug', async (req, res) => { try { const merchantId = process.env.MERCHANT_ID; const slug = req.params.slug; const folder = `brands/${merchantId}/templates`; console.log(`[Templates] GET /api/templates/:slug start | merchant=${merchantId} | slug=${slug} | pid=${process.pid}`); const tmpl = await fetchJSON(folder, slug); if (!tmpl) return res.status(404).json({ error: 'Template not found' }); console.log( `[Templates] GET /api/templates/:slug done | merchant=${merchantId} | slug=${slug} | approved=${!!tmpl.approvedVariant} | updatedAt=${tmpl.updatedAt || 'n/a'}` ); res.json(tmpl); } catch (err) { res.status(500).json({ error: err.message }); } }); // POST /api/templates/:slug/approve router.post('/:slug/approve', async (req, res) => { try { const { approvedVariant } = req.body; if (!approvedVariant) return res.status(400).json({ error: 'approvedVariant is required' }); const merchantId = process.env.MERCHANT_ID; const slug = req.params.slug; const folder = `brands/${merchantId}/templates`; console.log( `[Templates] POST /api/templates/:slug/approve start | merchant=${merchantId} | slug=${slug} | incomingLen=${approvedVariant.length} | pid=${process.pid}` ); const tmpl = await fetchJSON(folder, slug); if (!tmpl) return res.status(404).json({ error: 'Template not found' }); console.log( `[Templates] POST /api/templates/:slug/approve before | merchant=${merchantId} | slug=${slug} | approved=${!!tmpl.approvedVariant} | updatedAt=${tmpl.updatedAt || 'n/a'}` ); tmpl.approvedVariant = approvedVariant; tmpl.whitelistStatus = 'submitted'; tmpl.updatedAt = new Date().toISOString(); await uploadJSON(folder, slug, tmpl); console.log( `[Templates] POST /api/templates/:slug/approve after | merchant=${merchantId} | slug=${slug} | approved=${!!tmpl.approvedVariant} | updatedAt=${tmpl.updatedAt}` ); res.json(tmpl); } catch (err) { res.status(500).json({ error: err.message }); } }); // POST /api/templates/:slug/curl router.post('/:slug/curl', async (req, res) => { try { const { rawCurl } = req.body; if (!rawCurl) return res.status(400).json({ error: 'rawCurl is required' }); const folder = `brands/${process.env.MERCHANT_ID}/templates`; const tmpl = await fetchJSON(folder, req.params.slug); if (!tmpl) return res.status(404).json({ error: 'Template not found' }); if (!tmpl.approvedVariant) return res.status(400).json({ error: 'Template must have an approved variant first' }); const { processedCurl, variableMap } = await processCurl(rawCurl, tmpl.approvedVariant, req.params.slug); tmpl.rawCurl = rawCurl; tmpl.processedCurl = processedCurl; tmpl.variableMap = variableMap; tmpl.updatedAt = new Date().toISOString(); await uploadJSON(folder, req.params.slug, tmpl); res.json({ processedCurl, variableMap }); } catch (err) { res.status(500).json({ error: err.message }); } }); // POST /api/templates/:slug/image router.post('/:slug/image', async (req, res) => { try { const { imagePath } = req.body; if (imagePath === undefined) return res.status(400).json({ error: 'imagePath is required' }); const folder = `brands/${process.env.MERCHANT_ID}/templates`; const tmpl = await fetchJSON(folder, req.params.slug); if (!tmpl) return res.status(404).json({ error: 'Template not found' }); tmpl.selectedImagePath = imagePath; tmpl.updatedAt = new Date().toISOString(); await uploadJSON(folder, req.params.slug, tmpl); res.json(tmpl); } catch (err) { res.status(500).json({ error: err.message }); } }); module.exports = router;