feat: add soft delete for classes with cascade to sessions and linked records
This commit is contained in:
@@ -84,6 +84,15 @@ const sessionSchema = new mongoose.Schema({
|
||||
adminNotes: {
|
||||
type: [String],
|
||||
default: []
|
||||
},
|
||||
isDeleted: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
index: true
|
||||
},
|
||||
deletedAt: {
|
||||
type: Date,
|
||||
default: null
|
||||
}
|
||||
}, {
|
||||
timestamps: true
|
||||
|
||||
@@ -124,7 +124,7 @@ const buildStudentsByClassId = async (sessions) => {
|
||||
)];
|
||||
if (!classIds.length) return new Map();
|
||||
|
||||
const classes = await Class.find({ _id: { $in: classIds } }).select('students').lean();
|
||||
const classes = await Class.find({ _id: { $in: classIds }, isDeleted: { $ne: true } }).select('students').lean();
|
||||
const allStudentIds = [...new Set(
|
||||
classes.flatMap((cls) => (cls.students || []).map(normalizeId)).filter(Boolean)
|
||||
)];
|
||||
@@ -257,6 +257,12 @@ const getAllSessions = async (queryParams) => {
|
||||
}
|
||||
if (queryParams.professorId) filter.professor = queryParams.professorId;
|
||||
|
||||
if (queryParams.trash === 'true' || queryParams.isDeleted === 'true') {
|
||||
filter.isDeleted = true;
|
||||
} else {
|
||||
filter.isDeleted = { $ne: true };
|
||||
}
|
||||
|
||||
if (filter.status) {
|
||||
filter.status = STATUS_MAP[filter.status] || filter.status;
|
||||
}
|
||||
@@ -313,7 +319,7 @@ const deleteSession = async (id) => {
|
||||
if (!session) {
|
||||
throw new AppError('SESSION_NOT_FOUND');
|
||||
}
|
||||
await Session.findByIdAndDelete(id);
|
||||
await Session.findByIdAndUpdate(id, { $set: { isDeleted: true, deletedAt: new Date() } });
|
||||
return null;
|
||||
};
|
||||
|
||||
@@ -328,8 +334,11 @@ const bulkDeleteSessions = async (ids) => {
|
||||
throw new AppError('VALIDATION_FAILED', { ids: 'Required' }, 'هیچ جلسهای انتخاب نشده است.');
|
||||
}
|
||||
|
||||
const result = await Session.deleteMany({ _id: { $in: sessionIds } });
|
||||
return { deletedCount: result.deletedCount || 0 };
|
||||
const result = await Session.updateMany(
|
||||
{ _id: { $in: sessionIds } },
|
||||
{ $set: { isDeleted: true, deletedAt: new Date() } }
|
||||
);
|
||||
return { deletedCount: result.modifiedCount || result.nModified || 0 };
|
||||
};
|
||||
|
||||
const bulkUpdateSessionStatus = async (ids, status, actorId = null) => {
|
||||
@@ -405,10 +414,10 @@ const updateSessionAttendance = async (sessionId, attendanceList, recordedBy = n
|
||||
};
|
||||
|
||||
const getMySessions = async (userId, queryParams) => {
|
||||
const userClasses = await Class.find({ students: userId }).select('_id');
|
||||
const userClasses = await Class.find({ students: userId, isDeleted: { $ne: true } }).select('_id');
|
||||
const classIds = userClasses.map((c) => c._id);
|
||||
|
||||
const filter = { class: { $in: classIds } };
|
||||
const filter = { class: { $in: classIds }, isDeleted: { $ne: true } };
|
||||
|
||||
const { page, limit, skip } = parsePaginationAndSort(queryParams, 'day', 'asc');
|
||||
const [matched, totalCount] = await Promise.all([
|
||||
|
||||
Reference in New Issue
Block a user