import { Router, Request, Response, NextFunction } from 'express'; import { actionCampaignsService } from './action-campaigns.service'; import { createActionCampaignSchema, updateActionCampaignSchema, createActionStepSchema, updateActionStepSchema, reorderStepsSchema, markCompleteSchema, } from './action-campaigns.schemas'; import { validate } from '../../middleware/validate'; import { authenticate, optionalAuth } from '../../middleware/auth.middleware'; import { requireRole } from '../../middleware/rbac.middleware'; import { INFLUENCE_ROLES } from '../../utils/roles'; const publicRouter = Router(); publicRouter.get( '/active', optionalAuth, async (req: Request, res: Response, next: NextFunction) => { try { if (req.user?.id) { const data = await actionCampaignsService.getActiveForUser(req.user.id); res.json(data); return; } const campaign = await actionCampaignsService.getActiveCampaign(); res.json(campaign); } catch (err) { next(err); } }, ); publicRouter.post( '/:slug/steps/:stepId/complete', authenticate, validate(markCompleteSchema), async (req: Request, res: Response, next: NextFunction) => { try { const stepId = req.params.stepId as string; const completion = await actionCampaignsService.markStepComplete( req.user!.id, stepId, (req.body as { source?: import('@prisma/client').ActionStepCompletionSource }).source, ); res.status(201).json({ ok: true, completion }); } catch (err) { next(err); } }, ); const adminRouter = Router(); adminRouter.use(authenticate); adminRouter.use(requireRole(...INFLUENCE_ROLES)); adminRouter.get('/', async (_req: Request, res: Response, next: NextFunction) => { try { const campaigns = await actionCampaignsService.listCampaigns(); res.json(campaigns); } catch (err) { next(err); } }); adminRouter.post( '/', validate(createActionCampaignSchema), async (req: Request, res: Response, next: NextFunction) => { try { const campaign = await actionCampaignsService.createCampaign(req.body, req.user!.id); res.status(201).json(campaign); } catch (err) { next(err); } }, ); adminRouter.get('/:id', async (req: Request, res: Response, next: NextFunction) => { try { const id = req.params.id as string; const campaign = await actionCampaignsService.getCampaign(id); res.json(campaign); } catch (err) { next(err); } }); adminRouter.put( '/:id', validate(updateActionCampaignSchema), async (req: Request, res: Response, next: NextFunction) => { try { const id = req.params.id as string; const campaign = await actionCampaignsService.updateCampaign(id, req.body); res.json(campaign); } catch (err) { next(err); } }, ); adminRouter.delete('/:id', async (req: Request, res: Response, next: NextFunction) => { try { const id = req.params.id as string; await actionCampaignsService.deleteCampaign(id); res.status(204).send(); } catch (err) { next(err); } }); adminRouter.post('/:id/activate', async (req: Request, res: Response, next: NextFunction) => { try { const id = req.params.id as string; const campaign = await actionCampaignsService.activateCampaign(id); res.json(campaign); } catch (err) { next(err); } }); adminRouter.post( '/:id/steps', validate(createActionStepSchema), async (req: Request, res: Response, next: NextFunction) => { try { const id = req.params.id as string; const step = await actionCampaignsService.addStep(id, req.body); res.status(201).json(step); } catch (err) { next(err); } }, ); adminRouter.put( '/:id/steps/:stepId', validate(updateActionStepSchema), async (req: Request, res: Response, next: NextFunction) => { try { const stepId = req.params.stepId as string; const step = await actionCampaignsService.updateStep(stepId, req.body); res.json(step); } catch (err) { next(err); } }, ); adminRouter.delete('/:id/steps/:stepId', async (req: Request, res: Response, next: NextFunction) => { try { const stepId = req.params.stepId as string; await actionCampaignsService.deleteStep(stepId); res.status(204).send(); } catch (err) { next(err); } }); adminRouter.post( '/:id/steps/reorder', validate(reorderStepsSchema), async (req: Request, res: Response, next: NextFunction) => { try { const id = req.params.id as string; const { stepIds } = req.body as { stepIds: string[] }; const steps = await actionCampaignsService.reorderSteps(id, stepIds); res.json(steps); } catch (err) { next(err); } }, ); export { publicRouter as actionCampaignsRouter, adminRouter as actionCampaignsAdminRouter };