Add sessionHolding template, unique 8-digit codes, reason slot for sessionCancelled, and disable unused notifications

This commit is contained in:
2026-08-21 10:44:51 +03:30
parent 5328f36f06
commit 091e519280
28 changed files with 2180 additions and 280 deletions
+20 -8
View File
@@ -8,7 +8,8 @@ const AppError = require('../../utils/AppError');
const { calculateMeta, escapeRegex, getSearchTerm } = require('../../utils/pagination');
const { sendClassRegisteredSms } = require('../../utils/senders/smsMessages');
const { buildClassScheduleContext, normalizeWeekdays, normalizeClockTime } = require('../../utils/classSchedule');
const { pickNotifyFlags } = require('../../utils/notifyFlags');
const { resolveNotifyFlags } = require('../../utils/notifyResolver');
const { notifyAction } = require('../../utils/actionNotify');
const logger = require('../../utils/logger');
const applyScheduleFields = (payload, body) => {
@@ -127,7 +128,7 @@ const registerUsers = async (classId, userIds, notifyInput = {}) => {
const cls = await Class.findById(classId).populate({ path: 'course', select: 'title' });
if (!cls) throw new AppError('CLASS_NOT_FOUND');
const notify = pickNotifyFlags(notifyInput);
const notify = await resolveNotifyFlags(notifyInput, 'classRegistered');
const toAdd = (userIds || []).filter(
(id) => !cls.students.map((s) => s.toString()).includes(id.toString())
);
@@ -138,24 +139,35 @@ const registerUsers = async (classId, userIds, notifyInput = {}) => {
cls.students.push(...toAdd);
await cls.save();
if (notify.sms) {
if (notify.sms || notify.email || notify.bot) {
const classLabel = cls.name || cls.course?.title || 'کلاس';
const sessions = await Session.find({ class: classId })
.select('day startTime endTime')
.sort({ day: 1 })
.lean();
const schedule = buildClassScheduleContext(cls, sessions);
const users = await User.find({ _id: { $in: toAdd } }).select('phoneNumber').lean();
const users = await User.find({ _id: { $in: toAdd } }).select('phoneNumber email name').lean();
await Promise.all(
users.map(async (user) => {
if (!user.phoneNumber) return;
try {
await sendClassRegisteredSms(user.phoneNumber, classLabel, user._id, {
courseName: cls.course?.title || classLabel,
...schedule
await notifyAction({
actionKey: 'classRegistered',
userId: user._id,
phoneNumber: user.phoneNumber,
email: user.email,
subject: 'ثبت‌نام در کلاس',
body: `ثبت‌نام شما در کلاس «${classLabel}» انجام شد. کد کلاس: ${cls.uniqueCode || ''}`,
smsHandler: () => sendClassRegisteredSms(user.phoneNumber, classLabel, user._id, {
fullName: user.name,
courseName: cls.course?.title || classLabel,
classCode: cls.uniqueCode || '',
...schedule
}),
requestSource: notifyInput
});
} catch (err) {
logger.error(`[registerUsers] SMS failed for ${user.phoneNumber}: ${err.message}`);
logger.error(`[registerUsers] Notification failed for ${user.phoneNumber}: ${err.message}`);
}
})
);