// Meta router factory — ESM conversion of meta-server/routes/campaigns.routes.js. // Phase 6.2: mutations (PATCH /campaigns/:id/budget, POST /campaigns/:id/:action) // require the `meta_write` permission. Reads (GET) stay authenticated-only. import express from 'express'; import { requirePermission } from '../../../shared/auth/middleware.js'; import { fetchCampaigns, fetchAccountInsights, updateCampaignBudget, updateCampaignStatus, } from '../../services/meta/meta.service.js'; export function createMetaRouter() { const router = express.Router(); // Reads — authenticated-only router.get('/campaigns', async (req, res, next) => { try { const { since, until } = req.query; if (!since || !until) { return res.status(400).json({ error: 'Date range is required (since, until)' }); } const campaigns = await fetchCampaigns(since, until); res.json(campaigns); } catch (error) { console.error('Campaign fetch error:', error); res.status(500).json({ error: 'Failed to fetch campaigns', details: error.response?.data?.error?.message || error.message, }); } }); router.get('/account-insights', async (req, res) => { try { const { since, until } = req.query; if (!since || !until) { return res.status(400).json({ error: 'Date range is required (since, until)' }); } const insights = await fetchAccountInsights(since, until); res.json(insights); } catch (error) { console.error('Account insights fetch error:', error); res.status(500).json({ error: 'Failed to fetch account insights', details: error.response?.data?.error?.message || error.message, }); } }); // Writes — meta_write router.patch('/campaigns/:campaignId/budget', requirePermission('meta_write'), async (req, res) => { try { const { campaignId } = req.params; const { budget } = req.body; if (!budget) { return res.status(400).json({ error: 'Budget is required' }); } const result = await updateCampaignBudget(campaignId, budget); res.json(result); } catch (error) { console.error('Budget update error:', error); res.status(500).json({ error: 'Failed to update campaign budget', details: error.response?.data?.error?.message || error.message, }); } }); router.post('/campaigns/:campaignId/:action', requirePermission('meta_write'), async (req, res) => { try { const { campaignId, action } = req.params; if (!['pause', 'unpause'].includes(action)) { return res.status(400).json({ error: 'Invalid action. Use "pause" or "unpause"' }); } const result = await updateCampaignStatus(campaignId, action); res.json(result); } catch (error) { console.error('Status update error:', error); res.status(500).json({ error: 'Failed to update campaign status', details: error.response?.data?.error?.message || error.message, }); } }); return router; }