Spaces:
Running
Running
Download src/controllers/course.controller.js from AndreaNotes1/auth-app-api: direct link, hf CLI and curl.
- Browser
- Download file 2.88 kB
-
https://huggingface.co/spaces/AndreaNotes1/auth-app-api/resolve/main/src/controllers/course.controller.js
- Command line
-
hf download hf://spaces/AndreaNotes1/auth-app-api/src/controllers/course.controller.js
-
curl -L -o course.controller.js https://huggingface.co/spaces/AndreaNotes1/auth-app-api/resolve/main/src/controllers/course.controller.js
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 }; | |