This commit is contained in:
@@ -311,7 +311,7 @@ class CategoryController {
|
||||
}
|
||||
|
||||
// Build query conditions
|
||||
const where = { id: id };
|
||||
const where = { category_id: id };
|
||||
if (is_active !== undefined) where.is_active = is_active === 'true';
|
||||
|
||||
// Query subjects
|
||||
@@ -349,6 +349,90 @@ class CategoryController {
|
||||
next(error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add subject to category (Create subject within category context)
|
||||
*/
|
||||
async addSubjectToCategory(req, res, next) {
|
||||
try {
|
||||
const { categoryId } = req.params;
|
||||
const subjectData = req.body;
|
||||
|
||||
// Check if category exists
|
||||
const category = await Categories.findByPk(categoryId);
|
||||
if (!category) {
|
||||
return res.status(404).json({
|
||||
success: false,
|
||||
message: 'Category not found',
|
||||
});
|
||||
}
|
||||
|
||||
// Create subject with category_id
|
||||
const subject = await Subject.create({
|
||||
...subjectData,
|
||||
category_id: categoryId,
|
||||
});
|
||||
|
||||
// Clear cache
|
||||
await cacheUtils.deletePattern('subjects:list:*');
|
||||
await cacheUtils.deletePattern(`category:${categoryId}:subjects:*`);
|
||||
|
||||
res.status(201).json({
|
||||
success: true,
|
||||
message: 'Subject added to category successfully',
|
||||
data: subject,
|
||||
});
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove subject from category (Delete subject within category context)
|
||||
*/
|
||||
async removeSubjectFromCategory(req, res, next) {
|
||||
try {
|
||||
const { categoryId, subjectId } = req.params;
|
||||
|
||||
// Check if category exists
|
||||
const category = await Categories.findByPk(categoryId);
|
||||
if (!category) {
|
||||
return res.status(404).json({
|
||||
success: false,
|
||||
message: 'Category not found',
|
||||
});
|
||||
}
|
||||
|
||||
// Find subject
|
||||
const subject = await Subject.findOne({
|
||||
where: {
|
||||
id: subjectId,
|
||||
category_id: categoryId,
|
||||
},
|
||||
});
|
||||
|
||||
if (!subject) {
|
||||
return res.status(404).json({
|
||||
success: false,
|
||||
message: 'Subject not found in this category',
|
||||
});
|
||||
}
|
||||
|
||||
await subject.destroy();
|
||||
|
||||
// Clear cache
|
||||
await cacheUtils.delete(`subject:${subjectId}`);
|
||||
await cacheUtils.deletePattern('subjects:list:*');
|
||||
await cacheUtils.deletePattern(`category:${categoryId}:subjects:*`);
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
message: 'Subject removed from category successfully',
|
||||
});
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = new CategoryController();
|
||||
|
||||
@@ -330,6 +330,98 @@ class ChapterController {
|
||||
next(error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add lesson to chapter (Create lesson within chapter context)
|
||||
*/
|
||||
async addLessonToChapter(req, res, next) {
|
||||
try {
|
||||
const { chapterId } = req.params;
|
||||
const lessonData = req.body;
|
||||
|
||||
// Check if chapter exists
|
||||
const chapter = await Chapter.findByPk(chapterId);
|
||||
if (!chapter) {
|
||||
return res.status(404).json({
|
||||
success: false,
|
||||
message: 'Chapter not found',
|
||||
});
|
||||
}
|
||||
|
||||
// Validate required fields
|
||||
if (!lessonData.lesson_number || !lessonData.lesson_title) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: 'lesson_number and lesson_title are required',
|
||||
});
|
||||
}
|
||||
|
||||
// Create lesson with chapter_id
|
||||
const lesson = await Lesson.create({
|
||||
...lessonData,
|
||||
chapter_id: chapterId,
|
||||
});
|
||||
|
||||
// Clear cache
|
||||
await cacheUtils.deletePattern('lessons:*');
|
||||
await cacheUtils.deletePattern(`chapter:${chapterId}:lessons:*`);
|
||||
|
||||
res.status(201).json({
|
||||
success: true,
|
||||
message: 'Lesson added to chapter successfully',
|
||||
data: lesson,
|
||||
});
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove lesson from chapter (Delete lesson within chapter context)
|
||||
*/
|
||||
async removeLessonFromChapter(req, res, next) {
|
||||
try {
|
||||
const { chapterId, lessonId } = req.params;
|
||||
|
||||
// Check if chapter exists
|
||||
const chapter = await Chapter.findByPk(chapterId);
|
||||
if (!chapter) {
|
||||
return res.status(404).json({
|
||||
success: false,
|
||||
message: 'Chapter not found',
|
||||
});
|
||||
}
|
||||
|
||||
// Find lesson
|
||||
const lesson = await Lesson.findOne({
|
||||
where: {
|
||||
id: lessonId,
|
||||
chapter_id: chapterId,
|
||||
},
|
||||
});
|
||||
|
||||
if (!lesson) {
|
||||
return res.status(404).json({
|
||||
success: false,
|
||||
message: 'Lesson not found in this chapter',
|
||||
});
|
||||
}
|
||||
|
||||
await lesson.destroy();
|
||||
|
||||
// Clear cache
|
||||
await cacheUtils.deletePattern('lessons:*');
|
||||
await cacheUtils.deletePattern(`lesson:${lessonId}*`);
|
||||
await cacheUtils.deletePattern(`chapter:${chapterId}:lessons:*`);
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
message: 'Lesson removed from chapter successfully',
|
||||
});
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = new ChapterController();
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
const { Lesson, Chapter, Subject, Game } = require('../models');
|
||||
const { Op } = require('sequelize');
|
||||
const { Story, LessonStory } = require('../models');
|
||||
const { cacheUtils } = require('../config/redis');
|
||||
|
||||
/**
|
||||
* Lesson Controller
|
||||
@@ -384,6 +386,243 @@ class LessonController {
|
||||
next(error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Lấy danh sách stories trong một lesson
|
||||
*/
|
||||
async getStoriesByLesson(req, res, next) {
|
||||
try {
|
||||
const { lessonId } = req.params;
|
||||
const { page = 1, limit = 20 } = req.query;
|
||||
const offset = (page - 1) * limit;
|
||||
|
||||
const cacheKey = `lesson:${lessonId}:stories:${page}:${limit}`;
|
||||
|
||||
const cached = await cacheUtils.get(cacheKey);
|
||||
if (cached) {
|
||||
return res.json({
|
||||
success: true,
|
||||
data: cached,
|
||||
cached: true,
|
||||
});
|
||||
}
|
||||
|
||||
// Check if lesson exists
|
||||
const lesson = await Lesson.findByPk(lessonId);
|
||||
if (!lesson) {
|
||||
return res.status(404).json({
|
||||
success: false,
|
||||
message: 'Không tìm thấy bài học',
|
||||
});
|
||||
}
|
||||
|
||||
// Get stories with pivot data
|
||||
const { count, rows } = await Story.findAndCountAll({
|
||||
include: [
|
||||
{
|
||||
model: Lesson,
|
||||
as: 'lessons',
|
||||
where: { id: lessonId },
|
||||
through: {
|
||||
attributes: ['display_order', 'is_required'],
|
||||
},
|
||||
attributes: [],
|
||||
},
|
||||
],
|
||||
limit: parseInt(limit),
|
||||
offset: parseInt(offset),
|
||||
order: [[{ model: Lesson, as: 'lessons' }, LessonStory, 'display_order', 'ASC']],
|
||||
});
|
||||
|
||||
const result = {
|
||||
lesson: {
|
||||
id: lesson.id,
|
||||
lesson_title: lesson.lesson_title,
|
||||
lesson_number: lesson.lesson_number,
|
||||
},
|
||||
stories: rows.map(story => ({
|
||||
...story.toJSON(),
|
||||
display_order: story.lessons[0]?.LessonStory?.display_order,
|
||||
is_required: story.lessons[0]?.LessonStory?.is_required,
|
||||
})),
|
||||
pagination: {
|
||||
total: count,
|
||||
page: parseInt(page),
|
||||
limit: parseInt(limit),
|
||||
totalPages: Math.ceil(count / limit),
|
||||
},
|
||||
};
|
||||
|
||||
await cacheUtils.set(cacheKey, result, 1800);
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
data: result,
|
||||
cached: false,
|
||||
});
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Thêm story vào lesson
|
||||
*/
|
||||
async addStoryToLesson(req, res, next) {
|
||||
try {
|
||||
const { lessonId } = req.params;
|
||||
const { story_id, display_order = 0, is_required = true } = req.body;
|
||||
|
||||
// Validate required fields
|
||||
if (!story_id) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: 'story_id is required',
|
||||
});
|
||||
}
|
||||
|
||||
// Check if lesson exists
|
||||
const lesson = await Lesson.findByPk(lessonId);
|
||||
if (!lesson) {
|
||||
return res.status(404).json({
|
||||
success: false,
|
||||
message: 'Không tìm thấy bài học',
|
||||
});
|
||||
}
|
||||
|
||||
// Check if story exists
|
||||
const story = await Story.findByPk(story_id);
|
||||
if (!story) {
|
||||
return res.status(404).json({
|
||||
success: false,
|
||||
message: 'Không tìm thấy story',
|
||||
});
|
||||
}
|
||||
|
||||
// Check if relationship already exists
|
||||
const existing = await LessonStory.findOne({
|
||||
where: {
|
||||
lesson_id: lessonId,
|
||||
story_id: story_id,
|
||||
},
|
||||
});
|
||||
|
||||
if (existing) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: 'Story đã tồn tại trong bài học này',
|
||||
});
|
||||
}
|
||||
|
||||
// Create relationship
|
||||
const lessonStory = await LessonStory.create({
|
||||
lesson_id: lessonId,
|
||||
story_id: story_id,
|
||||
display_order,
|
||||
is_required,
|
||||
});
|
||||
|
||||
// Clear cache
|
||||
await cacheUtils.deletePattern(`lesson:${lessonId}:stories:*`);
|
||||
await cacheUtils.deletePattern(`story:${story_id}:lessons:*`);
|
||||
|
||||
res.status(201).json({
|
||||
success: true,
|
||||
message: 'Story đã được thêm vào bài học',
|
||||
data: lessonStory,
|
||||
});
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Xóa story khỏi lesson
|
||||
*/
|
||||
async removeStoryFromLesson(req, res, next) {
|
||||
try {
|
||||
const { lessonId, storyId } = req.params;
|
||||
|
||||
// Check if lesson exists
|
||||
const lesson = await Lesson.findByPk(lessonId);
|
||||
if (!lesson) {
|
||||
return res.status(404).json({
|
||||
success: false,
|
||||
message: 'Không tìm thấy bài học',
|
||||
});
|
||||
}
|
||||
|
||||
// Find relationship
|
||||
const lessonStory = await LessonStory.findOne({
|
||||
where: {
|
||||
lesson_id: lessonId,
|
||||
story_id: storyId,
|
||||
},
|
||||
});
|
||||
|
||||
if (!lessonStory) {
|
||||
return res.status(404).json({
|
||||
success: false,
|
||||
message: 'Story không tồn tại trong bài học này',
|
||||
});
|
||||
}
|
||||
|
||||
await lessonStory.destroy();
|
||||
|
||||
// Clear cache
|
||||
await cacheUtils.deletePattern(`lesson:${lessonId}:stories:*`);
|
||||
await cacheUtils.deletePattern(`story:${storyId}:lessons:*`);
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
message: 'Story đã được xóa khỏi bài học',
|
||||
});
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Cập nhật thông tin story trong lesson (display_order, is_required)
|
||||
*/
|
||||
async updateStoryInLesson(req, res, next) {
|
||||
try {
|
||||
const { lessonId, storyId } = req.params;
|
||||
const { display_order, is_required } = req.body;
|
||||
|
||||
// Find relationship
|
||||
const lessonStory = await LessonStory.findOne({
|
||||
where: {
|
||||
lesson_id: lessonId,
|
||||
story_id: storyId,
|
||||
},
|
||||
});
|
||||
|
||||
if (!lessonStory) {
|
||||
return res.status(404).json({
|
||||
success: false,
|
||||
message: 'Story không tồn tại trong bài học này',
|
||||
});
|
||||
}
|
||||
|
||||
// Update
|
||||
await lessonStory.update({
|
||||
...(display_order !== undefined && { display_order }),
|
||||
...(is_required !== undefined && { is_required }),
|
||||
});
|
||||
|
||||
// Clear cache
|
||||
await cacheUtils.deletePattern(`lesson:${lessonId}:stories:*`);
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
message: 'Cập nhật thành công',
|
||||
data: lessonStory,
|
||||
});
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = new LessonController();
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
const { Story, sequelize } = require('../models');
|
||||
const { Op } = require('sequelize');
|
||||
const { Lesson, LessonStory } = require('../models');
|
||||
const { cacheUtils } = require('../config/redis');
|
||||
|
||||
/**
|
||||
* CREATE: Add new story
|
||||
@@ -733,3 +735,213 @@ exports.getStoryGuide = async (req, res) => {
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Lấy danh sách lessons sử dụng story này
|
||||
*/
|
||||
exports.getLessonsByStory = async (req, res) => {
|
||||
try {
|
||||
const { storyId } = req.params;
|
||||
const { page = 1, limit = 20 } = req.query;
|
||||
const offset = (parseInt(page) - 1) * parseInt(limit);
|
||||
|
||||
const cacheKey = `story:${storyId}:lessons:${page}:${limit}`;
|
||||
|
||||
const cached = await cacheUtils.get(cacheKey);
|
||||
if (cached) {
|
||||
return res.json({
|
||||
success: true,
|
||||
data: cached,
|
||||
cached: true,
|
||||
});
|
||||
}
|
||||
|
||||
// Check if story exists
|
||||
const story = await Story.findByPk(storyId);
|
||||
if (!story) {
|
||||
return res.status(404).json({
|
||||
success: false,
|
||||
message: 'Story not found',
|
||||
});
|
||||
}
|
||||
|
||||
// Get lessons with pivot data
|
||||
const { count, rows } = await Lesson.findAndCountAll({
|
||||
include: [
|
||||
{
|
||||
model: Story,
|
||||
as: 'stories',
|
||||
where: { id: storyId },
|
||||
through: {
|
||||
attributes: ['display_order', 'is_required'],
|
||||
},
|
||||
attributes: [],
|
||||
},
|
||||
],
|
||||
limit: parseInt(limit),
|
||||
offset: parseInt(offset),
|
||||
order: [[{ model: Story, as: 'stories' }, LessonStory, 'display_order', 'ASC']],
|
||||
});
|
||||
|
||||
const result = {
|
||||
story: {
|
||||
id: story.id,
|
||||
name: story.name,
|
||||
type: story.type,
|
||||
},
|
||||
lessons: rows.map(lesson => ({
|
||||
...lesson.toJSON(),
|
||||
display_order: lesson.stories[0]?.LessonStory?.display_order,
|
||||
is_required: lesson.stories[0]?.LessonStory?.is_required,
|
||||
})),
|
||||
pagination: {
|
||||
total: count,
|
||||
page: parseInt(page),
|
||||
limit: parseInt(limit),
|
||||
totalPages: Math.ceil(count / parseInt(limit)),
|
||||
},
|
||||
};
|
||||
|
||||
await cacheUtils.set(cacheKey, result, 1800);
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
data: result,
|
||||
cached: false,
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Error fetching lessons by story:', error);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
message: 'Failed to fetch lessons',
|
||||
error: error.message,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Thêm lesson vào story (alternative way)
|
||||
*/
|
||||
exports.addLessonToStory = async (req, res) => {
|
||||
try {
|
||||
const { storyId } = req.params;
|
||||
const { lesson_id, display_order = 0, is_required = true } = req.body;
|
||||
|
||||
// Validate required fields
|
||||
if (!lesson_id) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: 'lesson_id is required',
|
||||
});
|
||||
}
|
||||
|
||||
// Check if story exists
|
||||
const story = await Story.findByPk(storyId);
|
||||
if (!story) {
|
||||
return res.status(404).json({
|
||||
success: false,
|
||||
message: 'Story not found',
|
||||
});
|
||||
}
|
||||
|
||||
// Check if lesson exists
|
||||
const lesson = await Lesson.findByPk(lesson_id);
|
||||
if (!lesson) {
|
||||
return res.status(404).json({
|
||||
success: false,
|
||||
message: 'Lesson not found',
|
||||
});
|
||||
}
|
||||
|
||||
// Check if relationship already exists
|
||||
const existing = await LessonStory.findOne({
|
||||
where: {
|
||||
lesson_id: lesson_id,
|
||||
story_id: storyId,
|
||||
},
|
||||
});
|
||||
|
||||
if (existing) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: 'Lesson đã sử dụng story này',
|
||||
});
|
||||
}
|
||||
|
||||
// Create relationship
|
||||
const lessonStory = await LessonStory.create({
|
||||
lesson_id: lesson_id,
|
||||
story_id: storyId,
|
||||
display_order,
|
||||
is_required,
|
||||
});
|
||||
|
||||
// Clear cache
|
||||
await cacheUtils.deletePattern(`story:${storyId}:lessons:*`);
|
||||
await cacheUtils.deletePattern(`lesson:${lesson_id}:stories:*`);
|
||||
|
||||
res.status(201).json({
|
||||
success: true,
|
||||
message: 'Lesson đã được thêm vào story',
|
||||
data: lessonStory,
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Error adding lesson to story:', error);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
message: 'Failed to add lesson to story',
|
||||
error: error.message,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Xóa lesson khỏi story
|
||||
*/
|
||||
exports.removeLessonFromStory = async (req, res) => {
|
||||
try {
|
||||
const { storyId, lessonId } = req.params;
|
||||
|
||||
// Check if story exists
|
||||
const story = await Story.findByPk(storyId);
|
||||
if (!story) {
|
||||
return res.status(404).json({
|
||||
success: false,
|
||||
message: 'Story not found',
|
||||
});
|
||||
}
|
||||
|
||||
// Find relationship
|
||||
const lessonStory = await LessonStory.findOne({
|
||||
where: {
|
||||
lesson_id: lessonId,
|
||||
story_id: storyId,
|
||||
},
|
||||
});
|
||||
|
||||
if (!lessonStory) {
|
||||
return res.status(404).json({
|
||||
success: false,
|
||||
message: 'Lesson không sử dụng story này',
|
||||
});
|
||||
}
|
||||
|
||||
await lessonStory.destroy();
|
||||
|
||||
// Clear cache
|
||||
await cacheUtils.deletePattern(`story:${storyId}:lessons:*`);
|
||||
await cacheUtils.deletePattern(`lesson:${lessonId}:stories:*`);
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
message: 'Lesson đã được xóa khỏi story',
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Error removing lesson from story:', error);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
message: 'Failed to remove lesson from story',
|
||||
error: error.message,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@@ -349,6 +349,108 @@ class SubjectController {
|
||||
next(error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add chapter to subject (Create chapter within subject context)
|
||||
*/
|
||||
async addChapterToSubject(req, res, next) {
|
||||
try {
|
||||
const { subjectId } = req.params;
|
||||
const chapterData = req.body;
|
||||
|
||||
// Check if subject exists
|
||||
const subject = await Subject.findByPk(subjectId);
|
||||
if (!subject) {
|
||||
return res.status(404).json({
|
||||
success: false,
|
||||
message: 'Subject not found',
|
||||
});
|
||||
}
|
||||
|
||||
// Validate required fields
|
||||
if (!chapterData.chapter_number || !chapterData.chapter_title) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: 'chapter_number and chapter_title are required',
|
||||
});
|
||||
}
|
||||
|
||||
// Create chapter with subject_id
|
||||
const chapter = await Chapter.create({
|
||||
...chapterData,
|
||||
subject_id: subjectId,
|
||||
});
|
||||
|
||||
// Clear cache
|
||||
await cacheUtils.deletePattern('chapters:*');
|
||||
await cacheUtils.deletePattern(`subject:${subjectId}:chapters:*`);
|
||||
|
||||
res.status(201).json({
|
||||
success: true,
|
||||
message: 'Chapter added to subject successfully',
|
||||
data: chapter,
|
||||
});
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove chapter from subject (Delete chapter within subject context)
|
||||
*/
|
||||
async removeChapterFromSubject(req, res, next) {
|
||||
try {
|
||||
const { subjectId, chapterId } = req.params;
|
||||
|
||||
// Check if subject exists
|
||||
const subject = await Subject.findByPk(subjectId);
|
||||
if (!subject) {
|
||||
return res.status(404).json({
|
||||
success: false,
|
||||
message: 'Subject not found',
|
||||
});
|
||||
}
|
||||
|
||||
// Find chapter
|
||||
const chapter = await Chapter.findOne({
|
||||
where: {
|
||||
id: chapterId,
|
||||
subject_id: subjectId,
|
||||
},
|
||||
});
|
||||
|
||||
if (!chapter) {
|
||||
return res.status(404).json({
|
||||
success: false,
|
||||
message: 'Chapter not found in this subject',
|
||||
});
|
||||
}
|
||||
|
||||
// Check if chapter has lessons
|
||||
const Lesson = require('../models').Lesson;
|
||||
const lessonsCount = await Lesson.count({ where: { chapter_id: chapterId } });
|
||||
if (lessonsCount > 0) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: `Cannot delete chapter. It has ${lessonsCount} lesson(s). Delete lessons first.`,
|
||||
});
|
||||
}
|
||||
|
||||
await chapter.destroy();
|
||||
|
||||
// Clear cache
|
||||
await cacheUtils.deletePattern('chapters:*');
|
||||
await cacheUtils.deletePattern(`chapter:${chapterId}*`);
|
||||
await cacheUtils.deletePattern(`subject:${subjectId}:chapters:*`);
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
message: 'Chapter removed from subject successfully',
|
||||
});
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = new SubjectController();
|
||||
|
||||
Reference in New Issue
Block a user