auth-app-api / src /controllers /course.controller.js
AndreaNotes1's picture
Upload 46 files
4c6b1e8 verified
Raw History Blame Contribute Delete
2.88 kB
const Course = require("../models/Course");
/**
* Public course catalogue listing — powers both the homepage "Our
* Academy" preview and the full Academy page. Supports the category
* filter, free-text search, and pagination the Academy page needs,
* since the number of courses is expected to keep growing.
*
* Query params (all optional):
* category - one of Course.CATEGORIES, exact match
* search - matched against title/description (case-insensitive)
* page - 1-indexed, default 1
* limit - default 12, capped at 50 to avoid huge unbounded responses
*/
async function listCourses(req, res, next) {
try {
const filter = req.user?.role === "admin" ? {} : { isPublished: true };
if (req.query.category) {
filter.category = req.query.category;
}
if (req.query.search) {
const escaped = req.query.search.trim().replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
const pattern = new RegExp(escaped, "i");
filter.$or = [{ title: pattern }, { description: pattern }];
}
const page = Math.max(1, parseInt(req.query.page, 10) || 1);
const limit = Math.min(50, Math.max(1, parseInt(req.query.limit, 10) || 12));
const [courses, total] = await Promise.all([
Course.find(filter)
.sort({ createdAt: 1 })
.skip((page - 1) * limit)
.limit(limit),
Course.countDocuments(filter),
]);
res.json({ courses, total, page, pages: Math.max(1, Math.ceil(total / limit)) });
} catch (err) {
next(err);
}
}
async function getCourse(req, res, next) {
try {
const course = await Course.findById(req.params.id);
if (!course) return res.status(404).json({ error: "Course not found." });
res.json({ course });
} catch (err) {
next(err);
}
}
async function createCourse(req, res, next) {
try {
const course = await Course.create(req.body);
res.status(201).json({ course });
} catch (err) {
if (err.code === 11000) return res.status(409).json({ error: "A course with this slug already exists." });
next(err);
}
}
async function updateCourse(req, res, next) {
try {
const course = await Course.findByIdAndUpdate(req.params.id, req.body, {
new: true,
runValidators: true,
});
if (!course) return res.status(404).json({ error: "Course not found." });
res.json({ course });
} catch (err) {
next(err);
}
}
async function deleteCourse(req, res, next) {
try {
const course = await Course.findByIdAndUpdate(req.params.id, { isPublished: false }, { new: true });
if (!course) return res.status(404).json({ error: "Course not found." });
res.json({ success: true });
} catch (err) {
next(err);
}
}
module.exports = { listCourses, getCourse, createCourse, updateCourse, deleteCourse };