Source: controllers/registrationController.js

/**
 * @file Controller for event registration operations.
 * @module controllers/registrationController
 * @requires ../models/registrationModel
 * @requires ../models/eventModel
 */

const Registration = require("../models/registrationModel");
const Event = require("../models/eventModel");

/**
 * Registers the currently authenticated user for a specific event.
 *
 * - Checks if the event exists.
 * - Prevents duplicate registrations.
 * - Creates a new registration if valid.
 *
 * @async
 * @route POST /api/registrations/events/:eventId/register
 * @access Private
 * @param {Object} req - Express request object (contains `params.eventId` and `user._id`).
 * @param {Object} res - Express response object.
 * @returns {Promise<void>}
 */
exports.registerForEvent = async (req, res) => {
  const { eventId } = req.params;
  const userId = req.user._id;

  try {
    const event = await Event.findById(eventId);
    if (!event) {
      return res.status(404).json({ message: "Event not found" });
    }

    // Prevent duplicate registrations
    const existingRegistration = await Registration.findOne({
      event: eventId,
      user: userId,
    });
    if (existingRegistration) {
      return res
        .status(400)
        .json({ message: "You are already registered for this event" });
    }

    const registration = await Registration.create({
      event: eventId,
      user: userId,
    });

    res.status(201).json(registration);
  } catch (error) {
    res
      .status(500)
      .json({ message: "Registration failed", error: error.message });
  }
};

/**
 * Retrieves all registrations for the currently authenticated user.
 *
 * Populates related event details (`title`, `date`, `location`).
 *
 * @async
 * @route GET /api/registrations/my
 * @access Private
 * @param {Object} req - Express request object (contains `user._id`).
 * @param {Object} res - Express response object.
 * @returns {Promise<void>}
 */
exports.getMyRegistrations = async (req, res) => {
  try {
    const registrations = await Registration.find({
      user: req.user._id,
    }).populate("event", "title date location");

    res.json(registrations);
  } catch (error) {
    console.error(error); // useful for debugging
    res.status(500).json({ message: "Server Error", error: error.message });
  }
};

/**
 * Cancels a specific registration by its ID.
 *
 * - Only the owner of the registration can cancel.
 * - Deletes the registration if authorized.
 *
 * @async
 * @route DELETE /api/registrations/:id
 * @access Private
 * @param {Object} req - Express request object (contains `params.id` and `user._id`).
 * @param {Object} res - Express response object.
 * @returns {Promise<void>}
 */
exports.cancelRegistration = async (req, res) => {
  try {
    const registration = await Registration.findById(req.params.id);

    if (!registration) {
      return res.status(404).json({ message: "Registration not found" });
    }

    // Ensure only the owner can cancel
    if (registration.user.toString() !== req.user._id.toString()) {
      return res
        .status(401)
        .json({ message: "Not authorized to cancel this registration" });
    }

    await registration.deleteOne();
    res.json({ message: "Registration cancelled successfully" });
  } catch (error) {
    console.error(error); // useful for debugging
    res.status(500).json({ message: "Server Error", error: error.message });
  }
};