- v2: staff list (paged), event registrations, registration in full (+ /me), status, manual registration, bulk, items, invoice, coupon, attendees and form links, form drafts and responses. - src/services/registrationAdmin.ts holds the rest of registrationController.js (now v1 wrappers). - Frontend: fetchAllRegistrations(); every registration screen on v2. - Roadmap: money gets its own release (1.51.11); webhooks and links move to 1.51.16. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ls1vMdg2GYqbnKZmPaX1ot
65 lines
2.8 KiB
JavaScript
65 lines
2.8 KiB
JavaScript
// Registrations (v1). The work is in src/services: registrations.ts (making and cancelling
|
|
// one) and registrationAdmin.ts (everything after) — shared with /api/v2.
|
|
const { getClientIp } = require('../utils/requestUtils');
|
|
const { v1StatusOf } = require('../services/errors');
|
|
const registrationService = require('../services/registrations');
|
|
const admin = require('../services/registrationAdmin');
|
|
|
|
// @desc Create a new registration
|
|
// @route POST /api/registrations
|
|
// @access Private
|
|
const createRegistration = async (req, res) => {
|
|
try {
|
|
const actor = req.user ? { id: req.user.id, role: req.user.role, email: req.user.email } : null;
|
|
const { registration, couponError } = await registrationService.createRegistration(req.body || {}, actor);
|
|
res.status(201).json({ ...registration, ...(couponError ? { couponError } : {}) });
|
|
} catch (error) {
|
|
res.status(400).json({ message: error.message });
|
|
}
|
|
};
|
|
|
|
// @desc Cancel a registration
|
|
// @route DELETE /api/registrations/:id
|
|
// @access Private (owner, or an admin)
|
|
const cancelRegistration = async (req, res) => {
|
|
try {
|
|
const updatedRegistration = await registrationService.cancelRegistration(req.params.id, req.user, getClientIp(req));
|
|
res.json({ message: 'Registration cancelled', registration: updatedRegistration });
|
|
} catch (error) {
|
|
res.status(400).json({ message: error.message });
|
|
}
|
|
};
|
|
|
|
/** A service function as a v1 handler: its answer as JSON, its error as `{ message }`. */
|
|
const handler = (fn, status = () => 200) => async (req, res) => {
|
|
try {
|
|
const out = await fn(admin.callOf(req));
|
|
res.status(status(out)).json(out);
|
|
} catch (error) {
|
|
if (!error.statusCode) console.error(error);
|
|
res.status(v1StatusOf(error, 400)).json({ message: error.message });
|
|
}
|
|
};
|
|
|
|
module.exports = {
|
|
createRegistration,
|
|
cancelRegistration,
|
|
getRegistrations: handler(admin.getRegistrations),
|
|
getUserRegistrations: handler(admin.getUserRegistrations),
|
|
getRegistrationById: handler(admin.getRegistrationById),
|
|
updateRegistrationStatus: handler(admin.updateRegistrationStatus),
|
|
getRegistrationsByEvent: handler(admin.getRegistrationsByEvent),
|
|
createManualRegistration: handler(admin.createManualRegistration, () => 201),
|
|
updateRegistrationOptions: handler(admin.updateRegistrationOptions),
|
|
// "No form for this event" was a 200; responses saved are a 201.
|
|
submitFormResponses: handler(admin.submitFormResponses, out => (out && out.count !== undefined ? 201 : 200)),
|
|
replaceFormResponses: handler(admin.replaceFormResponses),
|
|
getFormDraft: handler(admin.getFormDraft),
|
|
saveFormDraft: handler(admin.saveFormDraft),
|
|
sendInvoice: handler(admin.sendInvoice),
|
|
applyCoupon: handler(admin.applyCoupon),
|
|
removeCoupon: handler(admin.removeCoupon),
|
|
updateAttendees: handler(admin.updateAttendees),
|
|
sendAttendeeFormLink: handler(admin.sendAttendeeFormLink),
|
|
};
|