Six site improvements picked from a "what could be better" review, plus a Jest test suite covering the two areas with the trickiest money-handling history in this project (early-bird pricing tranches, donation-leg accounting): - "Add to calendar" .ics download on event pages and in confirmation emails - sitemap.xml, robots.txt, and Open Graph/Twitter metadata for public pages - Sentry error monitoring (backend + frontend), a no-op until SENTRY_DSN is set - Nightly local pg_dump backups with a Site Settings tab to browse/trigger/download - Admin audit trail for refunds, donations, manual registrations, event and settings changes, and staff-initiated cancellations - Jest tests reproducing and guarding against the 1.8.0 tranche-pricing bug and the 1.4.2 donation-balance-inflation bug Wallet passes (Google/Apple) were scoped out of this round — Apple Wallet needs a paid Apple Developer account the project doesn't have yet, and the user preferred shipping both together later rather than Google alone now. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
88 lines
3.2 KiB
JavaScript
88 lines
3.2 KiB
JavaScript
const express = require('express');
|
|
const router = express.Router();
|
|
const {
|
|
createEvent,
|
|
getEvents,
|
|
getAllEvents,
|
|
getEventsAll,
|
|
getEventById,
|
|
getEventIcs,
|
|
updateEvent,
|
|
getEventNotifyRecipients,
|
|
updateEventNotifyRecipients,
|
|
deleteEvent,
|
|
createEventOption,
|
|
updateEventOption,
|
|
deleteEventOption,
|
|
createOptionVariant,
|
|
updateOptionVariant,
|
|
deleteOptionVariant,
|
|
listEventAttachments,
|
|
uploadEventAttachment,
|
|
deleteEventAttachment,
|
|
attachmentsStatus,
|
|
attachmentsSync,
|
|
emailEventAttendees,
|
|
scheduleEmailEventAttendees,
|
|
whatsappEventAttendees,
|
|
scheduleWhatsappEventAttendees,
|
|
getEventByAlias
|
|
} = require('../controllers/eventController');
|
|
const { protect, admin, supervisor, optionalAuth } = require('../middleware/authMiddleware');
|
|
|
|
// Public routes
|
|
router.get('/', getEvents);
|
|
|
|
// Staff/supervisor/admin: all events including hidden, optional past/inactive filters
|
|
router.get('/all', protect, getEventsAll);
|
|
|
|
// Admin routes
|
|
router.get('/admin/all', protect, admin, getAllEvents);
|
|
router.get('/attachments/status', protect, admin, attachmentsStatus);
|
|
router.post('/attachments/sync', protect, admin, attachmentsSync);
|
|
|
|
// Public route for single event (keep after specific admin routes).
|
|
// optionalAuth populates req.user when a valid token is present so staff/supervisor/admin
|
|
// can still load inactive events (e.g. for cashup or editing) without being 404'd.
|
|
router.get('/:id', optionalAuth, getEventById);
|
|
router.get('/:id/ics', optionalAuth, getEventIcs);
|
|
router.get('/by-alias/:redirectUrl', getEventByAlias);
|
|
|
|
// Create/Update/Delete event
|
|
router.post('/', protect, supervisor, createEvent);
|
|
router.route('/:id')
|
|
.put(protect, supervisor, updateEvent)
|
|
.delete(protect, admin, deleteEvent);
|
|
|
|
// Notification recipients: who gets registration/payment/daily-summary emails for this event
|
|
router.route('/:id/notify-recipients')
|
|
.get(protect, supervisor, getEventNotifyRecipients)
|
|
.put(protect, supervisor, updateEventNotifyRecipients);
|
|
|
|
// Attachments routes
|
|
router.get('/:id/attachments', listEventAttachments); // public read (used by event detail page)
|
|
router.post('/:id/attachments', protect, supervisor, ...uploadEventAttachment);
|
|
router.delete('/:eventId/attachments/:attachmentId', protect, supervisor, deleteEventAttachment);
|
|
|
|
// Bulk email attendees
|
|
router.post('/:id/email-attendees', protect, supervisor, emailEventAttendees);
|
|
// Schedule bulk email to attendees
|
|
router.post('/:id/email-attendees/schedule', protect, supervisor, scheduleEmailEventAttendees);
|
|
// Bulk WhatsApp message to attendees
|
|
router.post('/:id/whatsapp-attendees', protect, supervisor, whatsappEventAttendees);
|
|
// Schedule bulk WhatsApp message to attendees
|
|
router.post('/:id/whatsapp-attendees/schedule', protect, supervisor, scheduleWhatsappEventAttendees);
|
|
|
|
// Event options routes
|
|
router.post('/:id/options', protect, supervisor, createEventOption);
|
|
router.route('/options/:id')
|
|
.put(protect, supervisor, updateEventOption)
|
|
.delete(protect, admin, deleteEventOption);
|
|
|
|
// Option variant routes
|
|
router.post('/options/:id/variants', protect, supervisor, createOptionVariant);
|
|
router.route('/variants/:id')
|
|
.put(protect, supervisor, updateOptionVariant)
|
|
.delete(protect, admin, deleteOptionVariant);
|
|
|
|
module.exports = router; |