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
+40 -22
View File
@@ -6,6 +6,8 @@ const Session = require('../components/sessions/sessionModel');
const User = require('../components/users/userModel');
const { sendClassReminderSms } = require('../utils/senders/smsMessages');
const { buildClassScheduleContext } = require('../utils/classSchedule');
const { notifyAction } = require('../utils/actionNotify');
const { resolveNotifyFlags } = require('../utils/notifyResolver');
const logger = require('../utils/logger');
const parseStartDateTime = (session) => {
@@ -37,7 +39,7 @@ const runClassReminderJob = async () => {
reminderSentAt: null,
day: { $gte: dayFrom, $lte: dayTo },
})
.populate({ path: 'class', select: 'name students startDate days startTime endTime' })
.populate({ path: 'class', select: 'name students startDate days startTime endTime uniqueCode' })
.populate({ path: 'course', select: 'title' })
.lean();
@@ -60,27 +62,43 @@ const runClassReminderJob = async () => {
: [];
const schedule = buildClassScheduleContext(classDoc, classSessions, session);
const users = await User.find({ _id: { $in: studentIds } }).select('phoneNumber').lean();
await Promise.all(
users.map(async (user) => {
if (!user.phoneNumber) return;
try {
await sendClassReminderSms(
user.phoneNumber,
classLabel,
timeLabel,
placeLabel,
user._id,
{
courseName: session.course?.title || classLabel,
...schedule
}
);
} catch (err) {
logger.error(`[ClassReminderJob] SMS failed for ${user.phoneNumber}: ${err.message}`);
}
})
);
const users = await User.find({ _id: { $in: studentIds } }).select('phoneNumber email name').lean();
const notify = await resolveNotifyFlags({}, 'classReminder');
if (notify.sms || notify.email || notify.bot) {
await Promise.all(
users.map(async (user) => {
if (!user.phoneNumber) return;
try {
await notifyAction({
actionKey: 'classReminder',
userId: user._id,
phoneNumber: user.phoneNumber,
email: user.email,
subject: 'یادآوری کلاس',
body: `یادآوری کلاس «${classLabel}» ساعت ${timeLabel} — مکان: ${placeLabel || '-'}`,
smsHandler: () => sendClassReminderSms(
user.phoneNumber,
classLabel,
timeLabel,
placeLabel,
user._id,
{
fullName: user.name,
topic: session.topic || classLabel,
sessionDate: session.day ? new Date(session.day).toLocaleDateString('fa-IR') : '',
classTime: timeLabel || session.startTime || '',
courseName: session.course?.title || classLabel,
classCode: classDoc?.uniqueCode || '',
...schedule
}
)
});
} catch (err) {
logger.error(`[ClassReminderJob] Notification failed for ${user.phoneNumber}: ${err.message}`);
}
})
);
}
await Session.updateOne({ _id: session._id }, { reminderSentAt: new Date() });
logger.info(`[ClassReminderJob] Reminders sent for session ${session._id}`);